Why your AI agent should never see your database password
The model names a tool. The platform makes the call. Credentials are decrypted inside the connector — never in a prompt, a log or a trace.
The simplest way to let a language model query a database is to give it the connection string. It is also the worst. Everything a model is shown can end up in a provider's logs, in your own logs, in a debugging transcript, or — with the right hostile text in a customer note — repeated straight back in an answer.
So in Caterfli the model is never shown it. Not because one provider is more trustworthy than another, but because there is no version of "your database password went to a third party" that we are comfortable with.
What the model actually sees
For each tool, three things: a name, a description, and a schema for its arguments.
{
"name": "list_orders",
"description": "Find orders by status",
"input_schema": { "status": "string", "since": "date" }
}
That is enough to plan with. It is not enough to reach anything. The model's context has no hostname, no password, no connection id, no organisation id and no endpoint path. Descriptions do say whether a call will need approval, because a model that knows it will pause explains itself better.
The model names a tool; the platform makes the call
When the model wants data it proposes a tool and some arguments. That proposal goes through the platform's checks — the tool exists, the agent has it, the workspace owns the connection, the arguments validate, the person asking has permission, policy allows it. Only then does the connector run the call, and only the connector holds the means to.
This split is what makes the rest possible. A model that never had the password cannot leak it, cannot be talked into using it some other way, and cannot pass it to a tool that was never meant to receive it.
Encrypted, with a key of its own
Credentials are stored with envelope encryption, using a key entirely separate from the application's own:
- Each secret is sealed with a fresh, random 32-byte key using AES-256-GCM.
- That key is itself sealed by a versioned master key.
- The key version is bound into the encryption, so a secret sealed under one version cannot be presented as another.
- Tampering with a stored secret fails authentication rather than decrypting to something wrong.
Rotation re-wraps the small per-secret keys rather than re-encrypting every payload, which makes it cheap enough to actually do.
Decrypted at call time, inside the connector
The secret is decrypted at the moment a call is made, inside the connector, and held only for the duration of that call. It is never rendered back into a form, so editing a connection means entering a new secret rather than revealing the old one. Nobody at Caterfli can read it back, including through the admin panel; support can see that a connection exists and whether it is healthy, not what is in it.
Scrubbed from everything else
Defence in depth means assuming something, somewhere, will try to log a secret anyway. A redactor sits in front of logs, audit records and prompts, and strips values that look like credentials — by key name (password, token, api_key, authorization and others) and by shape, such as provider API keys, Slack tokens, JWTs and credentials embedded in URLs.
It is a safety net, not a licence. Nothing should be putting a credential there in the first place.
One request in return
Do not paste credentials into an agent's instructions, a chat message or a support ticket. Those places are not built to hold one, and we never need it. If one has already gone somewhere it should not have, rotate it rather than deleting the message.
The security page covers the rest of the boundary. This part is short: the model plans, and it plans without the keys.
0 comments
Sign in to join the discussion.