AgentStack
MCP verified MIT Self-run

Ironrun

mcp-generalized-labs-ironrun · by Generalized-Labs

Agent-safe sealed command execution — secrets injected behind airgap

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add mcp-generalized-labs-ironrun

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Ironrun? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

ironrun

Manage project environments in the terminal and let AI agents use secrets without reading them.

[](https://github.com/generalized-labs/ironrun/actions/workflows/ci.yml) [](https://goreportcard.com/report/github.com/generalized-labs/ironrun) [](https://github.com/generalized-labs/ironrun/blob/main/LICENSE)


ironrun is a local-first encrypted environment workspace. It gives humans one terminal UI for projects, environments, .env imports, and agent access. Trust an agent session once for a project’s dev environment, then it can work normally while ironrun injects values only into child processes and strips them back out of output before the agent sees them.

Your tests still get a live DATABASE_URL. The agent gets back exit_code: 0 and tests passed — and never the connection string.


Why you might want this

Coding agents (Claude Code, Codex, Cursor, and others) run shell commands on your machine, and those commands can see your environment. Most of the time that's fine. The problem is the small set of commands that print the environment:

printenv                 # dumps every env var, including secrets
cat .env                 # prints your local secrets file
echo $STRIPE_SECRET_KEY  # a normal debugging step
docker inspect web       # config blobs often contain credentials

When an agent runs one of these — often while legitimately debugging something you asked it to fix — the secret value lands in the chat transcript. From there it's in the model's context, it may be in the provider's logs, and it may be in a screen recording or a shared session. You can't un-send it, so the safe response is to rotate the credential.

This isn't hypothetical. From the Claude Code issue tracker:

> "Three confirmed incidents at one operator workstation in ~6 days. Each incident forced a credential rotation. None of these are exotic — they're shapes that came up during normal diagnosis work the model was asked to do." > — anthropics/claude-code#65122

The agents don't redact their own output, and the secret managers you already use (op run, doppler run, infisical run) inject secrets but don't redact either. ironrun adds the missing piece: it sits between the agent and the command so secrets flow in but never flow back out.

The threat you probably haven't seen yet

When Claude Code runs a command that uses a secret — a curl with an Authorization header, a deploy script that reads DATABASE_URL — that command invocation is logged verbatim to:

~/.claude/projects//YYYYMMDD_HHMMSS_*.jsonl

These JSONL files are Claude Code's conversation history. They contain every tool call, every shell command, every piece of output — including the secret values that appeared in those outputs. They persist between sessions and across project restarts.

One developer found this by accident:

> "It will just grep the logs and try to find a working secret from other projects/past sessions"

The logs are readable by any process with access to your home directory. If you've ever run a command through Claude Code that touched a secret, assume that value is in those logs.

ironrun redacts secret values from command output before it reaches the agent — so the values never enter the conversation, and never end up in the JSONL logs.


How it works

┌─────────────────────────────────────────────────────────────┐
│  AI agent (Claude Code, Codex, Cursor, …)                   │
│                                                             │
│   "run the test suite"                                      │
│        │                                                    │
│        ▼                                                    │
│   run_sealed({argv})   ◄── one MCP tool call               │
│        │                                                    │
└────────┼────────────────────────────────────────────────────┘
         │  ironrun takes over here
         ▼
┌─────────────────────────────────────────────────────────────┐
│  ironrun                                                    │
│                                                             │
│  1. Check the human-approved project, dev environment, and  │
│     current agent session                                  │
│  2. Resolve its encrypted environment entries               │
│  3. Run the command with those secrets injected             │
│  4. Stream output through a redactor:                       │
│        any secret value that appears  →  [REDACTED]         │
│  5. Hand back exit code + cleaned output                    │
│                                                             │
│  Agent sees:   exit_code=0, stdout="ok  tests passed"      │
│  Agent doesn't see:   DATABASE_URL=postgres://…            │
└─────────────────────────────────────────────────────────────┘

By default, an agent can use arbitrary argv only during a temporary session you explicitly trust. Strict policy commands remain available for CI, production, and sensitive projects. Ironrun never has a tool that returns a secret’s value.

> ironrun adds approximately 5-10ms per command invocation: ~2ms for provider lookup (env/envfile) up to ~100ms for a 1Password CLI call. The redaction layer adds under 1ms for typical output sizes.


Install

# curl (Linux/macOS — inspectable script, mandatory checksum verification)
curl -fsSL https://ironrun.dev/install.sh -o /tmp/ironrun-install.sh
bash /tmp/ironrun-install.sh

# Go (any platform)
go install github.com/generalized-labs/ironrun/cmd/ironrun@latest

# Verified npm launcher (Node 20+; native Go security boundary)
npx @generalized-labs/ironrun@latest

Windows (amd64) is a beta: download ironrun_Windows_x86_64.zip from the latest release and put ironrun.exe on your PATH.

Check it's on your path:

ironrun version
# ironrun 0.4.0   (a source build prints "ironrun dev")

Quickstart

Set up a project once:

cd your-project
ironrun setup

Setup previews every file it will write, detects .env key names without displaying values, creates an encrypted dev environment, registers MCP clients, and optionally installs the value-blind per-user service.

Then use bare ironrun from anywhere. It opens the global Projects and Inbox workspace. Agent requests appear automatically; Enter opens the exact review and resumes the waiting MCP call after approval or masked secret entry.

The everyday CLI is also intentionally short:

ironrun add OPENAI_API_KEY   # masked prompt; saves to the active environment
ironrun import .env          # preview names, confirm, encrypt, verify
ironrun new staging         # create and switch to a persistent environment
ironrun session             # create and switch to a 24-hour environment
ironrun use dev             # switch environments
ironrun envs                # list names and keys, never values
ironrun run test            # run the approved command named "test"
ironrun trust list          # inspect active trusted agent sessions
ironrun trust revoke ID     # stop one immediately
ironrun status              # value-blind project summary

Run ironrun setup when you also want project agent instructions and MCP configuration. It looks at your project and writes three files:

  • ironrun.yml — a starter policy. It detects your stack (npm/pnpm/yarn/bun, Go, Rust, Python) and your .env, and pre-fills commands like test, dev, and build with the env vars it found.
  • .mcp.json — wires Claude Code up to ironrun (project-scoped MCP server, merged into any existing file).
  • CLAUDE.md, AGENTS.md, .cursorrules — tell the agent (Claude Code, Codex, Cursor) to run commands via run_sealed instead of typing them into a shell.

New policies bind approved commands directly to encrypted environment entry names. Storing or rotating a value never requires a policy edit:

version: "2"
environment_set: active
require_agent_leases: true
allow_proposals: true

commands:
  - id: dev
    argv: [npm, run, dev]
    ttl: 0
    secrets: [DATABASE_URL, STRIPE_SECRET_KEY]

  - id: test
    argv: [npm, test]
    ttl: 120s
    secrets: [DATABASE_URL, STRIPE_SECRET_KEY]

  - id: build
    argv: [npm, run, build]
    ttl: 120s

Import or add values locally, then check the workspace:

chmod 600 .env
ironrun import .env
ironrun status

The import shows key names only, asks for confirmation, verifies the encrypted copy, and warns that the plaintext source remains. Ironrun never offers reveal, clipboard copy, or plaintext export.

Run one yourself to see the redaction:

ironrun run test
# npm test runs with DATABASE_URL and STRIPE_SECRET_KEY set.
# If a test logs the connection string, you'll see [REDACTED] instead.

Existing version-1 policies

Version-1 provider aliases remain supported. Preview a reversible migration:

ironrun migrate
ironrun migrate --apply

Migration copies values transactionally, verifies encrypted storage, preserves policy comments through an AST edit, keeps an ignored backup, and does not delete legacy values. ironrun migrate rollback ID remains available until an explicit ironrun migrate cleanup ID --yes.

Project environment sets

For projects with more than one environment, manage the values entirely from the terminal. On a new project, simply run ironrun: it creates a valid local-vault policy, registers the project identity, creates dev, and opens the control room. The original nested CLI remains available for scripts and advanced operations:

ironrun env init dev
ironrun env set dev HYDRA_DB_API_KEY
ironrun env create staging
ironrun env clone dev staging
ironrun env use staging
ironrun env status
ironrun run hydra-bootstrap

Temporary session sets expire automatically (24 hours by default):

ironrun env create session --temporary --ttl 8h
ironrun env use session
ironrun env prune

Use ironrun run --set staging for a one-run override. env list, env rotate, env delete, env remove, env doctor, and env import cover the remaining lifecycle. Imports accept owner-only dotenv files, display key names but never values, and refuse project-local or group/other-readable files. env export writes only a KEY= template; it never exports plaintext values.

Project metadata lives under .ironrun/ and contains no secret values. The encrypted vault lives outside the repository under ~/.ironrun/vaults/. Every environment has a rotating data key wrapped by a project root key in the native OS credential manager. Existing per-value credential-manager records migrate into the vault on first successful read, with vault commit before legacy delete.

Terminal control room

Run Ironrun with no arguments in a terminal, or use the explicit command:

ironrun
ironrun tui

The TUI opens on the encrypted workspace: environments, masked environment/file secret names, approved commands, and the actions people need most. Use arrows, Enter, Escape, and Tab; press / for the action palette and ? for help. A detected .env can be reviewed by key name, partially selected, confirmed, and verified after encrypted import. Ironrun never deletes the plaintext source for you and warns while it remains. Requests, leases, and audit state live on secondary tabs. There is no reveal, clipboard-copy, or plaintext-export action.

Encrypted file secrets

File-backed secrets are stored as opaque encrypted bytes and materialized only while an approved command runs. Declare a safe basename and the environment variable that receives its temporary path:

secrets:
  service-account:
    env: GOOGLE_APPLICATION_CREDENTIALS
    kind: file
    filename: service-account.json
    allow: [integration-test]
commands:
  - id: integration-test
    argv: [go, test, ./integration/...]
    secrets: [service-account]

Choose Add secret file in the TUI. Ironrun rejects symlinks, traversal, unsafe basenames, permissive source files, and duplicate targets. At execution it creates a unique owner-only directory outside the repository, writes the file with owner-only permissions, injects only its path, redacts literal and common encoded forms of the contents, and removes the directory after success, failure, timeout, or cancellation. Validated stale crash remnants are removed on startup.

Temporary plaintext necessarily exists on disk while the child process uses a file secret. Cleanup limits its lifetime but cannot guarantee physical erasure from SSD media. Use short command timeouts and revoke agent leases when access is no longer needed.

Revocable agent leases

Agent leases are opt-in for compatibility. Require them for MCP execution:

version: "1"
provider: passthrough
require_agent_leases: true

An agent calls request_lease with policy command IDs, a reason, and a desired TTL. The command remains blocked until a human approves it:

ironrun access list
ironrun access approve req_abc123...
ironrun access leases
ironrun access revoke lease_abc123...

Leases are bound to the exact MCP server session, environment, command set, and expiry. Restarting the MCP server creates a new session; old leases do not transfer. Revocation is checked before the next run.

Trusted workspace sessions (the fast agent path)

For normal local development, an agent can call request_workspace_access or attempt run_sealed with an argv array. Ironrun shows one request in the global Inbox. Approve it once and the same MCP session can run normal commands for the selected project and environment for two hours:

ironrun trust list
ironrun trust grant req_abc123
ironrun trust pause trust_abc123
ironrun trust extend trust_abc123 --ttl 2h
ironrun trust revoke trust_abc123

Trusted sessions are pinned to the MCP session, project, and environment. A server restart creates a new session; an old grant cannot transfer. The default scope is the current dev environment. staging and prod require a separate explicit grant. Normal development network access is enabled, which means a trusted agent could deliberately exfiltrate a secret through network or file actions. Ironrun protects agent context, logs, and routine output; it is not an OS sandbox for a process you choose to trust.

Secret requests and encrypted chat capsules

The request_secret MCP tool accepts only a declared alias and reason. It has no plaintext value field. Fulfill it directly through the TUI or masked CLI:

ironrun access fulfill req_abc123...

If the workflow specifically requires pasting through chat, encrypt the value before it enters the transcript:

ironrun capsule create req_abc123...
# masked prompt; prints ir1.

Paste only the ir1. ciphertext. The agent passes it to claim_capsule; Ironrun decrypts and stores it locally. Capsules are project-bound, MCP-session-bound, request-bound, expire within ten minutes, and become unusable after the request is fulfilled. A plaintext key already pasted into chat cannot be retroactively removed from model-provider logs and should be rotated.

Local curl API

Start the owner-only Unix-socket API:

ironrun serve
curl --unix-socket .ironrun/ironrun.sock http://localhost/v1/status
curl --unix-socket .ironrun/ironrun.sock \
  -H 'Content-Type: application/json' \
  -d '{"command_id":"test","environment":"dev"}' \
  http://localhost/v1/run

The API exposes status, environment metadata, access requests, leases, revocation, denial, and sealed execution. It refuses unknown JSON fields and has no endpoint accepting plaintext secret values.

Now start your agent (claude, cursor, …). It sees run_sealed and asks for one trusted workspace session before normal development work. It can then

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.