---
title: How the agent trust model works
description: The platform treats LLM agents as first-class but untrusted users — a ladder of token scopes, default-deny grants, redaction, and anti-enumeration by design.
locale: en
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/how-it-works/agent-trust-model/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

**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.

## Layer 1 — the token ladder

Three access tiers, in increasing power:

| Tier | Can read | Can write |
| --- | --- | --- |
| Read-only scoped | An allowlist of GET surfaces | Nothing |
| **Agent** | The platform, with secrets always redacted | Only its granted contract pool |
| Owner | Everything | Everything |

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

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.

```mermaid
flowchart LR
    T[Agent token] --> L1[Layer 1<br/>route allowlist]
    L1 --> L2[Layer 2<br/>object-level grant check]
    L2 --> W[Write executes]
    L1 -- route not agent-writable --> R1[403]
    L2 -- contract not in pool --> R2[403 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

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.

## Layer 4 — untrusted input surfaces

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.

## Trade-offs

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](../../guides/authentication/#-the-token-replaces-pool-gotcha).

## See it in two minutes

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