Skip to content

Latest commit

 

History

History
783 lines (574 loc) · 46.1 KB

File metadata and controls

783 lines (574 loc) · 46.1 KB

Aixgate — Product Requirements Document

Runtime sandboxing for AI coding agents

Project Aixgate
Repository https://github.com/aixgo-dev/aixgate
Sibling project Aixgo — production AI agent framework for Go
Author Charles Green
Current release v0.1.0 (see GitHub Releases for the canonical version)
Date May 2026
License MIT

Table of Contents

  1. Executive Summary
  2. Problem Statement
  3. Goals and Non-Goals
  4. Users and Use Cases
  5. Product Overview
  6. Architecture
  7. Policy Specification
  8. Audit Log
  9. Packaging and Distribution
  10. Relationship to aixgo.dev
  11. Roadmap
  12. Success Metrics
  13. Risks and Open Questions
  14. Implementation Notes for Contributors
  15. v0.1 Weekend Build Plan
  16. Appendix

1. Executive Summary

Aixgate is a vendor-agnostic runtime sandbox for AI coding agents (Claude Code, Cursor, Aider, OpenAI Codex agents, and any other process that reads and writes files on behalf of an LLM). It enforces deny-by-default filesystem access policies at the OS boundary, ensuring that sensitive files such as .env, cloud credentials, SSH private keys, and personal documents are never exposed to an agent unless an explicit policy rule permits it.

Aixgate is an open-source component of aixgo.dev, the production-grade Go framework for AI agents. Where aixgo provides the primitives to build agents, Aixgate provides the primitives to run them safely on developer workstations. It is written in Go, distributed as a single binary, supports both macOS and Linux, and integrates into existing developer workflows by launching agents inside a transparent filesystem overlay.

The core hypothesis is simple: developers are adopting agentic coding tools faster than they are adopting the security controls to govern them. Today, running an AI agent in a project directory is roughly equivalent to running an untrusted script with full access to the user's home directory. Aixgate closes that gap without requiring behavioral change from the developer or cooperation from the agent vendor.

Key outcomes for v1

  • A developer can launch any AI coding agent with a single aixgate run command and be confident their .env files, credentials, and SSH keys are not accessible to that agent.
  • Policy is declarative, portable across agents, and version-controllable alongside a project repository.
  • Every filesystem access decision is logged to a structured audit trail that can be reviewed, searched, and shipped to a SIEM if desired.
  • Installation and day-one experience are smooth enough that a developer will actually use Aixgate instead of bypassing it.

2. Problem Statement

2.1 The threat model

AI coding agents execute with the full privileges of the user running them. In a typical developer setup, this means:

  • Unrestricted read access to the home directory, including .env files, ~/.aws/credentials, ~/.ssh/, browser-saved passwords, and personal documents.
  • Unrestricted shell execution, allowing the agent to curl, scp, or otherwise exfiltrate anything it can read.
  • Unrestricted write access to project files and system configuration.

This is acceptable when the agent is a trusted local tool operating on intentional input. It is not acceptable when:

  • The agent receives input from untrusted sources (a pasted error message, a GitHub issue, a webpage it was asked to summarize) — the well-documented prompt injection attack surface.
  • The agent operates autonomously for extended periods, with reduced human oversight of each action.
  • The developer is operating under a compliance regime (SOC 2, ISO 27001, financial regulation) that requires access controls over sensitive data.

2.2 Why existing tools do not solve this

Tool category What it does Why it is insufficient
Aqua / Falco / Tetragon Runtime protection for containers and Kubernetes workloads Targets server environments, not developer laptops. No macOS support. Requires privileged kernel access.
macOS App Sandbox Apple's built-in sandboxing for App Store apps Not available to arbitrary developer tools. Configuration is not portable.
Docker Desktop containers Isolate agents in containers Heavy, breaks developer workflow, agents cannot access project source as they expect, no fine-grained policy.
Agent-specific permission prompts e.g. Claude Code's tool approval flow Vendor-specific, inconsistent, bypassable, and the user quickly clicks through.
Vendor MCP servers with allowlists Some agents let you allowlist tools Only works within that vendor's tool-calling flow. An agent that shells out bypasses it entirely.

2.3 Target user

The primary target user for v1 is the individual developer or small team running AI coding agents on a personal or work laptop. Within that audience:

  • Security-conscious individual developers who want a belt-and-braces layer on top of vendor permission prompts.
  • Engineering teams at security-sensitive companies (fintech, healthcare, infrastructure) that want to adopt agentic tooling but need a defensible answer to "how are you protecting customer data and production credentials?"
  • Consultants and contractors, like the author, who run agents across multiple client codebases and need strong guarantees that credentials from one client are not accessible during a session scoped to another.

3. Goals and Non-Goals

