What is AgentSecrets?
The Zero-Knowledge Difference
How AgentSecrets Works
Installation
Quick Start
Migrating from .env Files
Migrating from Vault / AWS
Migrating from dotenv-vault
Production Checklist
Credential Exposure
What Zero-Knowledge Means
The Proxy Model
The Three-Layer Model
Environments
Agent Identity
Storage Modes
The No get() Principle
Secret-Level Policies
Credential Proxy Overview
Secrets Management
Environments
env Injection
Workspaces & Teams
Projects
Agent Identity
Audit & Governance
account (init / login / logout)
server (get / set / status / reset)
secrets (set / list / delete / push / pull)
proxy (start / stop / status / logs)
call (inject requests via proxy)
env (execute commands with secrets)
workspace (list / create / switch / roles)
project (list / create / use / update)
environment (list / switch / copy / merge)
agent (register / list / tokens)
agent policy (set / get / delete)
logs (list / watch / export / verify)
mcp (serve / install / config)
status (system & session diagnostics)
Aliases & Shortcuts
docs (interactive terminal viewer)
Shell Autocompletion
keychain-auth (daemon & security)
Ecosystem Overview
Zero-Knowledge MCP Server
Integrations Overview
Claude Desktop
Cursor IDE
OpenClaw
HTTP Proxy (Any Client)
LangChain (Native)
CrewAI (Native)
CI/CD Pipeline
SDK Overview
Python SDK
Python API Reference
Python SDK Manual Testing
JavaScript SDK (Soon)
ZK-MCP Integration Guide
Server Overview
5-Layer Architecture
Self-Hosting Guide
Self-Hosting Operations Manual
Server Data Migration
Authentication & Keys
Workspaces & Teams Backend
Projects & Scope Backend
Environments Backend
Secrets & Sync Protocol
Agent Identity Resolution
Telemetry & Metrics Engine
Audit Log Sync
API Endpoint Reference
Cloud Overview & Architecture
The Dual-Engine Model
Cloud Resolver Data Plane
Workload & Agent Tokens
Egress Allowlists & Audit Streams
Cloud REST API Reference
Security Overview
Anti-Impersonation & Process Verification
Encryption Model
Zero-Knowledge Sync
Proxy Security Layers
Threat Model
OWASP Top 10 Mitigation
Security FAQ
Third-Party Audit
Reporting Vulnerabilities
Guides Overview
Building on the SDK
Stripe Integration
OpenAI Integration
Multi-Agent Setup
Onboarding Team
CI/CD Pipeline
Publishing ZK MCP
Rotating Credentials
Auditing Team Activity
Dev to Production
Kubernetes Deployment
Monorepo Setup
Production Proxy Hardening
vs .env Files
vs HashiCorp Vault
vs AWS Secrets Manager
vs dotenv-vault
vs Infisical
When Not to Use
Proxy Not Starting
Proxy Not Resolving
Domain Blocked
Sync Conflicts
MCP Not Connecting
Session Token Errors
Proxy Session Authorization
Keychain Storage & Backends
SSRF & Destination Rules
Installation Issues
Error Codes Reference
Frequently Asked Questions
v3.x
v2.1.0
v2.0.0
v1.4.0
v1.3.x
v1.2.0
v1.1.x
v1.0.x
Secrets & Environmentsenv Injection

Environment Injection Architecture

While the Credential Proxy provides total zero-exposure security for HTTP traffic, modern development stacks frequently rely on tools, database drivers, and SDKs that require credentials in operating system environment variables (os.environ / process.env).

Traditionally, developers solve this by writing .env files to disk or running export KEY=value in their terminal. Both approaches introduce severe security vulnerabilities:

  • Plaintext Disk Exposure: Any background process, malicious package dependency, or autonomous AI agent with filesystem read access can read .env files.
  • Shell Environment Pollution: Running export KEY=value persists secrets in your interactive terminal session, writes them into shell history files (~/.bash_history, ~/.zsh_history), and leaks them to every subsequent command run in that shell.

AgentSecrets solves this through In-Memory Environment Injection via agentsecrets env -- <command>.


The Mental Model: How In-Memory Injection Works

agentsecrets env is an ephemeral process supervisor. It retrieves encrypted secrets from your local operating system keychain, decrypts them in memory, constructs a localized environment block, and spawns the target program directly using the OS execve system call.

Loading diagram...

Under the Hood: The 6-Stage Process Lifecycle

When you execute agentsecrets env -- <command>, the Go runtime executes the following sequence:

1Flag Isolation ()

Standard CLI parsers attempt to parse all incoming flags. If your target command contains flags (e.g. python manage.py runserver --noreload --port 8000), a standard CLI would crash, claiming --noreload is an unknown AgentSecrets flag.

