Veefore docs

ADR 0002: Gateway architecture

Two separate planes, built from one image, with the credential broker placed after everything that can refuse.

#Context

Agents and people need very different things from Veefore.

People manage: create agents, author policies, issue delegations, register credentials, read audit. Low volume, bursty, highly privileged, and the surface is large.

Agents ask: may I do this. High volume, latency sensitive, and the only thing they ever need is a decision.

Serving both from one process means the surface agents can reach includes POST /v1/policies/{id}/activate.

#Decision

Two request-serving processes.

Serves Reached by
Control plane /v1/* People, console, CLI, CI
Gateway /gateway/v1/* and /.well-known/veefore-platform-key Agents only

Plus a worker for queues and rollups. All three are built from one container image with three entry points, because they share almost all their code.

The gateway accepts no human credentials. It authenticates a signed Ed25519 assertion and nothing else.

Both planes are stateless: session state and the job queue live in PostgreSQL, so horizontal scaling needs no coordination.

#The pipeline order

The twelve stages run in a fixed order, and one position in it is a security property rather than a performance choice:

text
 1–9   everything that can refuse
10     CREDENTIAL   ← first side effect outside Veefore
11     EXECUTION
12     RESULT

#Alternatives

One process serving both. Simpler to deploy, and it means the surface agents can reach includes policy activation and credential registration. Every mitigation for that is a configuration — a reverse proxy rule, a path filter — and configurations drift.

A sidecar per agent. Lower latency, and the enforcement point becomes something running in the agent's own trust domain. An agent that can stop its own sidecar can stop being enforced. Also multiplies the number of places a credential is unsealed.

Three separate codebases. Clean separation, and it guarantees the planes drift: a policy change applied in one and not the other, three things to scan and sign, three dependency trees. The shared packages are the bulk of the code anyway.

Broker the credential earlier, in parallel with policy evaluation. Would save a few milliseconds on the allowed path. It would also mean a blocked action had already caused a credential to be issued — so "we blocked it" and "the secret did not go out" would become two different claims with only one of them true. Rejected on that basis alone.

#Consequences

Separate ingresses are mandatory, not advisory. Exposing /v1/* on the ingress agents can reach undoes the entire decision. This has to be stated in the deployment documentation and checked in review, because the manifests cannot enforce it for you.

The planes scale independently, which is the operational benefit. Typical ratio is 3:1 gateway to control plane, because their load profiles are nothing alike.

Each process gets only the secrets it needs. The gateway never issues a human session, so it does not need VEEFORE_SESSION_SECRET. A secret a process does not need is one more place a compromise can read it from.

Policy evaluation must be in-process. The gateway cannot take a network hop to another service in order to decide whether to allow something — that service could be down, and fail-closed would then turn every evaluation-service blip into a refusal of all traffic. This constraint drives ADR 0003.

Latency is bounded by the stage order, not optimised against it. The full pipeline excluding execution runs in 20–50 ms. Could be faster by caching a decision; caching a decision is what makes revocation take effect "eventually" rather than immediately.

Two readiness surfaces to monitor. Both planes expose /health/ready and both genuinely check the database. A plane that is live and not ready must leave the load balancer's rotation rather than serving errors — which once silently failed, because the embedded driver booted a fresh empty database after close and left readiness green with nothing behind it.

Identity, authority, policy and enforcement for autonomous AI agents.