3.1 Goals

  • G1. Vendor agnostic. Aixgate works with any AI agent that runs as a local process, without requiring cooperation from the agent vendor.
  • G2. Deny by default. Access to files and commands is denied unless explicitly permitted by the active policy.
  • G3. Transparent. Agents see a filtered filesystem view and shell environment; they do not know they are sandboxed. No agent code changes required.
  • G4. Cross-platform. macOS (Apple Silicon and Intel) and Linux (x86_64 and arm64) are first-class. No Windows support in v1.
  • G5. Low friction. A developer already using Claude Code can adopt Aixgate without changing how they work beyond prefixing aixgate run.
  • G6. Auditable. Every access decision is logged as structured data that can be reviewed or forwarded to a SIEM.
  • G7. Open source. Permissively licensed (MIT), contribution-friendly, part of the aixgo.dev ecosystem.
  • G8. Single binary. Install, upgrade, and uninstall must each be a single command.

3.2 Non-goals (for v1)

  • Windows support. Viable v2; v1 focuses on macOS and Linux where AI agent adoption is concentrated.
  • Kubernetes or CI sandboxing. Aixgate is designed for local developer use. Server-side enforcement is a future aixgo product.
  • Network egress control. Out of scope for v1. We do not intercept outbound connections. A future version may add optional network policy via a local proxy.
  • Replacing agent vendor permission flows. Aixgate is a defense-in-depth layer; it does not tell users to disable Claude Code's built-in approvals.
  • Kernel-level enforcement. v1 uses FUSE and OS-provided process isolation. eBPF and LSM-based enforcement are explicit v2+ territory.
  • Policy marketplace or GUI. v1 ships sensible defaults and YAML policies. A web UI or shared policy registry is a later concern.

3.3 Explicit anti-goals

Aixgate will not attempt to sandbox agents that are running as root, nor will it claim to defend against a motivated attacker with local code execution. The threat model is an agent acting on behalf of the user that may misbehave due to prompt injection, a flawed plan, or a buggy tool use — not an attacker who has already fully compromised the machine.


4. Users and Use Cases

4.1 Personas

Persona A: The security-conscious indie developer

Runs Claude Code on a personal laptop across side projects and contract work. Has had at least one close call where an agent attempted to read a .env or called a destructive command. Wants an always-on guardrail without giving up the productivity of agentic tools.

Persona B: The consultant with multiple clients

Works across several client codebases in a given week. Each client has its own credentials, API keys, and sensitive data. Needs hard boundaries so that a session in Client A's repo cannot see Client B's .env files, regardless of how "helpful" the agent tries to be.

Persona C: The platform engineer at a regulated company

Responsible for approving AI coding agent use across a 50- to 500-person engineering team. Needs a defensible story for the security and compliance teams: centralized policy, audit logs, and provable boundaries. Cares deeply about reproducibility and CI integration in the long run.

4.2 Primary use cases

UC1. Scoped agent session on a project

cd ~/code/client-a/app
aixgate run --profile claude-code -- claude

The agent launches inside a sandbox where only ~/code/client-a/app is readable and writable, plus a small set of system paths required for tooling. The user's home directory, other clients' projects, SSH keys, AWS credentials, and personal documents return as if they do not exist.

UC2. Per-project policy

A project repository contains a .aixgate.yaml file declaring which files the agent may access and which commands it may run. When aixgate run is invoked inside that project, the policy is loaded automatically. The policy is checked into version control and code-reviewed.

UC3. Audit and review

aixgate audit tail
aixgate audit query --since 24h --denied-only

The developer can at any time review every read, write, and exec decision Aixgate made. A security team can ship these logs to a SIEM for monitoring.

UC4. Profile-based defaults

Out of the box, Aixgate ships with profiles for popular agents (Claude Code, Aider, Cursor headless, generic). Each profile encodes the minimum access that agent needs to function, which users can tighten or loosen as desired.


5. Product Overview

5.1 How it works in one paragraph

Aixgate launches the target agent as a child process inside a filesystem namespace (Linux) or sandbox profile (macOS) that presents a FUSE overlay of the real filesystem. The overlay consults the active policy for every read, write, and lookup operation. Allowed paths pass through transparently. Denied paths return ENOENT, making them invisible to the agent. Sensitive paths can optionally return redacted stubs. Every decision is written to a structured audit log. The agent cannot escape this boundary without subverting the OS process isolation primitives Aixgate builds on.

5.2 User-facing surface

CLI commands

aixgate run [--profile NAME] [--policy FILE] -- CMD [ARGS...]

Launches a command inside a sandbox. Policy is resolved in order: explicit --policy flag, project-local .aixgate.yaml, named profile, built-in default.

aixgate init

Creates a .aixgate.yaml in the current directory with safe starter defaults for the detected project type.

aixgate policy check [FILE]

Validates policy syntax and reports any unresolvable globs or unsafe rules (such as overly broad allowlists).

aixgate policy explain PATH

For a given file path, explains what the active policy would do: allow, deny, redact, or prompt.

aixgate audit tail [--follow] [--profile NAME]
aixgate audit query --since 24h [--denied-only] [--path GLOB]

Tail or search the audit log.

aixgate profile list
aixgate profile show NAME

Inspect available built-in and user profiles.

aixgate doctor