AgentSecrets explicitly sets DisableFlagParsing: true on the command definition:

  • The mandatory -- delimiter marks the strict boundary between AgentSecrets options and child program arguments.
  • The CLI strips -- and forwards all remaining arguments verbatim to the OS executable locator (exec.LookPath).

2Verified Keychain Attestation

Before accessing any secret, the CLI establishes an IPC handshake with the keychain-auth daemon. The daemon verifies the calling binary's cryptographic hash (SHA-256) and PID via kernel-level socket credentials (SO_PEERCRED on Linux, LOCAL_PEERPID on macOS, Named Pipes on Windows). Once attested, the active project's secrets for the selected environment (dev, staging, or prod) are returned to the CLI's memory.

3In-Memory Environment Assembly

The CLI constructs the environment block for the child process:

// cmd/agentsecrets/commands/env.go env := os.Environ() // Inherit host PATH, USER, HOME, etc. for key, value := range secrets { env = append(env, fmt.Sprintf("%s=%s", key, value)) } childCmd.Env = env
  • No File System Footprint: The secrets never touch .env, temporary files, or swap memory.
  • No Shell Scope Pollution: The variables are bound strictly to the childCmd process descriptor. Your parent terminal shell remains completely unmodified.

4POSIX Signal Supervision (Clean Teardown)

In poorly designed process wrappers, pressing Ctrl+C kills the wrapper and leaves the child process running in the background as an orphaned zombie holding open database connections or network ports.

agentsecrets env runs an active signal supervisor:

// Traps SIGINT and SIGTERM and forwards directly to the child process sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) go func() { select { case sig := <-sigChan: if childCmd.Process != nil { childCmd.Process.Signal(sig) } case <-done: } }()

When you stop a server, web worker, or container, agentsecrets env propagates the interrupt signal directly to the child's PID, allowing frameworks like Django, Node.js, and Celery to execute their graceful shutdown hooks.

5Bidirectional Output Stream Masking ()

Even though credentials reside only in child process RAM, buggy application code, unhandled exceptions, or verbose debug logs might inadvertently print os.environ or error traces to the terminal.

To prevent terminal scrollback and CI log leakage, agentsecrets env wraps the child process os.Stdout and os.Stderr in real-time MaskingWriter streams. The interceptor matches and redacts:

  • Plaintext Values: sk_live_51ABC... -> [REDACTED]
  • Base64 Variants: Encoded strings -> [REDACTED]
  • Hex Representations: Hex-encoded bytes -> [REDACTED]
  • URL-Percent Escaped: Query parameters -> [REDACTED]

Output masking is enforced at the kernel pipe layer and cannot be disabled via flags.

6Exit Code Preservation & Audit Recording

When the child command finishes execution:

  1. MaskingWriter flushes any remaining buffered bytes to the terminal.
  2. The exact exit code of the child process (exitErr.ExitCode()) is extracted and returned. If the child exits with code 1 or 127, agentsecrets exits with code 1 or 127. Makefiles, shell scripts, and CI runners behave as if the child was invoked directly.
  3. An audit event is committed to the local audit trail (Method: "ENV", AuthStyles: ["env_inject"]). Crucially, only the secret key names are logged, never the values.

The Security Boundary: Guarantees vs. Trade-offs

It is vital to understand the exact security guarantees of Environment Injection compared to the Credential Proxy:

Security PropertyCredential Proxy (call / SDK)Environment Injection (env --)
Secrets on Physical DiskZero (Never written)Zero (Never written)
Secrets in Shell HistoryZero (Never written)Zero (Never written)
Terminal / Log RedactionYes (credential_echo defense)Yes (MaskingWriter stream interceptor)
Parent Shell ProtectionImmune (Never exported to shell)Immune (Never exported to parent shell or history)
Sibling Process SnoopingImmune (Protected in daemon RAM)Immune (OS kernel memory boundary isolates child)
Exfiltration via Shell envImmune (Key names only)Neutralized (env, printenv, echo $KEY masked to [REDACTED])
Secrets in Target Address SpaceZero (Application only holds key names)Localized to Child RAM (Required for DB drivers)
Target CompatibilityHTTP/HTTPS APIs onlyUniversal (Any CLI, database, runtime, container)

Architectural Rule of Thumb:

  • If your application or AI agent makes outbound HTTP calls (OpenAI, Anthropic, Stripe, GitHub), use the Credential Proxy for true zero-exposure security.
  • If your application requires direct system variables (Postgres DATABASE_URL, Redis credentials, Docker Compose, legacy CLIs), use agentsecrets env to eliminate plaintext .env files from disk.

Next Steps

Was this helpful?
Thanks for your feedback!
Your feedback helps us improve the platform.