seekrit
← all posts

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:

ComponentWhat it receives
Agent workspace and commandsSecret names, placeholders, and access to permitted broker operations
Isolated proxyThe Seekrit service token and decrypted credentials it needs
Upstream APIThe 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.