Diagnostic command that verifies FUSE is installed, permissions are correct, and the sandbox can be established. Outputs a remediation checklist for common setup issues.


6. Architecture

6.1 Component diagram

Aixgate is a single Go binary composed of the following internal components:

Component Responsibility
CLI (cmd/aixgate) Argument parsing, user-facing commands, orchestration.
Policy engine (internal/policy) Load, validate, and evaluate policies. Returns allow / deny / redact / prompt decisions for a given access request.
Overlay filesystem (internal/fs) FUSE-based filesystem that mediates every syscall through the policy engine. Implements path canonicalization, redaction stubs, and ENOENT masking.
Process sandbox (internal/aixgate/sandbox) Platform-specific process isolation: mount namespaces and landlock on Linux, sandbox-exec on macOS. Responsible for chroot, environment stripping, and PATH restriction.
Audit log (internal/audit) Structured JSONL writer with rotation. Supports live tailing and query.
Profile registry (internal/profiles) Built-in profiles shipped with the binary, plus user profile discovery in ~/.aixgate/profiles.
Prompt daemon (internal/prompt, v1.1) Desktop notifications for interactive allow/deny prompts when policy specifies prompt on deny.

6.2 Suggested repository layout

aixgate/
├── cmd/
│   └── aixgate/                 # CLI entry point
│       └── main.go
├── internal/
│   ├── policy/                 # Parse + evaluate policies
│   │   ├── schema.go           # Policy struct, YAML tags
│   │   ├── loader.go           # Load, merge, extend
│   │   ├── matcher.go          # Glob + rule evaluation
│   │   ├── matcher_test.go
│   │   └── rego.go             # Optional OPA integration (v2)
│   ├── fs/                     # FUSE filesystem (Linux only)
│   │   ├── overlay.go          # Core overlay logic (hanwen/go-fuse, pure Go)
│   │   ├── redact.go           # Stub/redaction generation
│   │   ├── canonical.go        # Path canonicalization
│   │   └── linux.go            # Linux-specific FUSE setup
│   ├── sandbox/                # Process isolation (pure-Go, no cgo)
│   │   ├── sandbox.go          # Cross-platform Sandbox interface
│   │   ├── policy.go           # Policy struct + DefaultV01Policy
│   │   ├── linux.go            # go-fuse overlay + go-landlock + go-seccomp-bpf
│   │   └── darwin.go           # sandbox-exec profile generation + exec.Command
│   ├── audit/                  # Structured logging
│   │   ├── writer.go           # JSONL writer with rotation
│   │   ├── query.go            # Query + tail
│   │   └── schema.go
│   ├── profiles/               # Profile registry
│   │   ├── registry.go
│   │   └── builtin/            # Embedded default profiles
│   │       ├── claude-code.yaml
│   │       ├── aider.yaml
│   │       ├── cursor.yaml
│   │       └── generic.yaml
│   ├── proc/                   # Process lifecycle, signals
│   │   └── supervisor.go
│   └── prompt/                 # Desktop prompts (v1.1)
│       ├── prompt.go
│       ├── darwin.go           # osascript
│       └── linux.go            # notify-send
├── pkg/                        # Public Go API (for aixgo integration)
│   └── aixgate/
│       └── client.go
├── profiles/                   # Shipped example profiles (not embedded)
├── docs/
├── scripts/
├── test/
│   └── e2e/                    # End-to-end tests with real agents
├── .github/
│   └── workflows/
├── go.mod
├── go.sum
├── Makefile
├── LICENSE                     # MIT
├── CLAUDE.md                   # Instructions for Claude Code contributors
└── README.md

6.3 Enforcement boundary

Aixgate is pure Go. No cgo, no C toolchain, no macFUSE kext. Enforcement is delivered per platform by composing pure-Go libraries (on Linux) and host-provided binaries invoked via exec.Command (on macOS), behind a single Sandbox interface.

Linux

  • A mount namespace (unshare(CLONE_NEWNS)) is created for the agent process.
  • A FUSE filesystem is mounted inside the namespace at the agent's perceived root, backed by hanwen/go-fuse (pure Go, no cgo).
  • Landlock is applied via landlock-lsm/go-landlock (Linux 5.13+, pure Go) as a belt-and-braces restriction even if the FUSE layer is somehow bypassed.
  • seccomp-bpf filters installed via elastic/go-seccomp-bpf (pure Go) block ptrace, mount, bpf, and other escape vectors.
  • A restricted PATH and a filtered environment are injected.

macOS

  • sandbox-exec is the primary enforcement mechanism: Aixgate generates a .sb profile from the policy ((allow file-read* (subpath "/foo")) / (deny file-read* (subpath "/foo/secrets"))), writes it to a temp file, and launches the agent via exec.Command("sandbox-exec", "-f", profile, "--", cmd, args...). This is kernel-level TrustedBSD MACF enforcement with genuinely fine-grained path policy.
  • sandbox-exec is deprecated by Apple but ships in every macOS release through Sequoia (2026) and is used by Apple's own components (WebKit, xcrun). We accept the deprecation risk and document FUSE-T + hanwen/go-fuse as a fallback path if Apple ever removes it.
  • Audit events are captured by tailing log stream --predicate 'subsystem == "com.apple.sandbox"' and translated into the Aixgate JSONL format.
  • The Aixgate binary is signed and notarized to avoid Gatekeeper friction, but requires no kernel extension approval.

