Alternative, and more robust approach is to give the agent surrogate credentials and replace them on the way out in a proxy. If proxy runs in an environment to which agent has no access to, the real secrets are not available to it directly; it can only make requests to scoped hosts with those.
I’ve built this in Airut and so far seems to handle all the common cases (GitHub, Anthropic / Google API keys, and even AWS, which requires slightly more work due to the request signing approach). Described in more detail here: https://github.com/airutorg/airut/blob/main/doc/network-sand...
Sometimes I need to give Claude Code access to a secret to do something. (e.g. Use the OpenAI API to generate an image to use in the application.) Obviously I rotate those often. But what is interesting is what happens if I forget to provide it the secret. It will just grep the logs and try to find a working secret from other projects/past sessions (at least in --dangerously-skip-permissions mode.)
I use bubblewrap to sandbox the agent to my projects folder, where the ai gets free read/write reign. Non-synthetic env cars are symlinked into my projects folder from outside that folder.
this solves a real problem. i run coding agents that have access to my workspace and the .env files are always the scariest part. even with .gitignore, the agent can still read them and potentially include secrets in context that gets sent to an API.
the approach of encrypting at rest and only decrypting into environment variables at runtime means the agent never sees the raw secrets even if it reads every file in the project. much better than the current best practice of just hoping your .gitignore is correct and your AI tool respects it.
one suggestion: it would be useful to have a "dry run" mode that shows which env vars would be set without actually setting them. helps verify the config is correct before you realize three services are broken because a typo in the key name.
What about something like Hashicorp secrets? We have a the hashicorp secrets in launch.json and load the values when the process is initialized (yeah it is still not great)
Alternative, and more robust approach is to give the agent surrogate credentials and replace them on the way out in a proxy. If proxy runs in an environment to which agent has no access to, the real secrets are not available to it directly; it can only make requests to scoped hosts with those.
I’ve built this in Airut and so far seems to handle all the common cases (GitHub, Anthropic / Google API keys, and even AWS, which requires slightly more work due to the request signing approach). Described in more detail here: https://github.com/airutorg/airut/blob/main/doc/network-sand...
https://github.com/jdx/fnox
A recent project by the creator of mise is related too
1Password has this feature in beta. [1]
[1]: https://developer.1password.com/docs/environments/
This doesn’t really fix that it can echo the secrets and read the logs. `enveil run — printenv`
Not the author but No, the decryption would ask the secret again? The readme mentions it's wiped from memory after use.
https://github.com/getsops/sops
This software has done this for years
this won't solve the problem.
Instead you need to do what hardsnow is doing: https://news.ycombinator.com/item?id=47133573
Or what the https://github.com/earendil-works/gondolin is doing
Sometimes I need to give Claude Code access to a secret to do something. (e.g. Use the OpenAI API to generate an image to use in the application.) Obviously I rotate those often. But what is interesting is what happens if I forget to provide it the secret. It will just grep the logs and try to find a working secret from other projects/past sessions (at least in --dangerously-skip-permissions mode.)
What software do you use that logs credentials?
I use bubblewrap to sandbox the agent to my projects folder, where the ai gets free read/write reign. Non-synthetic env cars are symlinked into my projects folder from outside that folder.
this solves a real problem. i run coding agents that have access to my workspace and the .env files are always the scariest part. even with .gitignore, the agent can still read them and potentially include secrets in context that gets sent to an API.
the approach of encrypting at rest and only decrypting into environment variables at runtime means the agent never sees the raw secrets even if it reads every file in the project. much better than the current best practice of just hoping your .gitignore is correct and your AI tool respects it.
one suggestion: it would be useful to have a "dry run" mode that shows which env vars would be set without actually setting them. helps verify the config is correct before you realize three services are broken because a typo in the key name.
What about something like Hashicorp secrets? We have a the hashicorp secrets in launch.json and load the values when the process is initialized (yeah it is still not great)
Looks good. Almost stopped reading due the npm example, grasped it was just a use case, kept reading.
Kernel keyring support would be the next step?
PASS=$(keyctl print $(keyctl search @s user enveil_key))