# Our agent already has a database user with the right grants. Why isn't that enough?

*Published on 2026-10-13T00:00:00.000Z*

*By CipherStash Team*

Because the database user identifies the agent's workload, not the person it is acting for. If every request from the agent arrives under the same credential, the database cannot tell a request made for one user from a request made for another, and neither can decryption bound to that credential. Make key requests as the signed-in user and lock values to that user, and the agent can decrypt those values only when it acts for them.

## Content

Trace the identities on one read. There is the database connection, which authenticates as a role. There is the application or workload, which holds that role's credential. There is the person the agent is working for. And there is the agent itself, running a plan the person did not write line by line.

A service credential collapses all of that to one identity. Every request from the agent looks like the application, no matter who asked. Two users with very different levels of access in your product, and one credential that can read both of their records. The database cannot tell the difference, because the difference was never in the request.

## Putting the person back in the request

CipherStash authenticates two ways. A workload uses a client key and an access key, which authenticates it as an application. A signed-in user's OIDC token can instead be federated into a short-lived token for ZeroKMS, so the request is made as that user.

Those are two separate steps, and they do different things. Federation on its own attributes every key request to the user, which gives you an audit trail. A lock context is what restricts decryption: it binds a value to a claim from the user's token, usually `sub`, and that value then decrypts only for that user. An agent acting for the user can decrypt the values locked to them. An agent holding only the service credential cannot decrypt values locked to a user, whatever its connection string lets it query.

A lock context binds a value to one user. It does not express shared access, such as a clinician reading a patient's record. For data several people need, keep your application's authorization in front of decryption, or separate the data by keyset.

## Technical evidence

- [Provable access: making requests as the end user](/docs/solutions/provable-access)
- [CipherStash Token Service](/docs/concepts/auth)
- [AI and RAG: authorization before decryption](/docs/solutions/ai-and-rag)

## Related notes

- [We already have Auth0 and row-level security. What does this add?](https://cipherstash.com/notes/we-already-have-auth0-and-row-level-security.md) — A layer below them. Once a query is allowed, the database returns plaintext. CipherStash decides whether a value can become plaintext, and for whom, inside the key derivation.
- [We don't need to search encrypted data. Why would we need you?](https://cipherstash.com/notes/we-dont-need-to-search-encrypted-data.md) — Most teams don't, and search is optional per column. CipherStash is for data-level access control, and that works with search switched off everywhere.