6.4 Policy evaluation flow

For every filesystem operation the agent performs, Aixgate follows this sequence:

  1. Canonicalize the path, resolving symlinks and .. components against the real filesystem root.
  2. Match the canonical path against the policy's explicit deny rules. If matched, return ENOENT (for reads and lookups) or EACCES (for writes), and log the denial.
  3. Match against redact rules. If matched, return a synthesized stub instead of real contents.
  4. Match against allow rules. If matched, pass through to the real filesystem.
  5. Otherwise, apply the default action (deny for v1). Log the decision.

6.5 Why ENOENT and not EACCES by default

Returning "permission denied" signals to the agent that a file exists but it cannot access it. Well-behaved agents may retry, prompt the user, or report an error that reveals the path. Returning "no such file or directory" gives the agent no information: it proceeds as if the file does not exist.

This choice is deliberate and important; it is why Aixgate is effective against agents that might otherwise try to work around an obstacle. Policies can opt into EACCES semantics per rule for cases where the developer wants visibility.

6.6 Threat model specifics

In scope:

  • A benign agent that is tricked by prompt injection into attempting to read sensitive files.
  • A buggy agent plan that inadvertently tries to touch sensitive files.
  • An agent that attempts to curl or scp credentials out — Aixgate prevents the read; exfiltration is moot.
  • Forked subprocesses (bash -c "cat .env") — the sandbox is inherited via process isolation, not FUSE alone.

Out of scope:

  • An attacker with root privileges on the machine.
  • An attacker with local code execution outside the Aixgate-launched process.
  • Kernel-level exploits.
  • Side-channel attacks (timing, filesystem metadata inference).

7. Policy Specification

7.1 Design principles

  • Readable by humans. YAML, not Rego or CUE for v1. Rego may be added as an advanced-user option in v2.
  • Portable. The same policy runs identically on macOS and Linux.
  • Composable. Profiles can extend other profiles. Project policies can extend a profile.
  • Explicit. No wildcarded inheritance; every effective rule can be traced to a source file and line.

7.2 Example policy

profile: claude-code
extends: defaults/generic
default: deny

filesystem:
  allow_read:
    - ${PROJECT}/**
    - ~/.config/git/**
    - /usr/lib/**
    - /opt/homebrew/**
  allow_write:
    - ${PROJECT}/**
    - ${TMPDIR}/aixgate-*/**
  redact:
    - '**/.env'
    - '**/.env.*'
    - ~/.aws/credentials
  deny:
    - ~/.ssh/id_*
    - ~/Documents/**

exec:
  allow: [git, node, npm, pnpm, python3, go, make]
  deny_args:
    git: ['push --force', 'config --global']

env:
  pass_through: [PATH, HOME, LANG, LC_ALL, TERM]
  inject:
    AIXGATE_ACTIVE: '1'

audit:
  log: ~/.aixgate/audit.jsonl
  on_deny: log   # log | prompt | block_silently

7.3 Precedence rules

When a path matches multiple rules, precedence is:

explicit deny  >  redact  >  allow_write  >  allow_read  >  default

Deny always wins. This is unsurprising, matches firewall conventions, and prevents accidental widening.

7.4 Variables

Variable Resolves to
${PROJECT} The directory aixgate run was invoked from.
${HOME} The current user's home directory.
${TMPDIR} The current user's temp directory.
${AIXGATE_CONFIG_DIR} ~/.aixgate.

7.5 Glob syntax

Aixgate uses doublestar semantics:

  • * matches any non-slash characters.
  • ** matches any number of path segments including zero.
  • ? matches a single character.
  • [abc] matches a character class.
  • {foo,bar} matches alternatives.

7.6 Policy schema (formal)

# JSON Schema equivalent in YAML form
profile: string                         # Required. Profile name.
extends: string                         # Optional. Another profile to extend.
default: "deny" | "allow"               # Default action. v1 recommends deny.

filesystem:
  allow_read: [glob]                    # Paths agent may read.
  allow_write: [glob]                   # Paths agent may write.
  redact: [glob]                        # Paths returned as redacted stubs.
  deny: [glob]                          # Paths always denied (highest precedence).

exec:
  allow: [string]                       # Allowed command basenames.
  deny: [string]                        # Denied command basenames.
  deny_args:
    <command>: [string]                 # Denied argument patterns per command.

env:
  pass_through: [string]                # Env vars passed through.
  inject:
    <key>: <value>                      # Env vars injected.
  strip: [string]                       # Env vars explicitly stripped.

audit:
  log: path                             # Audit log file path.
  on_deny: "log" | "prompt" | "block_silently"
  on_allow: "log" | "none"              # Default: log

8. Audit Log

8.1 Format

One JSON object per line (JSONL), structured to be trivially queryable with jq, grep, or ingested into a SIEM.

{"ts":"2026-04-20T10:12:33Z","profile":"claude-code","pid":4421,"session_id":"01HV2K...","op":"read","path":"/Users/cg/code/project/.env","decision":"redact","rule":"redact:**/.env","agent_cmd":"claude"}

