# Serve-Mode Exposure Security Decision

Status: Accepted
Date: 2026-03-11
Step: `security-and-docs.security-decision-doc`

## 1. Problem Statement

`anima serve` exposes a remote MCP control surface over HTTP/SSE for agent lifecycle
operations and streaming interactions (see `INTERFACES.md`, Sections B/C). The stream
bridge design intentionally deferred policy details to Phase 5. We now need a
security decision that defines exposure posture, trust boundaries, and authentication
requirements without changing the current public interface contract.

This decision covers serve-mode endpoint exposure and access control policy. It does
not redesign transport schemas or MCP tool payloads.

## 2. Phase-5 Context and Constraints

- Preserve the current API surface in `INTERFACES.md` (serve tools and `/stream`).
- Keep localhost-first behavior (`--host 127.0.0.1` default) as safe baseline.
- Do not require breaking changes to existing orchestration clients.
- Align with the stream bridge decision that separated transport semantics from
  security policy.

## 3. Threat Model

### 3.1 Assets

- Agent control operations (`anima.spawn`, `anima.kill`, `anima.interact`,
  `anima.collect`).
- Agent outputs and logs, including potentially sensitive prompts/responses.
- Node-local execution capability reachable via spawned agents and their tools.

### 3.2 Adversaries

- Unauthenticated network clients reaching exposed serve endpoint.
- Authenticated but unauthorized clients (cross-tenant or wrong role).
- Replay attackers reusing captured bearer/session material.
- Passive network observers when transport is not TLS-protected.

### 3.3 Primary Risks

- Unauthorized remote agent execution and tool invocation.
- Data exfiltration through logs, `collect`, and stream endpoints.
- Denial-of-service through request/stream fan-out abuse.
- Confused deputy behavior when multiple orchestrators share one node.

## 4. Trust Boundaries

1. **Client/Network boundary**: Any connection to serve HTTP/SSE endpoints is
   untrusted until authenticated.
2. **Serve control plane boundary**: The serve process is trusted to enforce
   authentication and authorization before invoking MCP bridge logic.
3. **Agent runtime boundary**: Spawned agents and MCP tool servers are partially
   trusted workloads; they must not be treated as an authorization boundary.
4. **Node boundary**: Host-level isolation and OS controls remain the final
   containment layer if higher-level controls fail.

## 5. Authentication Requirements

Minimum requirements for non-local serve exposure:

- Strong caller identity on every request (no anonymous access).
- Transport confidentiality/integrity (TLS termination at edge or in-process).
- Short-lived credentials with rotation support.
- Request-scoped identity available to authorization and audit logging.
- Distinct handling for streaming endpoints (`/stream` and future stream routes)
  so long-lived sessions are authenticated at connect time and attributable.

## 6. Auth Options Considered

### Option A: Network Perimeter Only (IP allowlist / private subnet)

Pros:

- Lowest implementation effort.
- No changes to serve request handling.

Cons:

- Weak identity guarantees inside trusted network.
- Poor auditability and weak tenant isolation.
- Not sufficient for internet-exposed or shared-network deployments.

### Option B: Reverse Proxy Auth Fronting Serve (Recommended)

Use a trusted gateway/reverse proxy to terminate TLS and enforce authn/authz,
forwarding only authenticated traffic to `anima serve` on localhost/private link.

Pros:

- Preserves current serve API and endpoint behavior.
- Reuses mature enterprise auth controls (OIDC, mTLS, policy engines, rate limits).
- Clear rollout path without breaking existing clients when deployed behind proxy.

Cons:

- Security posture depends on deployment discipline.
- Requires strict network policy so serve is not directly reachable.

### Option C: In-Process Auth in Serve

Pros:

- Self-contained enforcement by the application.
- Potentially simpler single-binary deployment story.

Cons:

- Larger implementation and maintenance surface in anima.
- Higher risk of auth drift from infrastructure standards.
- Delays Phase-5 closure versus gateway-first controls.

## 7. Decision and Recommended Posture

Choose **Option B: reverse-proxy-fronted authentication as the required posture
for non-local exposure**.

Policy:

- **Default-safe local mode**: direct serve remains acceptable only on loopback
  (`127.0.0.1`) for local development.
- **Remote mode**: any non-loopback exposure requires authenticated gateway,
  TLS, and explicit authorization policy for control and streaming endpoints.
- **No unauthenticated direct internet exposure** of `anima serve`.
- **Auditability**: authenticated principal identity must be logged with access
  to spawn/interact/collect/logs/stream operations.

## 8. Authorization Baseline

Required baseline authorization checks at gateway policy level:

- `spawn`, `kill`, `interact`, `collect`: allow only trusted orchestrator roles.
- `status`, `logs`, `/stream`: require read/observe roles and tenant scoping.
- Deny cross-tenant agent access by default (agent_id namespace isolation).

This decision sets minimum policy intent; concrete policy syntax is deployment
specific (e.g., gateway policy language).

## 9. Rollout Plan

1. **Phase 5A (immediate hardening)**
   - Document required deployment topology: gateway in front of serve.
   - Keep serve bound to loopback by default.
   - Add operator guidance for TLS, authn, authz, and rate limits.

2. **Phase 5B (operational enforcement)**
   - Add startup warnings when serve binds non-loopback without explicit
     hardening flags/documented deployment mode.
   - Add structured audit fields for principal and source metadata.

3. **Phase 5C (policy validation)**
   - Add integration checks for unauthorized/authorized access to tool and
     stream endpoints through gateway.

## 10. Relationship to API Unification Outcomes

This security decision is intentionally API-shape preserving:

- It does not change MCP tool names, payload schemas, or `/stream` event schema.
- It assumes API unification outcomes keep the existing serve-mode logical
  operations (`spawn`, `status`, `interact`, `collect`, control, logs, stream)
  stable while harmonizing transport and client ergonomics.
- If unification introduces new endpoint paths or protocol wrappers, the same
  posture applies: enforce identity/authz at the exposure boundary, keep
  localhost direct mode only for local development, and preserve audit identity.

## 11. Acceptance Criteria for This Decision

- Threat model identifies assets, adversaries, and primary risks for serve exposure.
- Trust boundaries are explicit between network, serve control plane, runtime, and node.
- Auth requirements and options are documented with trade-offs.
- Recommended posture is explicit for local vs remote exposure.
- Rollout plan defines immediate and phased hardening actions.
- Relationship to API unification outcomes is explicit and non-breaking.
