Things we say cannot happen.
Each line below is a claim, and each names the test that holds it up. The list is generated from the suite rather than written by hand, and the generator's own test fails our build if this page stops matching what passes. Rename one of these tests and the build objects.
// Invariant: a caller // cannot escalate… func TestBodyActor…go/ast reads the annotationthe claim, in words TestBodyActor… · file:lineA page of guarantees maintained by hand becomes a page of former guarantees, and nothing tells you when it happened. This one is regenerated from the suite, and a build step compares the two, so the page cannot describe a guarantee the code stopped making.
Authority cannot be self-asserted
a key bound to an agent cannot author a domain, export or delete the account, or choose what it is for, even when it holds the admin role.
someone tries use an admin key bound to an agent to rewrite the contract it is governed by, download every receipt, or delete the accountwhat happens these act for the account's people and require the owner's or an admin's session or a key not bound to an agenthandlers TestAgentKeyCannotActForTheAccount apps/api/internal/handlers/agent_key_account_test.go:18a key bound to an agent never holds the tenant_owner or admin role.
someone tries mint an agent's key with admin, or grant admin to it later, so domain permissions bound to admin reach the agentwhat happens minting or granting an account role onto an agent's key is refused, and a stored one resolves without itauth TestAgentKeyCannotHoldAccountRoles apps/api/internal/auth/agent_key_test.go:41an agent's own key cannot issue, share or answer for a Card, even when it holds the admin role.
someone tries mint an admin-role key bound to the agent, then issue itself a Card, add itself to another agent's Card, or approve its own held actionwhat happens managing Cards and answering for them require the owner's or an admin's own session or key, never one bound to an agenthandlers TestAgentKeyCannotManageCards apps/api/internal/handlers/shared_card_test.go:128a key bound to an agent cannot mint, grant or revoke keys, even when it holds the admin role.
someone tries mint an admin key bound to an agent, then use it to mint an unbound admin key and act as the account's ownerwhat happens key management requires the owner's or an admin's session or a key not bound to an agentauth TestAgentKeyCannotManageKeys apps/api/internal/auth/agent_key_test.go:16a key bound to an agent reads only the Cards that agent holds, alone or shared; another agent's Card is not listed and its statement is not found, even by its id (#1034). An agent's gateway key does not reach these routes at all.
someone tries agent A's key lists the account's Cards, or asks for agent B's Card statement by idwhat happens gateway keys stop at the gateway route list; other agent keys see only Cards their agent holdshandlers TestAgentKeyReadsOnlyCardsItsAgentHolds apps/api/internal/handlers/mandates_agent_isolation_test.go:112reading its Card gives an agent's key no way to change one.
someone tries an agent key that can read its Card tries to issue or revoke onewhat happens issuing and revoking stay gated on the management roleshandlers TestAgentKeyStillCannotIssueOrRevoke apps/api/internal/handlers/mandates_agent_card_test.go:143no key bound to an agent, and no runtime key, reads held work: not the list of card exceptions and not one by id, whoever's agent it belongs to or whichever Card it breached, shared or not. Held work carries the call's parameters and the Card's limits (#1036).
someone tries an agent's gateway or runtime key lists card exceptions, or reads another agent's held call by idwhat happens reading held work needs the account roles or a person's membership; keys bound to an agent never hold eitherhandlers TestAgentKeysCannotReadHeldWork apps/api/internal/handlers/mandate_exceptions_isolation_test.go:24no key bound to an agent, and no runtime key, watches the account's live decisions: it cannot subscribe to the event stream, so it never receives another agent's decision (#1036).
someone tries agent A's runtime or gateway key opens GET /v1/me/stream and waits for agent B's decisionswhat happens the stream is the account's view; it needs the account roles or a person's membershiphandlers TestAgentKeysCannotWatchTheDecisionStream apps/api/internal/handlers/stream_isolation_test.go:67through the real router, agent A's key reads only Cards agent A holds: not agent B's, by list or by id; a Card they share is visible to both. People and account keys read every Card (#1037, #1036).
someone tries agent A's runtime key lists Cards or reads agent B's Card statement by idwhat happens the Card list and statement are scoped to the key's agent; unbound runtime keys do not reach themmain TestAgentKeysSeeOnlyTheirOwnCardsThroughTheRouter apps/api/cmd/api/runtime_key_boundary_test.go:251A caller cannot escalate its own authority by decorating the actor it submits. Authority is resolved from policy-owned membership keyed by actor id; the roles on the request body carry no authorization power.
someone tries Submit an approval request whose body carries actor.roles = ["admin"]what happens Roles are resolved from policy for that actor id. The roles in the payload are descriptive metadata with no authorization powerhandlers TestApprovalRequest_BodyActorCannotEscalate apps/api/internal/handlers/tenant_runtime_approvals_test.go:299an agent's own key cannot grant or deny an approval, even one it may review by role or by grant.
someone tries request an approval with an agent's key, then grant it with the same key, which holds the reviewer permissionwhat happens a key bound to an agent never reviews; a person on the account answers the approvalhandlers TestApprovalReview_AgentKeyCannotReview apps/api/internal/handlers/tenant_runtime_approvals_test.go:695a key cannot grant or deny an approval it asked for, even when it holds the reviewer permission.
someone tries ask for an approval with a key that may also review it, naming another actor as the requester, then grant it with the same keywhat happens the key that asked is recorded with the approval and refused its review; another reviewer answers ithandlers TestApprovalReview_KeyCannotReviewWhatItAskedFor apps/api/internal/handlers/tenant_runtime_approvals_test.go:736approve once authorizes exactly one action, the one the owner saw, and does not raise the Card.
someone tries after the owner approves one €1,500 refund once, reuse the approval for a different amount, or send the same proposal again hoping for a second authorizationwhat happens the approval binds to the request's fingerprint and is consumed once; an identical retry replays the same authorization, a changed one is refusedmandate TestApproveOnce apps/api/internal/mandate/exception_test.go:173the agent's Card read answers only a key bound to an agent; a person or an unbound key has no agent whose Card it could show.
someone tries call GET /v1/me/card with a key that is not bound to an agentwhat happens the handler requires the identity's agenthandlers TestCardReadNeedsAnAgentKey apps/api/internal/handlers/mandates_agent_card_test.go:130a subject cannot exceed its cumulative limit, however many individually-permitted actions it proposes. Per-action ceilings bound one mistake; this bounds the day.
someone tries propose a further €600 refund after €4,600 has already been refunded today, each one individually under the per-action ceilingwhat happens the draw is added to the window's running total before the decision, so the 51st compliant action is refused when the 50 before it exhausted the limitmandate TestCumulativeLimitRefusesTheActionThatCrossesIt apps/api/internal/mandate/mandate_test.go:52an API key cannot approve a device sign-in, so an agent's key cannot turn itself into an owner session.
someone tries start a CLI sign-in, approve it with an agent's gateway key, and use the developer session it mints, which acts as the account's ownerwhat happens approving a device sign-in requires a signed-in person; an API key gets 403 and no session is mintedhandlers TestDeviceAuth_APIKeyCannotApprove apps/api/internal/handlers/device_auth_test.go:323A caller cannot grant itself a permission by putting a role on the actor in the request body. The execute gate resolves roles from policy, never from the payload.
someone tries POST an action with actor.roles = ["approver"] in the request bodywhat happens The execute gate reads roles from policy, never from the payload, and refusesmain TestExecuteGate_BodyRolesCannotEscalate apps/api/cmd/api/execute_role_gate_test.go:160an expired or revoked mandate never widens authority. It is reported as expired rather than falling through to "no mandate applies", which would turn an expiry into a grant.
someone tries let a mandate lapse, then propose the action it used to bound, hoping the check finds no active mandate and waves it throughwhat happens a lapsed mandate that covers the action is reported as expired, so the decide path refuses instead of treating the subject as unboundedmandate TestExpiredMandateDoesNotFallThroughToUnbounded apps/api/internal/mandate/mandate_test.go:125a gateway key is always bound to an agent. Neither creating a key nor adding a role to one yields a gateway_agent key without an agent.
someone tries mint a gateway_agent key with no agent_id, or add gateway_agent to an unbound keywhat happens key creation and role grants require an agent binding for gateway_agentauth TestGatewayKeyMustBeBoundToAnAgent apps/api/internal/auth/agent_key_test.go:171Work held for a Card's owner is refused once its hold expires unanswered, and stays refused.
someone tries let a €1,500 refund held for the owner sit past its hold expiry, then retry it and have the owner approve it latewhat happens every retry is refused as owner_expired, the late approval is refused, and nothing is drawnmandate TestHeldWorkExpires apps/api/internal/mandate/hold_expiry_test.go:19A runtime key cannot manage keys. Credentials issued for calling the decision API cannot mint, rotate, or revoke other credentials.
someone tries Use a runtime key, the credential agents call the decision API with, to mint a second keywhat happens Key management requires a management identity. The runtime key is refusedauth TestKeysHandler_RuntimeKeyCannotManage apps/api/internal/auth/keys_handler_test.go:402a mandate that sums a parameter an action does not declare as numeric is refused when it is issued, not discovered at runtime.
someone tries issue a mandate capping sum(reason), where reason is a string, so the limit silently sums nothing and never bindswhat happens issue-time validation reads the action's declared parameter types and rejects the mandatemandate TestMandateSummingANonNumericParameterIsRefusedAtIssue apps/api/internal/mandate/mandate_test.go:263an action outside a Card set to come home is held for the Card's owner and authorizes nothing until the owner answers.
someone tries propose a €1,500 refund against a Card allowing €500 each whose work comes home, and retry it until it goes throughwhat happens it is held as one owner exception and every retry returns owner_required with the same handle; nothing is drawnmandate TestOutsideTheCardComesHome apps/api/internal/mandate/exception_test.go:85an agent's gateway key pasted into a client reaches the same routes as an OAuth token for that agent, and no others: not the account's Cards, held work, event stream, agents or export (#1034).
someone tries use an agent's pasted gateway key to read the rest of the account through GET /v1/me/* routeswhat happens the middleware applies the gateway route list to any agent-bound gateway_agent key, not only to OAuth tokensauth TestPastedGatewayKeyReachesOnlyGatewayRoutes apps/api/internal/auth/oauth_test.go:85one action cannot carry more than the per-action limit, however much the Card's total has left.
someone tries propose a single €1,500 refund against a Card allowing €500 each and €5,000 a day, with nothing spent yetwhat happens the per-action limit is checked before the totals and refuses with its own outcomemandate TestPerActionLimit apps/api/internal/mandate/per_action_test.go:40revocation cannot be undone by re-issuing the same mandate id. Authority that was withdrawn stays withdrawn until a new mandate is issued under a new id.
someone tries revoke a mandate, then POST the original definition again with the same id to restore itwhat happens revoked_at is never read from a request body and is excluded from the issue upsert, so a re-issue leaves the revocation standinghandlers TestReIssuingDoesNotUnrevoke apps/api/internal/handlers/mandates_test.go:123a runtime credential cannot issue or revoke a mandate. A key that could grant itself authority would make every limit advisory.
someone tries use the agent's own decide credential to POST a mandate granting itself a larger limitwhat happens issuing is gated on the management roles, the same separation that stops a runtime key minting sibling keyshandlers TestRuntimeKeyCannotIssueItsOwnMandate apps/api/internal/handlers/mandates_test.go:65a runtime key (an agent's key, or any key without the account roles) cannot read the account's activity, settings or people's things, nor change them: the decision stream, evidence, receipts, proof packs, usage, alert targets, billing budget, notification preferences, support tickets, the key list (#1036).
someone tries an agent's runtime key reads account-wide activity or changes account settings through GET/PUT/POST /v1/me/* routes that only check the tenantwhat happens the route policy lets a runtime key reach only RuntimeKeyRules; every other route, including ones added later, is refusedmain TestRuntimeKeysReachOnlyRuntimeRoutes apps/api/cmd/api/runtime_key_boundary_test.go:120where several mandates cover one action, the tightest binds. Issuing an additional mandate can only narrow authority.
someone tries hold a generous domain-wide mandate and issue a second, narrower one, expecting the generous one to still permit the actionwhat happens mandates are conjunctive, so every covering mandate must have room and the tighter limit decidesmandate TestTighterMandateBindsWhenSeveralCover apps/api/internal/mandate/mandate_test.go:169an approval not yet used stops authorizing when its Card is revoked, moved to another holder, or expires.
someone tries have the owner approve an action once, then revoke or move the card, and redeem the approval anywaywhat happens revocation and moves invalidate open exceptions under the card's lock, and redemption rechecks the card under the same lockmandate TestUnusedApprovalIsWithdrawn apps/api/internal/mandate/exception_test.go:275
One tenant cannot reach another
One tenant's API keys are never visible to another. Key listing is scoped at the storage boundary, not filtered after the fact.
someone tries Authenticate as tenant A and list API keys, hoping tenant B's appearwhat happens Listing is scoped at the storage boundary, so tenant B's keys are never in the result to be filtered outauth TestKeysHandler_Tenants_Are_Isolated apps/api/internal/auth/keys_handler_test.go:244Two tenants recording byte-identical facts commit to different Merkle leaves. A public anchor cannot be used as a confirmation oracle for a guessed record without also guessing that tenant's salt.
someone tries Guess a record, hash it, and look for that leaf in the public anchor to confirm the guesswhat happens Each tenant's leaves are salted with a per-tenant secret, so the guess produces a different hash and confirms nothinganchor TestLeafHashDifferentSaltsCrossTenantIsolation apps/api/internal/anchor/merkle_salt_test.go:54
The record cannot quietly disagree with what happened
A receipt altered after signing fails verification against the anchored root. Tamper-evidence is checked, not asserted.
someone tries Change a field in a signed receipt and present it as genuinewhat happens The digest is recomputed from the receipt's own content, so the signature no longer recovers the declared signerreceipt TestAnchorAttester_TamperedReceiptFailsOnchainVerify apps/api/internal/receipt/anchor_attester_test.go:143A trace containing more than one execution is refused rather than turned into a receipt. A receipt describes exactly one executed action or it is not issued.
someone tries Feed the receipt builder a trace containing two executed actionswhat happens The build is refused. A receipt describes exactly one executed action or it is not issuedreceipt TestBuild_RejectsTraceWithMultipleExecutions apps/api/internal/receipt/build_test.go:313The bytes a receipt's signature commits to are pinned to a fixed encoding. Reordering a field would otherwise change every future hash while leaving past receipts verifiable, which is indistinguishable from tampering.
someone tries Reorder a field in the chain struct, changing what every future receipt hashes towhat happens The encoding is pinned to fixed bytes, so the build fails before a single receipt is signed against the new shapereceipt TestCausalChainCanonicalEncodingIsPinned apps/api/internal/receipt/canonical_test.go:39
What the gate never saw is reported, not assumed absent
A tool that ran more often than the gate was consulted is reported as undecided calls. Bypass is measured against recorded decisions rather than assumed absent.
someone tries Call a governed tool directly, bypassing the gate, and assume nobody can tellwhat happens Observed call counts are compared against recorded decisions, and the difference is reported as undecided callshandlers TestCoverage_ReportsCallsThatNeverReachedTheGate apps/api/internal/handlers/coverage_test.go:185
What happens when something breaks
When a source behind the evidence object is unavailable, that section is marked unavailable and the rest still answers. Evidence degrades section by section rather than failing whole or, worse, reporting an empty section as a clean one.
someone tries One source behind the evidence object is unavailable when a report is composedwhat happens That section is marked unavailable and the rest still answers, rather than an empty section reading as a clean oneevidence TestCompose_PostureReadError_Degrades apps/api/internal/evidence/composer_test.go:389When two first sign-ins for the same subject race, exactly one tenant survives and the loser cleans up the one it provisioned. No orphan tenant is left behind.
someone tries Two first sign-ins for the same subject arrive at once, each provisioning a tenantwhat happens Exactly one survives and the loser deletes the tenant it created, leaving no orphantenant TestEnsureForSubject_LoserOfRaceCleansUpItsTenant apps/api/internal/tenant/ensure_test.go:270When the usage limiter cannot establish its own state, the request is allowed. Blocking a customer's production traffic because our meter was uncertain is the worse failure, and this default is deliberately the opposite of the governance one.
someone tries The usage limiter cannot reach its own store while a customer is mid-requestwhat happens The request is allowed. Blocking production traffic because our meter was uncertain is the worse failureusage TestLimiter_FlushFailureIsAllowedWhenUncertain apps/api/internal/usage/limiter_test.go:321when current usage cannot be established, the proposal is refused. A mandate is the authority itself, not a meter, so allowing when uncertain means acting with authority nobody could confirm.
someone tries make the draw ledger unreadable at the moment a proposal arrives, hoping the check degrades to allowwhat happens Evaluate returns ErrUsageUnavailable and the caller must refuse, the opposite default to the billing limiter beside it, which allows when uncertain on purposemandate TestMandateFailsClosedUnlikeTheUsageLimiter apps/api/internal/mandate/mandate_test.go:107If the audit write fails, the mutation does not happen. A suspended tenant with no audit record is not an outcome this system can produce.
someone tries Suspend a tenant at the moment the audit write failswhat happens The mutation rolls back. A suspended tenant with no audit record is not a state this system can reachhandlers TestOps_Suspend_AuditFailureLeavesTenantUnchanged apps/api/internal/handlers/ops_audit_failure_test.go:55
What this page is not.
The file and line are an index, not evidence. This repository is private, so you cannot open any of them, and a citation you cannot check is not proof of anything. What it is good for is picking: name a line and we open that file in front of you on a call and run it. That is a worse claim than a badge and a more useful one.
These cover apps/api only, not every repository we publish, and they are the guarantees we chose to state, a passing test proves the property it tests and nothing else. Nothing here claims the set is complete, and a system with no failing tests is not a system with no flaws. We know that unusually well: three of four attacks against our own approval boundary worked, and the conformance tests passed the entire time it was broken, because they tested the compile-time property rather than the security one. Several of the tests above exist because of that.
These are also what we write against your claims when we put an action on rails: the attacks stay in your build, failing if the guarantee regresses. Showing you ours first is the point.