8.2 Fields

Field Description
ts ISO 8601 timestamp, UTC.
profile Active profile name.
pid PID of the process requesting access.
session_id Unique identifier for this aixgate run invocation (ULID).
op Operation: read, write, stat, exec, unlink, rename.
path Canonicalized absolute path.
decision allow, deny, redact, or prompt.
rule Identifier of the rule that produced the decision.
agent_cmd Top-level command that was launched by aixgate run.

8.3 Retention and rotation

Audit logs rotate at 100MB by default, keeping 10 files. Configurable via ~/.aixgate/config.yaml. Aixgate does not delete logs automatically beyond rotation; retention is the user's decision.

8.4 Query examples

# Everything denied in the last day
aixgate audit query --since 24h --denied-only

# Every time .env was touched
aixgate audit query --path '**/.env*'

# Every exec call for a specific session
aixgate audit query --session-id 01HV2K... --op exec

# Live tail filtered to one profile
aixgate audit tail --follow --profile claude-code

9. Packaging and Distribution

9.1 Artifacts

  • Signed macOS universal binary (arm64 + x86_64), distributed as a plain .tar.gz. No .pkg needed — no kernel extension to install.
  • Linux static binary for x86_64 and arm64, distributed as .tar.gz and .deb.
  • Homebrew tap: brew install aixgo-dev/tap/aixgate.
  • Shell installer: curl -sSL https://aixgo.dev/aixgate/install.sh | sh.

9.2 Dependencies

Dependency Purpose
Pure Go, no cgo Aixgate is pure Go. No C toolchain required to build. No cgo symbols in the binary.
sandbox-exec (macOS) Host-provided binary invoked via exec.Command. Ships with every macOS version; no install needed.
FUSE (Linux) Kernel module available by default on most distributions; userland support via fuse3 package. Loaded lazily on first aixgate run.
No external runtime Aixgate does not require Docker, VMs, macFUSE, or a background daemon.

9.3 Licensing

MIT, matching aixgo.dev. Contributions accepted under a lightweight DCO (Developer Certificate of Origin).


10. Relationship to aixgo.dev

Aixgate is the security and runtime isolation primitive in the aixgo.dev ecosystem. The cross-project story is documented in detail in the Aixgo PRD § 12; this section covers the same relationship from Aixgate's side.

The relationship is intentionally layered:

aixgo.dev project Role
aixgo (framework) Build agents: orchestration patterns, LLM providers, memory, tools. See https://github.com/aixgo-dev/aixgo.
Aixgate Run agents safely on developer workstations. Enforces filesystem and exec policy at the OS boundary.
aixgo-cloud (future) Run agents safely in server and CI environments. Shares policy format with Aixgate.

This layering gives aixgo.dev a credible answer to the single most common security question asked about agent frameworks: "how do I stop it from reading my credentials?" Aixgate's existence strengthens the framework's positioning for enterprise and security-conscious adopters, and in turn the framework's community distribution accelerates Aixgate's adoption.

10.1 Integration points

  • aixgo agents can detect the AIXGATE_ACTIVE=1 environment variable and surface sandboxed status in their UI, giving users confidence that their boundaries are being enforced.
  • aixgo's built-in tool definitions (file_read, shell_exec) can optionally emit additional context into Aixgate's audit log via a local socket, enabling per-tool-call attribution rather than per-syscall.
  • Shared policy schema: the same .aixgate.yaml file will eventually be interpretable by aixgo-cloud's server-side enforcement, enabling "write policy once, enforce everywhere."

10.2 Positioning notes

  • Aixgate is not bundled with aixgo. An agent built on aixgo may run without Aixgate, and Aixgate sandboxes agents built on anything.
  • The aixgo framework does not depend on Aixgate. The dependency is one-way and optional.
  • Marketing message: "aixgo.dev builds agents. Aixgate keeps them in their lane."

11. Roadmap

11.1 v0.1 — Proof of concept (2 weeks)

  • FUSE overlay on macOS and Linux that hides .env, ~/.ssh/id_*, ~/.aws/credentials by default.
  • aixgate run command with hardcoded policy.
  • No configuration, no audit log, no profiles. Single purpose: prove the enforcement boundary holds across at least three agents (Claude Code, Aider, a custom Go agent from aixgo).

11.2 v0.2 — Usable alpha (4 weeks)

  • YAML policy file support.
  • Built-in profiles for Claude Code, Aider, and a generic default.
  • Structured audit log with tail and query commands.
  • aixgate doctor diagnostic command.
  • Published to Homebrew and Linux packages.

11.3 v1.0 — Public launch (3 months)

  • Prompt-on-access with desktop notifications.
  • Project-local .aixgate.yaml discovery and extends:-style composition.
  • Signed installers, notarization, first-run UX polish.
  • Documentation site, example policies, and integration guides for the top five agents.
  • Launch blog post and BSides Tokyo talk.

