Skip to content

How the agent trust model works

The problem: this platform is operated by LLM agents — they read state, file defects, launch runs. An agent is a legitimate user and an untrusted one at the same time: it hallucinates, it retries, it can be prompt-injected by content it reads. Classic RBAC assumes a user who mostly behaves; this platform assumes one that sometimes won’t.

Three access tiers, in increasing power:

TierCan readCan write
Read-only scopedAn allowlist of GET surfacesNothing
AgentThe platform, with secrets always redactedOnly its granted contract pool
OwnerEverythingEverything

The agent tier is the interesting one: reads are broad (an agent that cannot see cannot reason), but every response passes recursive secret redaction — credentials never reach an agent even when it reads the config that contains them.

Layer 2 — default-deny grants with two enforcement layers

Section titled “Layer 2 — default-deny grants with two enforcement layers”

Write access lives in one table: one row per (agent, contract) with an explicit capability list. No row = no access; the sensitive publish capability is withheld by default even inside a granted pool. Enforcement is two-layered — a coarse route allowlist (only a small set of write routes accept agent tokens at all), then a per-object check inside each handler that the specific target contract is in the caller’s pool with the specific capability. The second layer is what stops the classic BOLA failure: a valid token quietly writing to object it was never granted.

route not agent-writablecontract not in poolAgent tokenLayer 1route allowlistLayer 2object-level grant checkWrite executes403403 naming the gap

MCP calls bypass none of this: the MCP mount requires a valid token for every call, and each tool re-runs the same capability checks in its body.

Layer 3 — discovery for the weakest agent

Section titled “Layer 3 — discovery for the weakest agent”

The platform assumes the least capable client, not the most: an unauthenticated onboarding page, a curated llms.txt, an MCP start_here tool returning an ordered plan, and — the hard-won lesson — meaning lives in payload values, not schemas, because many agents never introspect tool descriptions. Everything an agent must know to behave correctly is in the data it actually reads.

Where agents submit content, the platform treats them as a hostile stream: defect reports pass a gate chain (rate limit → dedup fingerprint → actionability check), and the public intake answers a bare 202 — no ticket id, no verdict — so the endpoint cannot be used to enumerate the board. A report without reproduction steps or evidence is quarantined rather than trusted.

Redaction-by-default occasionally hides something an agent legitimately needs — the resolution is an explicit grant, never a bypass. The bare-202 intake means a well-behaved agent can’t confirm its report landed; the answer is the separate authenticated read surface (the board tools), not a leakier intake. And re-minting a token replaces the whole grant pool — a sharp edge documented prominently in Authentication.

Call my_capabilities over MCP — the response is your exact trust envelope: readable domains, writable contracts, capabilities per contract.

Specs: SPEC-075 (read-only tier), SPEC-084 (agent tier + pool), SPEC-085 (read-all + redaction), SPEC-089 (discovery chain), SPEC-004 (untrusted intake), SPEC-112 (board access model).