Forge Trust & Security

Forge is a secure, portable AI Agent runtime. Run agents locally, in cloud, or enterprise environments without exposing inbound tunnels. Here's how.

Project Health

Live Status

CI Status

Unknown

Latest Release

v0.0.0

Advisories

0

published

License

Apache-2.0

Architecture

Security Architecture

Atomicity. Security. Portability. Every layer of Forge's architecture is designed to make these properties verifiable, not just claimed.

Forge's security is organized as a defense-in-depth stack. Each layer addresses a different threat surface, and layers are independently enforceable. No single layer failing compromises the entire system.

Guardrails

Content filtering, PII detection, jailbreak protection

Inbound and outbound messages are checked against configurable policy rules. Built-in guardrails include content filtering, PII detection (email, phone, SSN), and jailbreak phrase detection. Modes: enforce (blocking) or warn (logging).

Egress Enforcement

EgressEnforcer + EgressProxy + NetworkPolicy

Three-level outbound network control: an in-process Go RoundTripper validates every HTTP request, a localhost proxy enforces the same rules on subprocess traffic (curl, wget, Python), and Kubernetes NetworkPolicy restricts pod-level egress in production.

Execution Sandboxing

Env isolation, binary allowlists, arg validation

External code runs through sandboxed executors with environment isolation, binary allowlists, argument validation (rejects shell injection patterns), configurable timeouts, and output size limits. No shell expansion — ever.

Secrets Management

AES-256-GCM, Argon2id, per-agent isolation

Secrets are encrypted at rest using AES-256-GCM with Argon2id key derivation. Storage is per-agent with a provider chain: agent-local encrypted → global encrypted → environment variables. Files are 0600, excluded from git and Docker.

Build Integrity

Ed25519 signing, SHA-256 checksums

Every build computes SHA-256 checksums of all artifacts and signs them with Ed25519. Verification at runtime checks checksums and validates signatures against a trusted keyring. Production builds reject dev-open egress and dev-only tools.

Network Posture

Outbound-only connections, no public listeners

Forge agents never expose inbound listeners. No ngrok, no Cloudflare tunnels, no inbound webhooks. Slack uses Socket Mode (outbound WebSocket), Telegram uses long-polling. The dev server binds to localhost only. Zero inbound attack surface by default.

Layer 6

Network Posture

A running Forge agent has zero inbound attack surface by default. This is a fundamental design constraint, not a configuration option.

No Public Tunnels

Forge does not create ngrok, Cloudflare, or similar tunnels. There is no mechanism for inbound connections from the public internet.

No Inbound Webhooks

Channels use outbound-only connections. Slack uses Socket Mode (outbound WebSocket via apps.connections.open). Telegram uses long-polling via getUpdates.

Local-Only HTTP

The A2A dev server binds to localhost by default. It is never exposed to the network without explicit configuration.

Explicit Bindings

Every network binding is explicit and logged. No hidden listeners, no background services, no surprise ports.

Layer 5

Egress Control

Forge restricts outbound network access at three independent levels, each catching traffic that could bypass the previous layer.

Three-Level Enforcement

Level 1

In-Process Enforcer

A Go http.RoundTripper wraps every outbound HTTP request from in-process tools. Validates destination domain against the resolved allowlist before forwarding.

Level 2

Subprocess Proxy

A local EgressProxy on 127.0.0.1:<port> validates domains for subprocess HTTP traffic via HTTP_PROXY/HTTPS_PROXY injection.

Level 3

Kubernetes NetworkPolicy

In containerized deployments, generated Kubernetes NetworkPolicy manifests enforce egress at the pod level, restricting traffic to allowed domains on ports 80/443.

Proxy Architecture

┌─────────────────────────────────────────────────────┐
│                   forge run                         │
│                                                     │
│  In-process HTTP ──→ EgressEnforcer (RoundTripper)  │
│                                                     │
│  Subprocesses ──→ HTTP_PROXY ──→ EgressProxy        │
│  (curl, wget,       127.0.0.1:<port>  (validates   │
│   python, etc.)                        domains)     │
└─────────────────────────────────────────────────────┘

Egress Modes

Mode Behavior
deny-all All non-localhost outbound traffic blocked
allowlist Only explicitly allowed domains (exact + wildcard)
dev-open All traffic allowed (development only)

Domain Matching Rules

  • Exact match: api.openai.com matches api.openai.com
  • Wildcard match: *.github.com matches api.github.com but not github.com
  • Case insensitive: API.OpenAI.COM matches api.openai.com
  • Localhost bypass: 127.0.0.1, ::1, and localhost are always allowed in all modes

Domain Resolution

Allowed domains are resolved from three sources, combined and deduplicated:

  1. Explicit domains — listed in forge.yaml under egress.allowed_domains
  2. Tool domains — automatically inferred from registered tool names (e.g., web_searchapi.tavily.com)
  3. Capability bundles — pre-defined domain sets for common services (e.g., slackslack.com, hooks.slack.com, api.slack.com)

Configuration