11.4 v1.x and beyond

  • Windows support via a WFP-based filesystem filter.
  • Optional network egress policy via a local HTTPS proxy.
  • Rego policy backend for organizations with existing OPA investment.
  • Server-side variant for CI and Kubernetes: aixgo-cloud integration.
  • eBPF-based enforcement on Linux as an optional belt-and-braces layer.
  • Policy marketplace: community-contributed profiles for specific frameworks, languages, and cloud providers.

12. Success Metrics

12.1 Adoption metrics

  • GitHub stars on the aixgate repo: 500 within 3 months of v1.0 launch; 2,500 within 12 months.
  • Homebrew install count: 1,000 weekly active installs within 6 months of v1.0.
  • At least 5 community-contributed profiles for agents not authored by the core team.

12.2 Quality metrics

  • Zero known policy-bypass vulnerabilities in v1.0. A responsible disclosure policy is in place.
  • False positive rate (legitimate agent operations incorrectly denied): under 5% on the default Claude Code profile, measured against a benchmark of 50 common coding tasks.
  • p95 read latency overhead versus native filesystem access: under 10ms on an NVMe SSD.
  • Startup overhead of aixgate run versus direct launch: under 500ms.

12.3 Strategic metrics

  • Aixgate is cited in at least one public post-mortem where it prevented credential exposure.
  • Aixgate drives measurable traffic and conversion to aixgo.dev the framework, as tracked by referrer analytics on docs and GitHub.
  • At least one enterprise adopter references Aixgate in a security questionnaire response.

13. Risks and Open Questions

13.1 Technical risks

Risk Impact Mitigation
macOS sandbox-exec is Apple-deprecated (has been for years); future macOS could remove it. High Binary still ships in every macOS release through 2026 and is used by Apple's own tooling. Document a FUSE-T + hanwen/go-fuse fallback path; build the Sandbox interface so the implementation can swap without touching callers. aixgate doctor detects and warns if sandbox-exec is missing.
Agents fork subprocesses that escape the sandbox. High Rely on mount namespaces (Linux) and sandbox-exec child inheritance (macOS) rather than FUSE-only enforcement. Add landlock where available.
Symlink and path traversal bugs in the overlay leak data. High Canonicalize before every policy check. Comprehensive test suite including adversarial traversal cases. Third-party security review before v1.0.
Policy complexity leads to footgun allowlists. Medium aixgate policy check warns on overly broad rules. Ship safe defaults. Document common patterns.
FUSE performance overhead breaks agent UX. Medium Benchmark against native. Cache policy decisions per path per session. Optimize hot paths.

13.2 Product risks

Risk Impact Mitigation
Users assume agent vendors' built-in sandboxes are sufficient and Aixgate is redundant. Low The premise is empirically false on two fronts. First, vendor sandboxes get bypassed routinely. Cursor's YOLO mode accumulated seven CVEs in 2025 including shell-builtin and obfuscation bypasses of the denylist; a Claude Code agent at Ona discovered /proc/self/root/usr/bin/npx to bypass the denylist, and when bubblewrap blocked that path the agent simply disabled the sandbox itself; Google Antigravity's "secure mode" was defeated by prompt-injection-to-RCE; CVE-2025-54795 (Claude Code) and GHSA-534m-3w6r-8pqr (Cursor) are argument-injection bypasses of pre-approved commands. Agents are designed to break out when they decide a goal needs it; vendors are still patching new bypasses every quarter. Second, vendor-only sandboxing requires trusting the same vendor with both execution and audit. An audit trail written by the audited process is not an audit trail — when the agent is compromised, its log becomes part of the attack surface. Aixgate enforces at the OS boundary (Landlock + seccomp on Linux, sandbox-exec on macOS) below the agent's reach, and writes its audit log from the host process, not the agent. Defense-in-depth and vendor-independence, not redundancy.
Users disable Aixgate because the default profile is too strict. High Ship permissive-but-safe defaults. Make it easy to allow specific paths on the fly. Prioritize the "it just works" path for popular agents.
Open source positioning conflicts with future commercial offering. Medium Commit clearly that the core enforcement and policy engine are MIT forever. Commercial layer, if any, is around managed policy distribution, SIEM integration, or enterprise support — not gating core features.

13.3 Open questions

  • Should we support a "learning mode" that observes agent behavior and suggests policy? Useful for first-time users but potentially a security anti-pattern.
  • How do we handle agents that legitimately need a one-off read of a sensitive file (for example, reading a .env to verify a variable is present)? Redaction? Prompt? Neither?
  • Should the audit log be tamper-evident (hash chain, append-only) by default, or is that over-engineering for v1? Resolved (May 2026): tamper-evident audit logging is foundational, not over-engineering. The whole point of a host-written log is that an independent reviewer (operator, engineer, auditor) can verify what the agent did without trusting the agent or the host. Hash-chained append-only by default; cryptographic signing for the v0.2 SIEM integration path. See §13.2 for context.
  • Is there a meaningful difference between "Aixgate" as a standalone product and aixgo aixgate as a subcommand of an eventual aixgo CLI? Naming decision to revisit before launch.
  • Should .aixgate.yaml support environment-specific overrides (dev vs staging vs demo contexts)?

