The short version
A provider key you add is encrypted before it is written to our database. The dashboard and the API show only a masked preview, never the key. The key is decrypted in memory when a request has to be sent to the provider you added it for, and it goes to that provider's address and nowhere else.
AnyRouter has to use your key to send requests for you, so our servers can decrypt it at that moment. This post says what limits that, and what we do not claim.
How a key is stored
- Each key is encrypted with AES-256-GCM. Every key gets its own random salt and its own random nonce.
- The encryption key is derived from a master secret with HKDF-SHA-256 and that salt. The master secret is not in the database. It lives in Cloudflare Secrets Store and is read by the backend services that need it.
- Keys written in the current format are bound to your workspace. A ciphertext copied from one workspace's row does not decrypt as another workspace's key.
- Rows written before we added the stronger key derivation still decrypt, but they are not bound to a workspace until they are re-encrypted. A maintenance script can re-encrypt every stored key under the current format or under a new master secret.
Because the master secret is separate from the database, a copy of the database alone is ciphertext.
Who and what can read it
- You see a masked preview: the first four and last three characters. After you save a key, there is no screen or API call that returns the full value.
- Admin tools show the same preview. They do not return the stored ciphertext or the key.
- Other members never receive a key. A request that uses a donated key is made by our gateway, and the caller only gets the model's answer.
Where a key can be sent
A key is only sent to the provider it belongs to. Most providers are reached at a fixed address that we register, and for those a custom base URL is rejected when you add the key.
For providers where you supply an endpoint, such as a self-hosted server, the URL must use HTTPS, must not be an IP address or a local address, and must be on the provider's registered host when one exists. Azure AI Foundry endpoints must be on an Azure host, and Claude keys for Bedrock and Vertex are checked for their expected host and region. These checks run again on every request, not only when you save the key.
Pool requests ignore any custom base URL on a donor's key. A donated key is sent only to the registered address for its provider.
What stays out of logs
We do not write keys to our logs. The one place a key can come back to us is a provider's own error message, because some providers repeat the key you sent when they reject a request. Before an upstream error body is stored, logged or passed on, we remove the exact key that request used, in its plain, URL-encoded and JSON-escaped forms. This works for any key format, not only the ones we recognise by prefix.
Revoking a key
- Delete the key in the dashboard or the API. The encrypted row is removed, and any Pool donation backed by that key ends with it.
- If the key was donated, the Pool's selection cache is refreshed in the same request, so a deleted key stops serving other members right away.
- Replace the key in place instead of deleting it. The new key is checked with the provider first, and the old one is dropped from the Pool cache as soon as it is replaced.
Deleting a key here does not cancel it at the provider. If you think a key was exposed, also revoke it in your provider's console.
If you donate a key to the Pool
A donated key is the same encrypted row you added under BYOK. We do not make a second copy. You stay in control of it:
- Pause and resume it, or withdraw it, at any time.
- Cap its requests per minute.
- Choose free-only coverage, or paid coverage with your own price per model.
- Keys that keep failing or hit a provider limit are paused automatically.
Usage from the Pool appears on your provider account, and you agree to your provider's terms. Keys that open a whole cloud account, such as Claude on Bedrock, Vertex or Foundry, cannot be donated.
What we do not claim
We hold the master secret, so a compromise of our backend while it runs could expose keys that are in use. That is why we keep the number of services that hold it small and keep the re-encryption tooling ready for a rotation.
Use a key with a spend limit where your provider offers one, give it only the access you need, and revoke it at the provider if you stop using it.
Route your first request in 2 minutes
Start free with your own keys, or top up and pay per token. Get $4/mo in credits and free models on Go — $2/mo, or free when you donate a provider key.
Start free