# forge.yaml
egress:
  profile: standard
  mode: allowlist
  allowed_domains:
    - api.example.com
    - "*.github.com"
    - hooks.slack.com
  capabilities:
    - slack
    - telegram

Production vs Development

Setting Production Development
Profile strict / standard permissive
Mode deny-all / allowlist dev-open
Dev tools Filtered out Included
Network policy Enforced Not generated
Egress proxy Active Skipped
Container egress NetworkPolicy Proxy

Layer 4

Execution Sandboxing

Forge agents execute external code through two sandboxed executors, both designed to minimize the attack surface of subprocess execution.

SkillCommandExecutor

Skill scripts run via SkillCommandExecutor with the following controls:

Control Detail
Environment isolation Only PATH, HOME, and explicitly declared env vars passed through
Egress proxy injection HTTP_PROXY/HTTPS_PROXY route subprocess HTTP through the egress proxy
Configurable timeout Per-skill timeout_hint in YAML frontmatter (default: 120s)
No shell Runs bash <script> <json-input>, not through a shell interpreter
Scoped env vars Only env vars declared in the skill's requires.env section are passed

CLIExecuteTool — 7 Security Layers

The cli_execute tool provides layered security enforcement:

# Layer Detail
1 Binary allowlist Only pre-approved binaries can execute
2 Binary resolution Resolved to absolute paths via exec.LookPath at startup
3 Argument validation Rejects arguments containing $(, backticks, or newlines
4 Timeout Configurable per-command timeout (default: 120s)
5 No shell Uses exec.CommandContext directly — no shell expansion
6 Environment isolation Only PATH, HOME, LANG, explicit passthrough vars, and proxy vars
7 Output limits Configurable max output size (default: 1MB) to prevent memory exhaustion

Configuration

# forge.yaml
tools:
  - name: cli_execute
    config:
      allowed_binaries: ["git", "curl", "jq", "python3"]
      env_passthrough: ["GITHUB_TOKEN"]
      timeout: 120
      max_output_bytes: 1048576

Skill Trust

Trust Model

Trust is computed, not declared. Contributors cannot set their own trust level.

Trust Levels

Level Value Visible Executable Used For
Failed -1 No No Skills that fail validation or security analysis
Untrusted 0 Yes No Discovered but not evaluated, or failed remote signature
Under Review 1 Yes No Has warnings, pending admin promotion
Trusted 2 Yes Yes Passed all gates — fully active

Autowire Pipeline

Skills are autodiscovered and trust-evaluated through a pipeline:

Directory Scanner → Frontmatter Parser → Security Analyzer → Trust Evaluator
   Find dirs          Parse YAML           Verify hints        Assign trust
   with SKILL.md      + validate           vs actual content   level

Security Analyzer Checks

Check What Severity
Egress/network mismatch trust_hints.requires_network: false but egress domains declared Critical
Shell/scripts mismatch trust_hints.requires_shell: false but scripts/ exists Critical
Dangerous script patterns curl|sh, eval, rm -rf /, chmod 777 Critical
Hardcoded secrets API_KEY=... patterns in scripts Critical
Broad binary request Requiring bash, sh directly Warning
Overly permissive egress Wildcard patterns, CDN domains Warning
Env var leak risk Scripts that echo/print secrets Warning

Trust Rules by Tier

Embedded Skills

Always Trusted — curated by Forge maintainers.

Local Skills (strict)

Validation fail → Failed. Security critical → Failed. Security warning → Under Review. All clean → Trusted.

Remote Skills (leveled)

Failed at remote → Failed (never shown). Invalid signature → Untrusted. Untrusted registry → capped at Under Review. Trusted registry + clean → Trusted.

Layer 3

Secrets Management

Forge provides encrypted secret storage with per-agent isolation and defense-in-depth.

Encryption

Algorithm

AES-256-GCM

Authenticated encryption

Key Derivation

Argon2id

Memory-hard, resistant to GPU attacks

File format: salt(16 bytes) || nonce(12 bytes) || ciphertext. Plaintext format is JSON key-value map.

Storage Hierarchy

Secrets are resolved in order, with earlier sources taking priority:

# Source Location
1 Agent-local <agent-dir>/.forge/secrets.enc
2 Global ~/.forge/secrets.enc
3 Environment os.Getenv()

Passphrase Handling

Context Behavior
forge run (TTY) Prompts interactively if FORGE_PASSPHRASE not set
forge run (CI/CD) Reads from FORGE_PASSPHRASE environment variable
forge init (first time) Prompts for passphrase + confirmation
forge init (subsequent) Prompts once and validates against existing file

File Safety

  • .forge/ directories are automatically added to .gitignore
  • *.enc files are excluded in .dockerignore
  • Secret files use 0600 permissions (owner-only read/write)
  • Secret files never appear in container images

CLI Commands

forge secret set OPENAI_API_KEY              # Prompts for value securely
forge secret set SLACK_BOT_TOKEN xoxb-...    # Inline value
forge secret get OPENAI_API_KEY              # Shows value and source
forge secret list                            # Lists all keys
forge secret delete OLD_KEY                  # Removes a key
forge secret set API_KEY --local             # Agent-local secret

Layer 2

Build Signing & Integrity

Forge supports Ed25519 signing of build artifacts for supply chain integrity verification.

Signing Flow

1

forge build computes SHA-256 checksums of all generated artifacts

2

If a signing key exists at ~/.forge/signing-key.pem, checksums are signed with Ed25519

3

checksums.json is written with checksums, signature, and key ID

Verification Flow

1

Validates SHA-256 checksums of all files against checksums.json

2

Verifies the Ed25519 signature against trusted keys in ~/.forge/trusted-keys/

3

If checksums.json doesn't exist, verification is skipped (opt-in model)

Key Management

forge key generate                     # Generate Ed25519 keypair
forge key generate --name ci-key       # Named keypair
forge key trust ~/.forge/signing-key.pub   # Add to trusted keyring
forge key list                         # List signing + trusted keys

Production Build Safety

The build pipeline includes a secret-safety stage that enforces production constraints:

  • Blocks production builds that only use encrypted-file without env provider
  • Warns if .dockerignore is missing alongside a generated Dockerfile
  • Rejects dev-open egress mode in production builds
  • Filters out dev-only tools (local_shell, local_file_browser)

Layer 1

Guardrails

The guardrail engine checks inbound and outbound messages against configurable policy rules.

Built-in Guardrails

Guardrail Direction Description
content_filter Inbound + Outbound Blocks messages containing configured blocked words
no_pii Outbound Detects email addresses, phone numbers, and SSNs via regex
jailbreak_protection Inbound Detects common jailbreak phrases ("ignore previous instructions", etc.)

Enforcement Modes

Mode Behavior
enforce Blocks violating messages, returns error to caller
warn Logs violation, allows message to pass

Runtime

# Run with guardrails enforced
forge run --enforce-guardrails

# Default: warn mode (log only)
forge run

Observability

Audit Logging

All runtime security events are emitted as structured NDJSON to stderr with correlation IDs for end-to-end tracing.

Event Types

Event Description
session_start New task session begins
session_end Task session completes (with final state)
tool_exec Tool execution start/end (with tool name)
egress_allowed Outbound request allowed (with domain, mode)
egress_blocked Outbound request blocked (with domain, mode)
llm_call LLM API call completed (with token count)
guardrail_check Guardrail evaluation result

Correlation Threading

Every event carries a 16-hex-character correlation_id that links all events within a single task session. The source field distinguishes in-process enforcer events from subprocess proxy events ("source": "proxy").

Example Output

{"ts":"2026-02-28T10:00:00Z","event":"session_start","correlation_id":"a1b2c3d4","task_id":"task-1"}
{"ts":"2026-02-28T10:00:01Z","event":"tool_exec","correlation_id":"a1b2c3d4","fields":{"tool":"tavily_research","phase":"start"}}
{"ts":"2026-02-28T10:00:01Z","event":"egress_allowed","correlation_id":"a1b2c3d4","fields":{"domain":"api.tavily.com","mode":"allowlist","source":"proxy"}}
{"ts":"2026-02-28T10:00:05Z","event":"tool_exec","correlation_id":"a1b2c3d4","fields":{"tool":"tavily_research","phase":"end"}}
{"ts":"2026-02-28T10:00:06Z","event":"session_end","correlation_id":"a1b2c3d4","fields":{"state":"completed"}}

Deployment

Container Security

Every forge build generates container-ready security artifacts for production deployment.

Build Artifacts

Artifact Purpose
egress_allowlist.json Machine-readable domain allowlist
network-policy.yaml Kubernetes NetworkPolicy restricting pod egress
Dockerfile Container image with minimal attack surface
checksums.json SHA-256 checksums + Ed25519 signature

Container Runtime Behavior

When Forge detects it's running inside a container (via KUBERNETES_SERVICE_HOST or /.dockerenv):

  • The local EgressProxy is not startedNetworkPolicy handles egress enforcement at the infrastructure level
  • All other security controls (guardrails, execution sandboxing, audit logging) remain active
  • Secrets must use the env provider (encrypted files can't be decrypted without a passphrase)

Production Build

forge package --prod

Production builds enforce: no dev-open egress mode, no dev-only tools, secret provider chain must include env, and .dockerignore must exist if a Dockerfile is generated.

Reporting

Responsible Disclosure

Report a Vulnerability

If you discover a security vulnerability in Forge, please report it responsibly.

Security Contact

security@initializ.ai

Response Timeline

  • • Acknowledge within 48 hours
  • • Fix within 90 days

GitHub Security Advisories

View published advisories →

Standards

Compliance & Standards

Available Today

  • Apache 2.0 open-source license
  • NDJSON audit logs with correlation threading
  • AES-256-GCM encrypted secrets at rest
  • Ed25519 signed builds with checksum verification
  • Layered egress enforcement with NetworkPolicy

Roadmap

  • SOC 2 Type II readiness
  • HIPAA-compliant skill packs (via Hub Enterprise)
  • SIEM integration guides
  • Dependency vulnerability scanning (govulncheck)