14. Implementation Notes for Contributors

This section is intended to be read by Claude Code and human contributors working in the aixgo.dev repo.

14.1 Core libraries

Concern Library Notes
CLI spf13/cobra Consistent with aixgo's existing CLI patterns.
Config spf13/viper + goccy/go-yaml YAML parsing with line-number errors.
FUSE (Linux) hanwen/go-fuse Pure-Go FUSE library, no cgo. Actively maintained; nodefs/pathfs layers.
Landlock (Linux) landlock-lsm/go-landlock Pure-Go Landlock bindings. Linux 5.13+, ABI v4+ for network. Defense-in-depth.
Seccomp (Linux) elastic/go-seccomp-bpf Pure-Go seccomp-bpf filter. Blocks ptrace, mount, bpf. NOT seccomp/libseccomp-golang (cgo).
Sandbox (macOS) sandbox-exec via os/exec (stdlib) Host-provided binary. Generate SBPL profile, invoke with exec.Command.
Globs bmatcuk/doublestar Supports ** and brace expansion.
Logging log/slog (stdlib) Structured logs by default.
Audit log/slog JSONHandler + natefinch/lumberjack for rotation
ULIDs oklog/ulid Session IDs.
Testing stdlib testing + stretchr/testify Match aixgo conventions.

14.2 Key design decisions to respect

  1. The policy engine is pure. Given a policy and an access request, it returns a decision. It does not perform I/O, log, or have side effects. This makes it trivially testable.
  2. The FUSE overlay only implements the minimum filesystem operations needed. Prefer refusing exotic operations (ioctl, xattr) to implementing them partially.
  3. Path canonicalization happens exactly once per request, at the top of the policy check. Never trust a path that has not been canonicalized.
  4. Audit log writes are fire-and-forget from the FUSE hot path. Use a buffered channel; block on it only if the buffer is full, and prefer to drop with a counter metric rather than stall the agent.
  5. Platform-specific code lives in files suffixed _darwin.go / _linux.go. Shared logic lives in the unsuffixed file. Use Go build tags only where necessary.
  6. No cgo anywhere. All dependencies must be pure Go. On Linux, FUSE goes through hanwen/go-fuse; on macOS, sandboxing goes through sandbox-exec invoked via os/exec. This keeps binaries small, cross-compilation trivial, and eliminates the C-toolchain requirement for contributors.
  7. Platform mechanisms are asymmetric. Linux uses FUSE as the primary enforcement (per-op policy eval + rich audit); macOS uses sandbox-exec as the primary (kernel-enforced SBPL policy + OS log audit). Both sit behind a Sandbox interface so the rest of the codebase is platform-agnostic.

14.3 Testing strategy

  • Unit tests for the policy engine (internal/policy). Exhaustive table-driven tests covering precedence, variable substitution, glob semantics, and malformed input.
  • Integration tests for the FUSE overlay using a temporary mount and a known policy. Assert that specific reads return ENOENT, specific writes fail, and allowed paths pass through.
  • Adversarial tests for path canonicalization: symlink loops, .. traversal, null bytes, unicode normalization edge cases.
  • End-to-end tests in test/e2e that launch real agents (or scripted agent mocks) inside Aixgate and verify behavior. These are slow and live outside the default go test ./....
  • Benchmarks for policy decision latency and FUSE throughput.

14.4 Coding conventions

  • Follow gofmt, goimports, and golangci-lint with the aixgo.dev shared config.
  • Errors wrap with fmt.Errorf("context: %w", err); never bare-return.
  • No init() functions except for registering cobra commands and embedded profiles.
  • Every exported function in pkg/aixgate has a godoc comment starting with the function name.
  • Internal packages (internal/...) are not stable API; do not depend on them from outside the repo.

14.5 Security review requirements

Before v1.0:

  • Third-party security review of the FUSE overlay and path canonicalization.
  • Fuzz testing of the policy parser and glob matcher.
  • Threat model review against the documented boundary in §6.6.
  • Responsible disclosure policy (SECURITY.md) and a signed PGP key for vulnerability reports.

14.6 Documentation requirements

  • README.md — installation, quickstart, link to docs site.
  • docs/ — full user documentation, policy cookbook, profile authoring guide.
  • CLAUDE.md — instructions for Claude Code contributors (architecture overview, dev loop, testing commands, PR conventions).
  • SECURITY.md — threat model, reporting process.
  • CONTRIBUTING.md — DCO, code style, PR process.
  • Per-profile docs in docs/profiles/ explaining the rationale for each rule in each default profile.

15. v0.1 Weekend Build Plan

Status (May 2026): v0.1.0 has shipped. See https://github.com/aixgo-dev/aixgate/releases/latest. This section is preserved as a historical record of the original scope and as guidance for contributors approaching the codebase. The roadmap for what comes next lives in § 11.

