Faramesh Docs
Concepts

Architecture

How the Faramesh daemon, lifecycle, supervisor, OS-tier sandbox, interception tiers, providers, and optional cloud control plane fit together end-to-end.

This page explains the runtime architecture of a Faramesh stack. What processes run, what they do, in what order, and where the trust boundaries are.

If you haven't read How Faramesh works yet, do that first. This page assumes you know the placement and the decision pipeline.

Components at a glance

ComponentProcess modelRole
governance.fmsFile on diskSource of truth: agents, rules, imports, providers.
CLI (faramesh)Short-livedcheck, plan, apply, dev, audit. Compiles and operates the stack.
DaemonLong-lived processEvaluates every tool call. Never bypassed in enforce mode.
Interception tierIn-process or daemon portHow calls reach the daemon (SDK shim / MCP proxy / HTTP proxy).
Agent supervisorThreads inside the daemonSpawns and supervises agent child processes under the OS sandbox.
ProvidersSubprocesses launched by the daemonMint secrets, sign DPRs, ship audit records.
WAL / DPRSQLite + append-only fileHash-chained local audit; optional KMS signature.
Faramesh CloudExternal SaaS (optional)Fleet UI, approvals, DPR replica. Not in the enforcement path.

The daemon lifecycle

The daemon goes through explicit states. The Unix socket is only opened after the daemon is READY: early calls return DAEMON_NOT_READY instead of being silently evaluated against an incomplete policy.

Daemon lifecycle
STARTING ──► INITIALIZING ──► READY ──► (running) ──► HALT
                  │                                    ▲
                  └──── on cold-start exceeded ────────┘
StateWhat happens
STARTINGProcess is up; no I/O yet.
INITIALIZINGOpen WAL, replay governance state, verify DPR chain, load policy, init providers, init telemetry. Socket is not yet open.
READYPolicy AST is loaded, providers verified, lifecycle marked ready. Socket starts listening. SDK calls are evaluated.
HALTCold-start budget exceeded, or fatal init error. Process exits non-zero.

The window during which calls return DAEMON_NOT_READY is configurable:

governance.fms
runtime {
  cold_start_deny_window = "5s"
}

Why this exists: if the daemon answered calls during init, the agent could race the policy load and slip through with the previous (or empty) AST. Faramesh fails closed.

→ See Denial codes for the full DAEMON_NOT_READY payload.

The interception tiers in detail

The agent never reaches the real tool endpoint. There are three places where the call gets redirected to the daemon:

Interception
                                ┌── SDK shim ──┐
                                │  (in-proc)   │
              ┌──── tier 1 ─────┘              │
              │                                ▼
   Agent ─────┤── tier 2 ───► MCP proxy ───► daemon
              │                  (port)        ▲
              │                                │
              └──── tier 3 ───► HTTP proxy ────┘
                                  (port)

Each tier has trade-offs documented in Interception. For untrusted agent code where bypass via direct SDK calls is a concern, combine the application tier with the OS-tier sandbox (next section).

The agent supervisor and OS-tier sandbox

This is the layer most product surfaces miss. When you set:

governance.fms
runtime {
  os_tier                   = true
  strip_ambient_credentials = true
  agent_enforce_profile     = "full"      # full | minimal | off
  supervised_command        = "python agent.py"   # optional
}

Two new behaviors kick in.

3a. The generated launcher (.faramesh/bin/agent)

faramesh apply writes a small, deterministic launcher script into your stack:

.faramesh/bin/agent
#!/bin/sh
# Generated by faramesh apply — do not edit.
. "$STACK_DIR/.faramesh/runtime/agent.env"
if [ "$FARAMESH_ENFORCE_PROFILE" = "off" ]; then exec "$@"; fi
exec "$FARAMESH_CLI" __agent-exec "$FARAMESH_ENFORCE_PROFILE" "$STACK_DIR" "$FARAMESH_PROXY_PORT" -- "$@"

You start your agent through the launcher:

Terminal
.faramesh/bin/agent -- python agent.py

The launcher:

  1. Loads .faramesh/runtime/agent.env (socket path, agent id, enforce profile).
  2. If os_tier = true, re-execs through __agent-exec, which applies the OS sandbox.
  3. Strips ambient credential env vars if strip_ambient_credentials = true.
  4. Sets FARAMESH_AUTOLOAD=1 so the SDK auto-patches the framework.

There is no separate faramesh run command. The launcher is the single entry point; governance.fms is the only thing that drives its behavior.

3b. The daemon supervisor

When runtime { supervised_command = "..." } is set, the daemon launches and supervises the agent child itself after reaching READY. You don't need to remember to invoke the launcher. faramesh apply starts the daemon, and the daemon starts the agent.

Supervised lifecycle
faramesh apply


daemon: STARTING → INITIALIZING → READY


                          agentSupervisor.Launch()


                        __agent-exec (sandbox)


                              agent process


                          (calls flow back through SDK shim)

