Skip to main content

Architecture

3 mins

Process Isolation #

Agent (MCP client)
    │
    │ Bearer: mac_<base64url macaroon>
    │
    ▼
┌──────────────────┐           ┌──────────────────┐
│  ephyr-broker    │  IPC      │  ephyr-signer    │
│                  ├──────────►│                  │
│  Policy engine   │           │  CA key custody  │
│  Macaroon verify │           │  SSH cert signing│
│  HMAC reducer    │           │  Never on network│
│  Audit logger    │           └──────────────────┘
│  HTTP proxy      │
│  MCP federation  │
│  Task identity   │
└────┬───────┬─────┘
     │       │
  SSH certs  HTTP proxy    MCP federation
     │       │                  │
     ▼       ▼                  ▼
  Targets  Services       Remote MCP servers

ephyr-signer #

Holds the Ed25519 CA private key. Unix socket IPC. Systemd sandbox with ProtectSystem=strict, MemoryDenyWriteExecute, zero capabilities. Never touches the network.

Its jobs: sign SSH certificates and issue delegation certificates to the broker.

ephyr-broker #

Handles everything else:

  • HMAC chain verification – validates macaroon caveat chains
  • Effective envelope reducer – derives most-restrictive authority from accumulated caveats
  • Policy evaluation – eight-step pipeline with per-agent RBAC
  • SSH certificates – requests signing from signer via IPC
  • HTTP proxy – injects stored credentials into outbound requests
  • MCP federation – aggregates tools from remote MCP servers
  • Task tree management – ULID lineage, delegation chains, watermarks
  • Audit logging – structured JSON-line output with ULID correlation
  • Admin dashboard – 11-view web UI on port 8553

ephyr (CLI) #

Agent-side tool for direct operations. Includes ephyr inspect for examining macaroon caveats.

Trust Model #

Tiered Trust #

The signer is the root of trust. The broker generates ephemeral Ed25519 keypairs locally, sends only the public key to the signer, and receives a delegation certificate. Private key material never transits IPC.

Delegation certificates expire on a short cycle (default 1 hour). Broker compromise is bounded by delegation expiry. The root key never leaves the signer.

Authentication Layers #

LayerMechanismStrength
Unix socketSO_PEERCRED (kernel-verified UID)Unforgeable
Session tokens256-bit random via crypto/randStrong
DashboardConstant-time comparison (crypto/subtle)Strong
MCP API keysbcrypt-hashed, cost 10Strong
SSH certificatesEd25519 chain of trustStrong
Auth cacheSHA-256 keyed bcrypt result cache, configurable TTLPerformance

Adversary Tiers #

  1. Unprivileged local user – can reach broker socket if in ephyr-agents group, but cannot impersonate another UID (SO_PEERCRED is kernel-enforced)
  2. Compromised agent – valid session, can request certs within policy limits, cannot exceed rate limits, role boundaries, or caps
  3. Network attacker – can reach TCP ports 8553/8554 but requires dashboard token or valid bcrypt API key

Security Boundaries #

What Ephyr enforces #

ControlMechanism
Access issuancePolicy YAML, RBAC, eight-step pipeline
Task scopeCapability envelopes, macaroon caveats, HMAC chain
Credential isolationSigner/broker process separation
Grant expiryTTL on certificates, epoch watermarking
Delegation limitsMax depth 5, envelope intersection, TTL constraint
Audit trailJSON-line structured logging with ULID correlation
Network isolationnftables UID-based rules, CIDR allow/deny

What Ephyr does NOT enforce #

  • Command filtering – the target host (shell restrictions, sudoers, filesystem permissions) is the enforcement layer
  • OS-level isolation – SELinux, AppArmor, filesystem permissions are outside scope
  • Push revocation to hosts – OpenSSH doesn’t support online CRL for user certificates; TTL is the mitigation
  • Holder binding – task tokens are bearer tokens until Ephyr Bind ships
  • Multi-tenant isolation – single policy file, single CA; deploy separate instances for tenant boundaries

Threat Model #

14 enumerated threats with explicit mitigations. Key properties:

  • Broker compromise does not expose the CA key
  • Host compromise can abuse active grants within TTL only (default 5 minutes)
  • Network isolation is defense-in-depth, not a substitute for host hardening

See the Security Whitepaper and Threat Model for full details.

Dependencies #

Three direct dependencies, all well-established:

ModulePurpose
github.com/gorilla/websocketWebSocket for dashboard and terminal
golang.org/x/cryptoSSH certificates, bcrypt
gopkg.in/yaml.v3Policy YAML parsing

The macaroon implementation is pure Go stdlib (HMAC-SHA256 from crypto/hmac). No external macaroon dependency.

No external databases. No message queues. No container runtime. No ORM.