Skip to content

Latest commit

 

History

History
244 lines (172 loc) · 11.1 KB

File metadata and controls

244 lines (172 loc) · 11.1 KB

Security

Forge is designed with security as a foundational principle, not an afterthought. This document describes the complete security architecture — from network-level egress controls to encrypted secrets, build signing, execution sandboxing, and runtime guardrails.

Security Model

Forge's security is organized in layers, each addressing a different threat surface:

┌──────────────────────────────────────────────────────────────┐
│                       Guardrails                             │
│              (content filtering, PII, jailbreak)             │
├──────────────────────────────────────────────────────────────┤
│                    Egress Enforcement                        │
│       (EgressEnforcer + EgressProxy + NetworkPolicy)         │
├──────────────────────────────────────────────────────────────┤
│                  Execution Sandboxing                        │
│    (env isolation, binary allowlists, arg validation)        │
├──────────────────────────────────────────────────────────────┤
│                   Secrets Management                         │
│         (AES-256-GCM, Argon2id, per-agent isolation)         │
├──────────────────────────────────────────────────────────────┤
│                   Build Integrity                            │
│           (Ed25519 signing, SHA-256 checksums)               │
├──────────────────────────────────────────────────────────────┤
│                   Network Posture                            │
│       (outbound-only connections, no public listeners)       │
└──────────────────────────────────────────────────────────────┘

Table of Contents


Network Posture

Forge agents are designed to never expose inbound listeners to the public internet:

  • No public tunnels — Forge does not create ngrok, Cloudflare, or similar tunnels
  • No inbound webhooks — Channels use outbound-only connections
    • Slack: Socket Mode (outbound WebSocket via apps.connections.open)
    • Telegram: Long-polling via getUpdates
  • Local-only HTTP server — The A2A dev server binds to localhost by default
  • No hidden listeners — Every network binding is explicit and logged

This means a running Forge agent has zero inbound attack surface by default.


Egress Enforcement

Forge restricts outbound network access at three levels:

1. In-Process Enforcer

The EgressEnforcer is a Go http.RoundTripper that wraps every outbound HTTP request from in-process tools (http_request, web_search, LLM API calls). It validates the destination domain against a resolved allowlist before forwarding.

2. Subprocess Proxy

Skill scripts and cli_execute subprocesses bypass Go-level enforcement. A local EgressProxy on 127.0.0.1:<random-port> validates domains for subprocess HTTP traffic via HTTP_PROXY/HTTPS_PROXY env var injection.

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.

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 Resolution

Allowed domains are resolved from three sources:

  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)

Localhost (127.0.0.1, ::1, localhost) is always allowed in all modes.

For full details on egress enforcement, see Egress Security.


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 (forge-cli/tools/exec.go):

Control Detail
Environment isolation Only PATH, HOME, and explicitly declared env vars are passed through
Egress proxy injection HTTP_PROXY/HTTPS_PROXY env vars 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

The cli_execute tool (forge-cli/tools/cli_execute.go) provides 7 security layers:

# Layer Detail
1 Binary allowlist Only pre-approved binaries can execute
2 Binary resolution Binaries are 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

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

Secrets Management

Forge provides AES-256-GCM encrypted secret storage with Argon2id key derivation, per-agent isolation, and a three-tier resolution hierarchy (agent-local -> global -> environment). Secrets are managed via forge secret set|get|list|delete.

For full details, see Secrets Management.


Build Integrity

Forge supports Ed25519 signing and SHA-256 checksumming of build artifacts for supply chain integrity. At runtime, forge run can verify artifacts against trusted keys before execution.

For full details, see Build Signing & Verification.


Guardrails

The guardrail engine checks inbound and outbound messages against policy rules including content filtering, PII detection, and jailbreak protection. Guardrails run in enforce (blocking) or warn (logging) mode.

For full details, see Content Guardrails.


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

Example

{"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"}}

The source field distinguishes in-process enforcer events from subprocess proxy events.


Container Security

Build-Time Artifacts

Every forge build generates container-ready security 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

Runtime Behavior in Containers

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 Checks

forge package --prod

Production builds enforce:

  • No dev-open egress mode
  • No dev-only tools (local_shell, local_file_browser)
  • Secret provider chain must include env (not just encrypted-file)
  • .dockerignore must exist if a Dockerfile is generated

Related Documentation

Document Description
Egress Security Deep dive into egress enforcement: profiles, modes, domain matching, proxy architecture, NetworkPolicy
Secrets Management Encrypted storage, per-agent secrets, passphrase handling
Build Signing & Verification Key management, build signing, runtime verification
Content Guardrails PII detection, jailbreak protection, custom rules
Architecture System design, module layout, and data flows
Tools Tool system including cli_execute security layers
Skills Skill definitions and runtime execution
Commands CLI reference including security-related flags

Channels | Back to README | Egress Security