Every request payload we write for your account is encrypted, the moment it is written, to a public key that belongs to you. The private half exists only wrapped under codes we hand you once and never keep. When you want help, you mint a grant key with a deadline on it. Until you do, there is no operator, no engineer and no database backup that can turn your traffic back into text.
Five stages, in order. Notice where the secrets are at each one, and notice that writing a log never needs one.
We generate an X25519 keypair for your account. The public key is stored as it is. The private key is encrypted under a master code, shown to you once, and we keep only a SHA-256 hash of that code so we can tell a right one from a wrong one. Nothing else about it is written down.
Each request body, each response body and each model step is encrypted to your public key with a fresh ephemeral keypair, then AES-256-GCM. Sealing needs no secret at all, so logging never stalls, never asks anyone for anything, and never has a moment where the plaintext is at rest.
You type your master code, choose how long the grant lasts and what it covers, and we rewrap your private key under a fresh grant key. You see that key once. We hold its hash and the wrapped blob, and nothing else.
Our support desk redeems the key you gave them. The scope you set is enforced when a payload is opened, refusals included, and the grant stops working the second it expires or you revoke it. Expiry does not lock the wrapped key away, it deletes it.
Redemptions, decryptions and refusals are written by the same code path that performs them, into a record in your dashboard. There is no way for us to read a payload without a line appearing next to your name for it.
We are not going to tell you the metadata is encrypted, because it is not. Timestamps, tool names, key kinds, costs, status and reference codes are stored in the clear on purpose: billing, metering and rate limiting have to work without anyone ever holding your codes, and a system that needed your master code to send an invoice would simply be a system that asked you for your master code every month. What is sealed is the content. Traffic analysis of your account is possible for us. Reading your traffic is not.
Encrypted to your key. Unreadable to us without a grant key you mint.
The same treatment, step by step, inside the same run.
It is squeezed out of the request body, so on a sealed account it is content wearing a metadata coat. We drop it rather than store it, and your log lists the tool name instead.
Readable. This is how your bill is calculated and your usage metered.
Readable. This is how quotas, rate limits and incident dashboards work.
Readable. They are how a row is attached to you in the first place.
Readable, and meant to be. It names a request so a support thread can start at the right one. It does not open it.
Readable, because a failure has to be diagnosable from the outside. Our messages describe conditions rather than quoting bodies, but treat this field as the one place a fragment of your input could surface, and tell us if you ever see one.
If you lose every code, the payloads sealed under them are gone. We cannot recover them and neither can you. Switching the feature on again generates a fresh keypair for future logs and leaves the old ones unreadable forever. This is not a gap in the design, it is the design working.
One distinction worth being precise about, because we would rather you heard it from us. The cryptographic boundary is your account: a grant key unwraps your account private key, so a scope of one tool or one date range is enforced by our software and recorded in your access record, not by the mathematics. The hard limits are the ones the mathematics does enforce: no grant at all without your master code, no reading after expiry, and no reading after revocation. Treat a scope as a promise we keep and log. Treat a duration as a fact.
Every check below can be run against a live account today, by your team, without asking us for anything except a support session where one is named.
Do thisCall GET /api/v1/logs/export with any of your API keys. It returns your own runs with the payload columns exactly as they sit on disk, in the fields named stored_request, stored_response, stored_input and stored_output. Nothing in that endpoint decrypts anything.
ExpectOn a sealed account every one of those fields begins pcifseal1. and carries an ephemeral public key, a nonce, a GCM tag and a body. No JSON structure, no field names, no lengths beyond the ciphertext length. The metadata beside it is readable, which is the claim on this page rendered as a response body.
Do thisOpen a sealed request in your dashboard log and type a code that is nearly right into the unlock field. Then try to mint a grant key with the same near miss.
ExpectBoth refuse. The unwrap fails the AES-GCM tag, so there is no partial answer and no error that tells you how close you were. The only thing stored is a hash, so there is nothing to compare against but the answer.
Do thisSwitch the feature on, copy the master code, then reload the settings page and go looking for it in the dashboard, in the API and in any support conversation with us.
ExpectIt is not there. It was generated in memory, shown to you, hashed, and dropped. Ask us for it and the honest answer is that we cannot produce it.
Do thisMint a grant with the shortest duration on offer, note the expiry shown on the row, and after it passes ask us to redeem the same key.
ExpectRedemption is refused, and the wrapped key stored behind that grant has been deleted rather than merely ignored. A row remains as a record of the grant having existed.
Do thisMint a grant, hand it to us, then press revoke while it is still well inside its window and ask us to open something else with it.
ExpectIt stops working immediately, on the next use, with no cache to wait out. The wrapped key behind it is blanked at the moment you press the button.
Do thisGive us a grant during an actual support conversation, let us open the request you are asking about, then open the access record in your settings.
ExpectA line for the session, a line for each payload opened, with who at PCIFIC, which grant, which reference code and when. Anything we were refused for being outside your scope is listed too. The rows are written by the same function that performs the decryption, so a decryption without a row would need a different build of the software.
Do thisHand this page to whoever reviews cryptography for you. The scheme is X25519 for key agreement, HKDF-SHA256 to derive a content key bound to both public keys, AES-256-GCM for the payload, scrypt to turn a typed code into the key that wraps the private key, and SHA-256 for the code hashes. All of it is Node's standard crypto module, no bespoke primitives.
ExpectA construction your team can reason about in an afternoon, and a set of properties that either hold or do not: sealing requires no secret, opening requires a code we never stored, and holding the whole database gets you ciphertext.