Hand an agent a scoped credential
Provision a capability-, project-, and expiry-scoped API key and run an AI agent against your database safely.
This is the credential half of Agent-Safe Change Control: how to mint a key an agent can hold safely, and hand it over without leaking a stronger one. The enforcement half — budgets, lanes, risk lint, promote policy — is Guardrails. Available today.
An agent-safe credential is a Kisenon API key with three bounds — capability, scope, and expiry — handed to the agent in a clean environment. The rule in one line: scope the agent's credential, and don't leave a stronger one where the agent can reach it.
1. Provision a scoped agent credential
Mint an API key with all three dimensions set:
capability = agent— can drive sandboxes, butkeon connection-string main(and every writable-mainroute) returns403. The agent can propose changes; it never holds a credential that writes production.scope = project— confined to one project. A leak can't reach your other projects.expires_at(short) — a bounded blast radius on leak. Days, not forever.
Mint it in the console — Settings → API keys at
kisenon.com — with Capability =
agent, Scope = a project, and Expires set. API keys are minted from a
signed-in browser session; a plain CLI key can't mint another key. Using the
key on a writable-main route returns exactly:
agent-scoped API keys cannot retrieve data-plane credentials or perform
branch-admin role/database operations; use the sandbox flow2. Hand it to the agent correctly
Give the agent its scoped key as its only credential, in a clean shell or container:
export KEON_API_KEY=nsk_<agent-key> # the scoped agent key, and ONLY this
unset DATABASE_URL # no full connection string in the env
# also: no personal `keon login` session (no ~/.config/keon/credentials.json),
# no ~/.pgpass, no admin DATABASE_URL reachable from the agent's process.PowerShell, same rule:
$env:KEON_API_KEY = "nsk_<agent-key>" # the scoped agent key, and ONLY this
Remove-Item Env:DATABASE_URL -ErrorAction SilentlyContinue
# also: no personal `keon login` session (no %USERPROFILE%\.config\keon\credentials.json),
# no %APPDATA%\postgresql\pgpass.conf, no admin DATABASE_URL reachable from the agent's process.Two-part rule, both required:
- Scope the credential you hand the agent (step 1).
- Remove the stronger ones it could otherwise pick up — a full
DATABASE_URL, a~/.pgpass, or a logged-inkeonsession in the same shell.
libpq's password file is ~/.pgpass on macOS and Linux, but
%APPDATA%\postgresql\pgpass.conf on Windows (PGPASSFILE overrides both).
On Windows, check that file — ~/.pgpass is never read there.
If you keep a password file for your own sessions, lock it to your user. On
macOS and Linux that is chmod 0600 ~/.pgpass; libpq ignores the file if
group or others have any access to it. libpq does no such check on Windows, so the ACL is
the only protection. Drop the inherited entries and grant only yourself:
icacls "$env:APPDATA\postgresql\pgpass.conf" /inheritance:r /grant:r "${env:USERNAME}:F"Either way this keeps other users out. It does not keep out an agent running as you — that is why the file has to be out of the agent's reach, not just private.
3. The safe loop
The agent proposes; a human — or its own bounded promote — disposes:
keon sandbox run \
--migrate "alembic upgrade head" \
--verify "pytest tests/db"keon sandbox run forks the branch, mints a short-lived agent token into an
isolated home, and injects the fork's scoped URL as DATABASE_URL for your
command — so even a command that tries keon connection-string main inside the
sandbox hits the agent key and gets 403. Review the captured diff, then
promote per the project's promote_mode:
promote_mode | Who commits to main |
|---|---|
self (default) | The agent runs keon sandbox promote <id> once its checks pass. |
human | The agent proposes; an owner/admin runs keon sandbox approve <id> after reviewing the diff + log. |
Turn on human review with keon projects update --promote-mode human.
What this is (and is not)
- A guardrail for a cooperating agent, not a jail for hostile code. Scoping the credential limits what you hand the agent; it does not contain a subprocess that already has host filesystem or network access. Real containment — a scrubbed environment, no host credential access, egress limited to the sandbox endpoint — is a separate layer. Add it too when the agent's code is untrusted.
- cp is the only writer to
main. Promotion replays the captured statements server-side; the agent never holds a writable-maincredential.
Break-glass
There is no special "break-glass" switch, by design. The direct writable-main
path is just a normal read_write credential held by a human (keon connection-string main, or the console) — deliberately unreachable from the
agent key. For an audited incident path, an operator uses their own
read_write session; every promote and approve is attributed server-side.