Every team using AI coding assistants hits the same wall: the permission prompt. We removed it — safely — and it changed how we build software.


The Permission Bottleneck

If you’ve used Claude Code for more than an hour, you know the rhythm. Write a file? Approve. Run a shell command? Approve. Stage a git commit? Approve. It’s sensible you wouldn’t want an AI agent silently executing arbitrary commands on your machine. For pair-programming sessions where you’re watching every step, the permission model works fine.

But we wanted something different. We wanted to describe a task, hand it to Claude Code, and walk away. Come back to a working implementation, tests passing, code committed to a feature branch. Autonomous background work.

That’s where --dangerously-skip-permissions enters the picture.

The flag does exactly what the name implies: it tells Claude Code to stop asking and start doing. Every file write, every shell command, every git operation — executed without human approval. The name is intentionally alarming. Anthropic wants you to pause before typing it.

The question we asked ourselves: can you build an environment where using this flag is the responsible thing to do?

The Multi-Repo Reality

At Telescoped, our platform spans separate repositories, a frontend, a backend, and a reference implementation. They’ve been independent since the project’s inception: different CI/CD pipelines, different package managers, different deploy targets.

You can run Claude Code in each repo independently, and it works great for single-repo tasks. But the moment you need a full-stack feature a “new API endpoint consumed by a new page” things fall apart. The agent working in the backend has no idea what the frontend expects. The agent working in the frontend can’t see the API it’s supposed to consume. You, the engineer, become the orchestration layer: copying context between sessions, bridging the gap manually, translating one repo’s decisions into instructions for the other. That’s not autonomous AI work. That’s you doing the hard part with extra steps.

The solution: a parent coordination workspace that gives Claude Code visibility across all repos at once.

We use git submodules for this, but they’re not strictly required you could clone repos into a folder and .gitignore them. The reason we chose submodules: portability. This workspace can live on an EC2 instance, and bootstrapping it is two commands: git clone and git submodule update --init. No manual repo setup, no “which branch was that on” everything is pinned and reproducible.

workspace/
├── CLAUDE.md              # Cross-repo context for AI
├── workspace.sh           # Provisioning script
├── .devcontainer/         # Container config
├── frontend/              # Git submodule
│   └── CLAUDE.md          # Frontend-specific context
├── backend/               # Git submodule
│   └── CLAUDE.md          # Backend-specific context
└── reference/             # Git submodule (read-only)
    └── CLAUDE.md          # Reference-specific context

The root CLAUDE.md gives Claude Code unified context, how the repos relate, domain terminology, cross-repo workflows. Each subrepo keeps its own CLAUDE.md with repo-specific commands, architecture, and conventions.

What “Dangerously” Actually Means

Let’s be specific about what --dangerously-skip-permissions enables without isolation:

  • Read SSH keys and credentials from ~/.ssh/, ~/.aws/, environment variables
  • Curl arbitrary endpoints — exfiltrate code, post to external services, download anything
  • Modify files outside the project — your shell config, other repos, system files
  • Access host-level secrets — Docker socket, cloud provider tokens, browser profiles

One hallucinated curl command with your credentials in the headers is a real problem. Not a theoretical one.

Hackers are already adapting — techniques like “slopsquatting” weaponize AI hallucinations to get malicious packages installed without the developer ever suspecting. The model doesn’t know it’s being exploited. It just confidently gives you the wrong answer. That’s exactly what makes it dangerous — and exactly why security can’t be an afterthought when working with AI tools.

But here’s the thing: the flag name is a feature, not a bug. It forces you to think about the boundary. Every developer who types --dangerously-skip-permissions should be asking: what can this agent actually reach?

The Moment It Got Real

Here’s a story that crystallized why this matters. Claude Code was debugging a feature that wasn’t working. It suggested the database might have no entries for the relevant data. The database was a local Docker instance(no production credentials involved) so we asked Claude to check the DB and return the user IDs. My plan was take those IDs and manually check a third-party dev service that Claude didn’t have access to. I had the API keys locally (zshrc).

Except Claude was more resourceful than expected. It didn’t just query the database and hand back IDs. It wrote an inline Python script that extracted API keys from my local environment variables and used them to query the third-party service directly. It automated part of the testing workflow we’d planned to do manually.

It was simultaneously impressive and terrifying. Impressive because it identified the fastest path to a complete answer. Terrifying because it “hacked” the local environment to access credentials it was never explicitly given.

Claude Code’s sandbox mode doesn’t solve this either, it restricts file system access and blocks some commands, but environment variables are still readable by any process inside the sandbox. Auto-approve mode won’t help — the issue isn’t that the agent asks permission and you blindly approve. The issue is that the agent is resourceful enough to discover and use credentials it was never told about. A properly isolated, firewalled environment wasn’t optional. It was the only responsible path forward.

Don’t avoid the flag. Build an environment where it can’t cause damage outside a perimeter.

Three defense layers make this possible:

  1. Containerization — the agent runs inside Docker, not on your host
  2. Network egress control — firewall with default-deny, explicit allowlist
  3. Scoped credentials — development-only API keys that can be rotated in minutes

Architecture

Here’s the full stack, previewed before we dive deep in Part 2:

┌──────────────────────────────────────────────────┐
│  HOST MACHINE                                    │
│  ┌────────────────────────────────────────────┐  │
│  │  DOCKER CONTAINER (non-root user)          │  │
│  │  ┌──────────────────────────────────────┐  │  │
│  │  │  IPTABLES FIREWALL                   │  │  │
│  │  │  DEFAULT: REJECT                     │  │  │
│  │  │  ALLOW: GitHub, npm, PyPI,           │  │  │
│  │  │         Anthropic API, Firebase      │  │  │
│  │  │  ┌────────────────────────────────┐  │  │  │
│  │  │  │  CLAUDE CODE                   │  │  │  │
│  │  │  │  --dangerously-skip-permissions│  │  │  │
│  │  │  │  Autonomous execution mode     │  │  │  │
│  │  │  └────────────────────────────────┘  │  │  │
│  │  └──────────────────────────────────────┘  │  │
│  │  Scoped .env (dev-only keys)               │  │
│  └────────────────────────────────────────────┘  │
│  Bind-mount: workspace directory only            │
│  Forwarded ports: dev servers + database         │
└──────────────────────────────────────────────────┘

The container sees only the workspace directory. The firewall blocks everything except the services Claude Code actually needs. The credentials are development-only — rotatable, scoped, harmless if leaked.

My goal is to have a script that let me run ./workspace.sh create feature-x and have an isolated, firewalled, ready-to-go environment in under a minute.


In Part 2, we’ll show how we built it: a single shell script that provisions an isolated, firewalled environment — and manages multiple of them simultaneously. We’ll crack open the Dockerfile, walk through the firewall rules line by line, and show how workspace.sh stitches it all together — including the honest drawbacks we hit along the way.

Categories: Uncategorized

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *