When “don't ask again” saves your API key
Agent security
A file that remembers which commands your coding agent may run can quietly become a credential store.
In research published November 5 and updated November 8, 2026, Apiiro reported 2,539 distinct exposed secrets across 1,994 public GitHub repositories. Its classification identified likely credentials; researchers did not attempt to use them, so the count does not establish how many remained valid. Read Apiiro's research.
The reported sequence is ordinary development work: an agent constructs a
shell command containing a credential, the developer grants a standing
approval, and Claude Code saves the literal command in
.claude/settings.local.json. If that file gets committed, the credential
travels with it. Apiiro also found exposures in history, shared settings, and
saved agent conversations. Its findings show that secret-bearing artifacts
extend beyond the files developers deliberately use for configuration.
Source: Apiiro.
Seekrit can help at two points in this workflow: keep values out of command text, and, where the integration supports it, keep the provider credential out of the agent's reach altogether. Those offer different levels of protection.
Clean up existing exposure first
If a credential has reached a repository, revoke or rotate it at its issuer before treating the cleanup as complete. Deleting the current file cannot invalidate copies in old commits, forks, or other people's clones. GitHub's sensitive-data removal guide explains both the priority of revocation and the coordination required for history cleanup.
Then check what your repository actually tracks. These commands list paths and commits without printing the files' contents:
git ls-files -- .claude/settings.local.json .claude/settings.json
git log --all --oneline -- .claude/settings.local.json .claude/settings.json
Repeat for agent directories in nested projects. Review sensitive contents in a trusted local tool, rather than pasting them into another agent conversation.
Anthropic's settings documentation
confirms that standing approvals are saved in the local settings file and
describes its global Git exclude rule. Put
**/.claude/settings.local.json in the repository's own .gitignore as well,
and untrack existing copies. Keep shared .claude/settings.json available for
team configuration, but review it for embedded values.
Include agent-generated files in your secret-scanning coverage and review staged changes before committing. These controls help catch mistakes after a value has been copied. The next step is to reduce the copying itself.
Keep secret values out of the command
For a trusted application or maintenance script, Seekrit's CLI can resolve secrets and inject them into the child process's environment. The command you approve names the application, environment, and script:
seekrit run --app storefront --env staging -- node scripts/check-db.mjs
This assumes you have authenticated to Seekrit, stored the staging credentials,
and written check-db.mjs to read its connection configuration from environment
variables. The command contains no database password or connection URL for an
approval file to remember. The script can use the database without generating
a plaintext .env export.
The child process still receives real values. It can print them, send them
elsewhere, or include them in an error. An agent that can change the script or
invoke seekrit run -- env with the same authority can obtain those values too.
Wrapping the coding agent itself in seekrit run gives that agent the secrets.
Use this approach when the process is trusted with its credentials. Keep its
grants narrow, remove obsolete plaintext copies, and avoid environment dumps
and shell tracing. Ordinary seekrit run can continue with local environment
values if remote resolution fails, so applications should validate required
configuration on startup. The CLI reference
documents precedence and failure behavior.
Keep the provider key outside the agent
For supported HTTP API calls, Seekrit's credential proxy
provides a stronger separation. The agent sends a placeholder such as
{{seekrit:REPORTS_API_KEY}}. The proxy resolves the real value and substitutes
it into a permitted outbound request.
Here is an illustrative route for a reporting API. The hostname and endpoint are examples; configure them for the service you actually use:
[[route]]
prefix = "/reports"
upstream = "https://api.example.com"
allow = ["REPORTS_API_KEY"]
methods = ["GET"]
paths = ["/v1/status"]
On a private network where only the authorized workload can reach this broker, the agent's request can look like this:
curl http://seekrit-proxy:8080/reports/v1/status \
-H 'Authorization: Bearer {{seekrit:REPORTS_API_KEY}}'
The proxy strips the route prefix, checks the method, path, and permitted secret name, then forwards the authenticated request to the configured upstream. An approval file recording that command would contain the placeholder. It would not gain the provider key from the command text.
The deployment determines whether this separation holds:
| Component | What it receives |
|---|---|
| Agent workspace and commands | Secret names, placeholders, and access to permitted broker operations |
| Isolated proxy | The Seekrit service token and decrypted credentials it needs |
| Upstream API | The credential required to authenticate the permitted request |
Keep the proxy's SEEKRIT_TOKEN, process, configuration, and administration
outside the agent's control. A second process under the same unrestricted
user account does not establish that boundary. Use a separate service, OS
identity, or container isolation the agent cannot administer; protect remote
broker access with authenticated ingress. A placeholder does not authenticate
the caller.
The proxy supports restrictions on destinations, secret names, methods, and paths. Set the method and path restrictions explicitly: omitting them permits any method or path covered by the route. Choose endpoints that cannot return credentials or act as arbitrary forwarding services. The proxy also redacts supported echoes of injected values from responses, but that is a backup control, not a guarantee against every transformation or disclosure.
An agent can still misuse an allowed operation, incur charges, or receive
sensitive response data. If your design requires all traffic to pass through
the proxy, enforce that with network isolation; an HTTPS_PROXY variable alone
does not constrain an agent with shell access.
This is the Seekrit integration to use when the requirement is to keep a reusable provider key away from the coding agent. Giving the agent the proxy's service token would undo that separation.
Give database tasks temporary access
An HTTP credential proxy does not automatically broker a native Postgres connection. For a trusted database script, Seekrit can instead create a temporary database user and inject its connection URL for that run:
seekrit run --app storefront --env staging \
--lease DATABASE_URL=staging-readonly --lease-ttl 15m \
-- node scripts/check-db.mjs
Here staging-readonly must already be a registered Postgres target configured
with read-only grants; the name itself does not enforce permissions. Lease
operations currently require an organization admin or owner, so keep the
launcher and its authentication under trusted control.
The CLI mints the temporary identity, injects its URL, and attempts revocation when the command exits. Expiry provides a fallback if immediate cleanup cannot run. The receiving process can still expose the temporary credential, and cleanup does not guarantee termination of established database sessions. See the lease lifecycle and limitations.
Temporary access reduces how much standing authority a task needs. It complements careful handling of commands and output; it does not make a credential harmless while it is usable.
Every development tool leaves artifacts. Design the credential path so those artifacts can record what happened without acquiring a reusable provider key. Start with runtime injection for trusted processes, or use the proxy setup guide to separate agent access from credential custody.