The supervisor:

  • Owns the child's PID and reaps on exit (logs and clears state).
  • Applies the same OS sandbox that .faramesh/bin/agent would have.
  • Strips ambient credentials before exec.
  • Exposes supervisor_launch, supervisor_stop, supervisor_list over the SDK socket so external tooling (or a future operator UI) can manage children programmatically.

supervised_command is optional. If you set it, the daemon manages the child. If you don't, you start the agent yourself with .faramesh/bin/agent --. Both paths use exactly the same sandbox: they differ only in who starts the process.

3c. The OS sandbox itself

__agent-exec applies platform-specific syscall and filesystem confinement before exec:

PlatformMechanismWhat it blocks
Linuxseccomp-BPF + LandlockDisallowed syscalls (e.g. kill/tkill/tgkill against foreign PIDs), filesystem writes outside the stack dir, raw network without going through Faramesh
macOSSeatbelt (sandbox-exec)File writes outside stack dir, network connections except to localhost (where the daemon listens)
OtherApplication-tier onlySandbox not applied; daemon still enforces policy via the SDK shim / proxy

Profiles map to severity:

  • agent_enforce_profile = "full": strict sandbox; the agent can talk to the local daemon and nothing else without policy approval.
  • agent_enforce_profile = "minimal": looser sandbox for development.
  • agent_enforce_profile = "off": no OS sandbox; SDK/proxy tier only.

→ Full security posture: Security model.

Where each piece runs

Process map
┌──────────────────────────────────────────────────────────────┐
│  faramesh daemon (one process, long-lived)                    │
│                                                               │
│  ┌────────────────┐  ┌────────────────┐  ┌─────────────────┐ │
│  │ policy engine  │  │ agent          │  │ provider        │ │
│  │ (in-memory AST)│  │ supervisor     │  │ launchers       │ │
│  └────────────────┘  └──────┬─────────┘  └─────────┬───────┘ │
│                             │                      │         │
│  ┌────────────────┐  ┌──────┼──────────┐  ┌───────▼────────┐ │
│  │ SDK socket     │  │ MCP proxy port  │  │ Vault, SPIFFE, │ │
│  │ (Unix socket)  │  │ HTTP proxy port │  │ KMS providers  │ │
│  └────────────────┘  └─────────────────┘  │ (subprocesses) │ │
│                                            └────────────────┘ │
│                                                               │
└──────────────────────────────────────────────────────────────┘
        │                       │                       │
        ▼                       ▼                       ▼
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Agent process │       │ MCP / HTTP    │       │ Real Vault,   │
│ (sandboxed)   │       │ client        │       │ KMS endpoints │
└───────────────┘       └───────────────┘       └───────────────┘

The daemon is one process. The supervisor and the policy engine live as components inside it; they don't run as separate processes. Providers run as subprocesses launched by the daemon and verified against the keys in trust { }.

Trust boundaries

ComponentTrust levelWhy
DaemonTrustedThe thing enforcing policy and writing audit.
ProvidersTrusted after signature verificationLoaded from the registry; verified against trust { }.
Agent processUntrustedTool args and model output are inputs to policy, not authority.
Faramesh CloudUntrusted (optional)Visibility plane. Never on the enforcement path.

The agent being untrusted is the whole point. Everything else flows from that assumption.

Catalog and registry

Imports in governance.fms resolve from github.com/faramesh/faramesh-registry:

  • Framework profiles: fPL wiring for a runtime tier.
  • Policy packs: reusable rules (Stripe, shell, GitHub, MCP, …).
  • Providers: signed binaries downloaded at faramesh apply.

The CLI fetches from GitHub by default. For air-gapped setups, mirror the catalog and set FARAMESH_REGISTRY_ROOT.

→ Details: Registry overview.

The full apply → run sequence

When you run faramesh apply and your governance.fms has os_tier = true and supervised_command, here's the full sequence end to end:

apply → run
1.  faramesh apply
       └─► parse + check governance.fms
       └─► resolve registry imports (verify signatures)
       └─► download/verify provider binaries
       └─► compile to .faramesh/policy.bin (deterministic AST)
       └─► write .faramesh/runtime/agent.env
       └─► write .faramesh/bin/agent (launcher)
       └─► write .faramesh/runtime/cli.path
       └─► start (or reload) daemon

2.  daemon starts
       └─► STARTING
       └─► INITIALIZING (open WAL, replay, init providers)
       └─► READY
       └─► open SDK socket, MCP/HTTP ports
       └─► wireAgentSupervisor()
              └─► if supervised_command: launch via __agent-exec
              └─► strip ambient credentials
              └─► apply OS sandbox

3.  agent starts (under sandbox)
       └─► FARAMESH_AUTOLOAD=1 patches the framework
       └─► every tool call → daemon (steps 1–12 of pipeline)
       └─► permits run with brokered credentials
       └─► defers wait for approval
       └─► every decision → DPR → WAL → optional Cloud replica

That's the entire system. Everything else in the docs is depth on top of these seven steps.

On this page