No prompt, response, or RAG content ever leaves your VPC. The collector emits priced metadata only. Message content and retrieved chunks are written to a Postgres database inside your network and are read back — for a dashboard drill-down — only from within that network.
The data-residency model
Firedog is split-plane. The two planes hold different data and sit in different trust boundaries.- Data plane — the collector, inside your VPC. It exposes an OpenAI-compatible endpoint (
POST /v1/chat/completions). Your applications route their LLM calls through it, it forwards to the upstream provider, prices the call from a shared pricing table, and writes the full record to a local Postgres in your VPC. This full record — theCallRecord— never leaves your network. - Control plane — Firedog cloud, the dashboard. It receives only metadata (
CallMetadata) through an ingest API: priced, attributed, and identity-protected numbers with no message content. This is what powers Home, Cost allocation, Workflow detail, Answer quality, and the Audit trail.
callId (a client-side ULID) links the two. It lets a dashboard drill-down fetch the full record from the collector, within your VPC — never from the cloud, which does not hold it.
See How it works for the end-to-end flow.
What stays vs. what leaves
TheCallRecord holds the content and stays in your Postgres. The CallMetadata holds priced, attributed numbers and is the only thing sent to Firedog cloud. Content fields have no counterpart on the cloud side.
| Field | CallRecord — stays in your VPC | CallMetadata — emitted to Firedog cloud |
|---|---|---|
| Prompt messages | Stored | — never leaves |
| Retrieved RAG chunks | Stored | — never leaves |
| Model response / completion text | Stored | — never leaves |
callId (ULID) | Stored | Emitted |
tenantId | Stored | Emitted |
collectorId | Stored | Emitted |
timestamp | Stored | Emitted |
model | Stored | Emitted |
promptTokens / completionTokens | Stored | Emitted (counts only) |
cost | Stored | Emitted |
latencyMs | Stored | Emitted |
team | Stored | Emitted (subject to profile) |
workflow | Stored | Emitted (subject to profile) |
userHash (salted hash) | Stored | Emitted (never the raw identity) |
category | Stored | Emitted (subject to profile) |
qaOverall (quality score) | Stored | Emitted |
shadowSaving | Stored | Emitted |
Identity and tag protection
Even though only metadata leaves your VPC, that metadata can still carry labels. Firedog is designed to protect them before they are emitted.- User identity is never sent raw. The
userIdyou attach for attribution is emitted as a salted hash (userHash), so per-user cost views work without the control plane holding an identity you can reverse. - Team and workflow tags can be hashed. Labels like
Project-Titancan be emitted as opaque tokens (for examplewf_7c2a) rather than the human-readable name, so a project’s existence isn’t exposed by its cost line. - Category can be dropped where it could itself identify a desk or initiative.
strict, standard, or open:
strict
Maximal redaction: tags hashed, user always hashed, identifying category dropped.
standard
Balanced: raw workflow and team labels, salted user hash, quality signal retained.
open
Richest tags, for teams whose labels are not sensitive.
Sensitivity profiles are configurable defaults for what the collector is allowed to emit, not hard guarantees for every possible label. Choose the profile per collector to match the desk’s data-classification policy.
Self-hosted collector, metadata-only egress
The collector is the data plane and it runs where your data already lives — inside your VPC, alongside a Postgres you own. Two properties follow from that placement:Content is written locally
Full
CallRecord rows — prompt, RAG chunks, response — are written to your in-VPC Postgres. They are queried in place for dashboard drill-downs, keyed by callId.Your data, our role
Under GDPR, the client is the controller and holds the content; Firedog is a processor on usage metadata only; the LLM providers are the client’s own processors — content reaches them from the client, never via Firedog. The only personal data that leaves the client is a collaborator identifier, emitted as a salted hash. See Data processing & residency for the full treatment.Access and retention
Retention of the fullCallRecord is governed by your own Postgres, which you operate and can age out or purge on your own schedule. On the control plane, Firedog keeps raw metadata for 30–90 days and aggregates in longer retention; content is never retained by Firedog.
Exact windows and control-plane access controls (authentication, roles, per-client isolation, access logging) are being formalised — see the [Placeholders] on Data processing & residency.
Data residency and subprocessors
The Firedog control plane — the metadata store and web app — is hosted in the EU only: Railway, region EU West (Amsterdam), on GCPeurope-west4. Client content stays in your VPC and is never hosted by Firedog or its subprocessors.
The processing chain is Firedog → Railway → Google Cloud. Railway is SOC 2 Type II + SOC 3; Google Cloud is SOC 2 / ISO 27001 and DPF-certified. The full subprocessor table, transfer basis, retention and deletion model live on Data processing & residency.
[Placeholder — confirm with the Firedog team: any attestations held by Firedog itself, and the client DPA.]
Related
Data processing & residency
GDPR roles, subprocessors, retention, deletion, and EU hosting.
How it works
The split-plane architecture end to end.
Sensitivity profiles
What each profile emits, and how to choose one.
Attribution
How tags reach the metadata, and how they’re hashed.
Quickstart
Route your first call through the collector with the SDK or a base-URL swap.