A concrete, scoped proof-of-concept that a contributor (human or Claude Code) can complete in a weekend. The goal was to validate the enforcement boundary and the UX hypothesis, not to ship a product.

15.1 Scope

  1. Single Go binary named aixgate, built pure Go (no cgo).
  2. One command: aixgate run -- CMD [ARGS...].
  3. Hardcoded policy: hide every file matching **/.env, **/.env.*, ~/.ssh/id_*, ~/.aws/credentials by returning ENOENT (Linux, via FUSE) or denying file-read* in the generated SBPL profile (macOS, via sandbox-exec). Everything else passes through.
  4. macOS + Linux support. One platform is enough for the PoC; the other may be stubbed behind the Sandbox interface.
  5. No config, no audit log, no profiles, no tests beyond a minimal smoke check.

15.2 Milestones

  1. Stand up the Sandbox interface and a pass-through implementation for the contributor's platform.
    • On Linux: mount a pass-through FUSE overlay via hanwen/go-fuse. aixgate run -- ls ~ works and shows the real home directory through the FUSE mount.
    • On macOS: generate an SBPL profile that allows everything, write it to a temp file, and exec the agent via sandbox-exec -f profile.sb -- CMD. aixgate run -- ls ~ works and shows the real home directory under the sandbox.
  2. Add the deny rules. aixgate run -- cat ~/.ssh/id_rsa returns "No such file or directory" on Linux (FUSE ENOENT) and an access-denied on macOS (sandbox deny). aixgate run -- cat ~/.aws/credentials same. aixgate run -- ls ~/.ssh does not show id_* files on Linux; on macOS the files are visible in ls but unreadable (SBPL can't hide existence, only deny access — document this platform asymmetry).
  3. Verify against a real agent. Launch Claude Code inside aixgate run in a directory containing a .env. Confirm the agent reports it cannot find or read the file, and does not surface the contents in any form.
  4. Verify subprocess containment. aixgate run -- bash -c "cat .env" also fails, proving that forked children inherit the sandbox on both platforms (mount namespace on Linux; SBPL is per-process-tree on macOS).

15.3 Definition of done for v0.1

  • go build ./cmd/aixgate produces a working binary on the contributor's platform.
  • The four hardcoded paths are provably hidden from shell commands launched via aixgate run.
  • At least one real AI agent (Claude Code preferred) has been tested inside the sandbox and its logs/UI confirm it cannot see the protected paths.
  • A 200–400 word writeup of what worked, what didn't, and what the UX surprises were. This becomes the basis for the launch blog post and informs v0.2.

15.4 Out of scope for v0.1

Everything else in this PRD. Resist the urge to build the policy engine, audit log, profiles, aixgate doctor, installers, or documentation beyond a two-paragraph README. The goal is to learn, not to ship.


16. Appendix

16.1 Glossary

Term Meaning
Agent A process driven by an LLM that reads and writes files, runs commands, and otherwise acts on the user's behalf.
FUSE Filesystem in Userspace. Lets a userspace program provide a filesystem that the kernel exposes to other processes.
Landlock A Linux kernel feature (5.13+) that lets a process voluntarily drop filesystem access, used as defense in depth.
sandbox-exec A macOS tool that launches a process under a TrustedBSD sandbox profile. Used extensively by Apple's own system components.
Profile A named set of Aixgate policy defaults, typically shipped with the binary and specialized per agent.
Policy The effective rule set governing a Aixgate session, composed from profile defaults and project-local overrides.
Canonicalization The process of resolving a path to its absolute, symlink-free, ..-free form before policy evaluation.
ULID Universally unique, lexicographically sortable identifier. Used for session IDs.

16.2 Prior art

  • Aqua Security, Falco, and Tetragon for container runtime protection. These informed the "enforcement at the OS boundary, not the application" thesis.
  • Bubblewrap and Flatpak on Linux for user-space process isolation primitives.
  • Apple's sandbox-exec and App Sandbox for the macOS enforcement model.
  • Deno's permission model as an example of what built-in, policy-based runtime security looks like when done well.
  • Docker's --read-only and tmpfs mount patterns for the "present a filtered filesystem view" primitive.
  • OpenBSD's pledge(2) and unveil(2) for the general design principle of restricting a process to the minimum it needs.

16.3 References and further reading

16.4 Document history

Version Date Author Notes
0.1 April 2026 Charles Green Initial draft.
0.2 April 2026 Charles Green Rebrand Warden → Aixgate.
0.3 April 2026 Charles Green Replace cgofuse with pure-Go sandbox stack (hanwen/go-fuse + go-landlock + go-seccomp-bpf on Linux, sandbox-exec on macOS). Confirm aixgate lives in the aixgo monorepo — see ADR 0001.
0.4 May 2026 Charles Green Rename jail/Jailer to sandbox/Sandbox throughout (legacy terms left over from the Warden→Aixgate rebrand). Document v0.1 weekend-build PoC results in PR #3.

End of document.