Where credentials live
ExecBound's central promise is that an agent can ask for an action but never hold the credential that performs it. This page lists every credential ExecBound keeps, the form it is kept in, where it is kept and who can read it, and it says plainly where that protection ends. It was checked against the source on 24 September 2026. The threat model carries the threats behind it, with evidence and status.
What an agent holds
An agent holds one credential: its own ExecBound token, in the form eb1.<tenant>.<credential>.<secret>, which the console calls its API key. An administrator issues it (Get an API key), for up to 90 days or to never expire; a key that never expires stays valid until it is revoked. It opens only the agent routes: proposing an action, reading the status of its own requests, and reading back its own identity. Over MCP those are two tools, execute and execution_status.
An agent never receives a vendor credential, in any form. The connector adds it to the request on the gateway's side, and sends the request to a destination the operator configured, which the agent cannot choose. There is no route that returns configuration, a vendor credential, a signing key or a control store, and no generic passthrough tool.
The one signed thing an agent can receive is a continuation, handed back while a request waits for approval. It is a capability rather than a credential: bound to the tenant, the agent, its credential, the one execution and approval, the plan and a nonce, and expiring within two minutes at most. Its signing key never leaves the gateway.
Four forms, from the least useful to an attacker
- Not kept at all, only a digest. A copy of the database yields nothing that can be turned back into the credential.
- Only a public key. The private half never reaches ExecBound.
- Encrypted in the database. AES-256-GCM under a key ring kept in the deployment's private configuration, so the database alone yields ciphertext.
- In the deployment's private configuration or environment, never in the database. Protected by the host and file permissions, not by encryption.
Every credential
| Credential | Form | Where | Who can read it |
|---|---|---|---|
| Agent token | SHA-256 digest; the token is shown once, when issued | Database | Nobody: only the digest exists |
| Session and form-protection tokens for people | SHA-256 digests | Database | Nobody |
| Invitation and sign-up codes | Digests | Database | Nobody |
| Recovery codes | A domain-separated SHA-256 digest of 96 random bits; shown once | Database | Nobody |
| Passwords | scrypt; the database refuses any other algorithm | Database | Nobody can reverse one. A stolen hash can only be attacked by guessing, which scrypt makes slow, so a weak password is still a weak password |
| Monitoring source tokens | Digest; the token is written once to a file the operator creates | Database, and the operator's file | Whoever holds the operator's file |
| Passkeys | The public key and a signature counter | Database | The private key never leaves the person's authenticator |
| Executor signing keys | Ed25519 public keys only | Database | The private key never leaves the executor, so nothing on ExecBound's side can forge an executor's report |
| Authenticator seeds for multi-factor sign-in | AES-256-GCM | Database, key in the private configuration | A process that can read the deployment's private configuration |
| A customer's identity provider: client secret and refresh token | AES-256-GCM, bound to the tenant, the provider and the purpose, so ciphertext moved to another row does not open | Database, key in the private configuration | A process that can read the deployment's private configuration |
| Vendor credentials for connectors, and their evidence keys | Plain values in the private configuration file | Never the database | A process that can read the private configuration. The connector sends them; the agent cannot. Reusing one across vendor families is refused at startup |
| Continuation signing keys | Private configuration | Never the database | Same |
| Slack and Teams webhook addresses, where the address is itself the secret, and the shared secrets of signed webhooks | Private configuration | Never the database | Same |
| Google and GitHub sign-in client secrets, the mail relay password, the assistant's model key | Environment variables, never written anywhere | Never the database | The deployment's operator |
| Scout's directory read credential | A file the operator keeps, for a read-only registration held separate from any registration that performs actions | Never the database | The operator |
| Database role passwords | The deployment's environment | Never the database | The operator |
No vendor credential is stored in the database. The database holds digests, public keys and the two kinds of ciphertext above, and nothing else of this kind.
What protects them
- Against the agent: the gateway's routes and the database's permissions. The role the gateway runs as cannot write to principals, credentials or approval scopes, and reaches them only through a small set of audited database functions, which is also how the console's administration pages act. The owner connection that migrations and owner commands use has no web route at all.
- Against a copy of the database: a backup, a replica or a query that reaches the tables yields digests, public keys and ciphertext, none of which performs an action on its own.
Where the protection stops
These limits matter as much as the table.
- Anything that can read the deployment's private configuration can open every encrypted secret and use every vendor credential. The key ring and the vendor credentials live there, so the configuration file and the environment are the custody. There is no managed key service or secret manager yet; that is open work on #153.
- Never run an agent where it can read the gateway's configuration. Put it on another host, in another container, or at the least under another operating system account with no read access to the configuration file. On one machine under one account, an agent that can read files can read the configuration, and the only protection left is the gateway's routes. The enforcement is only native where this holds, which is why the first step of the demonstration tries to reach the vendor credential directly and fails.
- The configuration files are owner-only on Linux and macOS. On Windows a file takes the permissions of its folder, so the folder's permissions are its protection.
- ExecBound protects what an agent can do, not the host it runs on. A compromised operator account, host or database owner is outside what these controls address.
Hosted and self-hosted
- Self-hosted: you hold the configuration, the environment and the database. None of these credentials is sent to ExecBound.
- Hosted Community: ExecBound LLC operates the configuration and the database, and so can open the encrypted secrets it holds for you: your people's authenticator seeds and, if you connect one, your identity provider's client secret and refresh token. Passwords, recovery codes and tokens are hashed there too, and cannot be read back. Hosted Community holds no vendor credentials: its providers are ExecBound's protected mocks, and real vendor connections wait on the custody work in #153.
What will change this page
- Managed key custody (#153) moves the key ring out of the configuration file.
- The hybrid executor (#411) keeps vendor credentials inside the customer's own network while using the hosted service.
- The credential store (#406) lets the gateway hold agents' own service credentials under that custody.
All three are designed and none is built. This page changes when one ships, not before.