96 guarantees · generated from the test suite

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.

A 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 Card's amounts are counted in its own currency only.

    someone tries refund $300 on a USD payment against a Card limited to 50 EUR
    what happens KIFF reads the payment's currency first; a call in another currency, or one it can't check, is refused and nothing is sent
    gateway TestACallInAnotherCurrencyIsNotSent apps/gateway/internal/gateway/unit_test.go:53
  • once KIFF accepts a phone's signature for another service, that service saves the account's contract and permit targets with the phone's session, each once, within a minute, and nothing else (kiff/tafs#206).

    someone tries a phone's session writes the contract with no grant, reuses a grant, uses it on another route, after it ended, or with another session
    what happens 403 without a live grant of this session, 409 for a second use, and no route but the two writes
    handlers TestADeviceGrantAdmitsTheTwoWritesOnce apps/api/internal/handlers/device_signature_test.go:96
  • the owner's halt binds in observe mode too. Observe makes KIFF's decisions advisory while an account watches what enforcing would do; a halt is the owner stopping an agent, not a decision to watch.

    someone tries an agent of an account in observe mode keeps acting after the owner halts it, because the refusal comes back advisory
    what happens the halted refusal is labelled observe and is not advisory
    handlers TestAHaltBindsInObserveMode apps/api/internal/handlers/halt_refusal_test.go:85
  • while the owner has halted an agent, or its whole account, KIFF decides none of its calls: a new call, a retry of one decided before and a held call asked again are all refused (halted), so nothing is sent and no permit is issued. Once resumed, only new calls go through: what was asked before the halt stays refused.

    someone tries an agent keeps calling after the owner halts it, retries an operation allowed before the halt, or waits out the halt to collect a held call the owner had approved
    what happens every decision for a halted agent or account is blocked with halted; after a resume, an operation first decided before the halt is blocked with halted too
    handlers TestAHaltRefusesEveryCallAndNothingFromBeforeComesBack apps/api/internal/handlers/halt_refusal_test.go:23
  • a hard refusal has nothing to approve. A call past a Card set to refuse is refused with no held call behind it, so the owner's list shows nothing to answer, and approving it by its call's id finds nothing.

    someone tries a call past a Card set to refuse, then an approval of that refusal, by the call's id or by guessing a held call's
    what happens no held call is made, the owner's list is empty, and approve-once answers 404
    handlers TestAHardRefusalHasNothingToApprove apps/api/internal/handlers/gate_c_test.go:21
  • a phone's approval key is replaced only when its own person approves the new key in their browser, after the new key proved itself.

    someone tries code holding the phone's session and device key (no prompt) swaps in an approval key of its own, or another person approves the swap
    what happens the device key alone only asks; the new key must sign the request; only the session's person, in the browser, approves; nothing changes before that
    handlers TestARelinkReplacesTheApprovalKeyOnlyWhenItsPersonApproves apps/api/internal/handlers/device_relink_test.go:148
  • a person's run grant goes with each call KIFF decides, and a grant KIFF refuses sends nothing. The gateway never decides on the grant itself: only KIFF can say who it is for.

    someone tries a run whose person may no longer use the agent, or with a forged grant, issues a refund
    what happens KIFF refuses the call on the grant and the tool receives nothing
    gateway TestARunGrantGoesWithEachDecision apps/gateway/internal/gateway/grant_test.go:11
  • a trial (agent~trial) reads and halts as its agent, so planque, which asks KIFF about a trial permit's subject, refuses a trial's calls under its agent's halt, and after a resume a trial permit issued before it.

    someone tries a trial permit issued just before the owner halts the agent is sent through planque within its lifetime, or after the resume
    what happens the trial's halt is its agent's, with the same halted_at
    handlers TestATrialReadsAsItsAgentsHalt apps/api/internal/handlers/halts_test.go:239
  • a write whose vendor answer doesn't match what KIFF decided is flagged and its operation paused.

    someone tries a vendor refunds 700 where the Card decided 500, or a read-back that can't be made
    what happens the call is recorded as sent and flagged; the operation is paused and nothing more is sent through it until the owner resumes it
    gateway TestAVerifyReadThatDiffersPausesTheOperation apps/gateway/internal/gateway/verify_test.go:45
  • a write that doesn't carry its amount is limited by the amount its resource has, as KIFF reads it.

    someone tries answer a 9,000 EUR dispute through a Card that holds anything over 1,000, by leaving the amount out or naming a small one
    what happens KIFF reads the dispute's amount itself and decides on it; an amount the agent sends is refused, and so is a call whose amount can't be read
    gateway TestAWriteIsLimitedByTheAmountItsResourceHas apps/gateway/internal/gateway/amount_test.go:46
  • a revision draft changes an agent's Cards only when an owner confirms it, all of them or none, keeping each revised Card's usage so its totals don't start again, and it gives no key.

    someone tries an agent drafts a revision of its own Card with a higher limit, hoping it applies before an owner confirms, resets the day's totals, or yields a second key
    what happens nothing changes until an owner confirms; then the Card is revised under the same id with what it used kept, and no claim secret or key comes out of it
    handlers TestAgentDraftRevisesTheAgentsCards apps/api/internal/handlers/agent_drafts_revision_test.go:68
  • 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 account
    what 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 agent
    handlers TestAgentKeyCannotActForTheAccount apps/api/internal/handlers/agent_key_account_test.go:18
  • a 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 agent
    what happens minting or granting an account role onto an agent's key is refused, and a stored one resolves without it
    auth TestAgentKeyCannotHoldAccountRoles apps/api/internal/auth/agent_key_test.go:41
  • an 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 action
    what happens managing Cards and answering for them require the owner's or an admin's own session or key, never one bound to an agent
    handlers TestAgentKeyCannotManageCards apps/api/internal/handlers/shared_card_test.go:128
  • a 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 owner
    what happens key management requires the owner's or an admin's session or a key not bound to an agent
    auth TestAgentKeyCannotManageKeys apps/api/internal/auth/agent_key_test.go:16
  • a 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 id
    what happens gateway keys stop at the gateway route list; other agent keys see only Cards their agent holds
    handlers TestAgentKeyReadsOnlyCardsItsAgentHolds apps/api/internal/handlers/mandates_agent_isolation_test.go:112
  • reading 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 one
    what happens issuing and revoking stay gated on the management roles
    handlers TestAgentKeyStillCannotIssueOrRevoke apps/api/internal/handlers/mandates_agent_card_test.go:239
  • no 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 id
    what happens reading held work needs the account roles or a person's membership; keys bound to an agent never hold either
    handlers TestAgentKeysCannotReadHeldWork apps/api/internal/handlers/mandate_exceptions_isolation_test.go:24
  • no 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 decisions
    what happens the stream is the account's view; it needs the account roles or a person's membership
    handlers TestAgentKeysCannotWatchTheDecisionStream apps/api/internal/handlers/stream_isolation_test.go:67
  • through 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 id
    what happens the Card list and statement are scoped to the key's agent; unbound runtime keys do not reach them
    main TestAgentKeysSeeOnlyTheirOwnCardsThroughTheRouter apps/api/cmd/api/runtime_key_boundary_test.go:412
  • a tool that checks KIFF's execution permit never receives an allowed call without one, and that call is reported as not sent.

    someone tries get an allowed decision for a permit-checking tool with no permit attached
    what happens the gateway does not forward it and records that it was never sent
    gateway TestAllowedWithoutPermitIsNotSent apps/gateway/internal/gateway/gateway_test.go:1052
  • another KIFF service takes a person's act signed on their phone only when KIFF confirms that phone signed that exact request, once, and the person may connect tools (kiff/tafs#206: connecting the account's control server through the gateway).

    someone tries a phone's session replays a signed request, changes its body, or asks without the right to connect tools; another key asks
    what happens a replay is 409, another body or path is 403, a role without tools.connect is 403, and only a phone's session may ask
    handlers TestAnotherServiceAsksWhetherThePhoneSignedIt apps/api/internal/handlers/device_signature_test.go:31
  • A 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 power
    handlers TestApprovalRequest_BodyActorCannotEscalate apps/api/internal/handlers/tenant_runtime_approvals_test.go:299
  • an 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 permission
    what happens a key bound to an agent never reviews; a person on the account answers the approval
    handlers TestApprovalReview_AgentKeyCannotReview apps/api/internal/handlers/tenant_runtime_approvals_test.go:695
  • a 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 key
    what happens the key that asked is recorded with the approval and refused its review; another reviewer answers it
    handlers TestApprovalReview_KeyCannotReviewWhatItAskedFor apps/api/internal/handlers/tenant_runtime_approvals_test.go:736
  • approve once authorizes exactly one action, the one the owner saw, and does not raise the Card. That action still counts in full toward the Card's totals.

    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 authorization
    what happens the approval binds to the request's fingerprint and is consumed once; an identical retry replays the same authorization, a changed one is refused, and the full amount is drawn from the Card
    mandate TestApproveOnce apps/api/internal/mandate/exception_test.go:174
  • the 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 agent
    what happens the handler requires the identity's agent
    handlers TestCardReadNeedsAnAgentKey apps/api/internal/handlers/mandates_agent_card_test.go:226
  • a 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 ceiling
    what 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 limit
    mandate TestCumulativeLimitRefusesTheActionThatCrossesIt apps/api/internal/mandate/mandate_test.go:52
  • a call made under a trial its owner started is decided on the trial's Cards alone, drawing on them, and recorded under the trial; a call without it never sees them. Once the trial ends, its calls, held ones included, are refused.

    someone tries an agent names a trial to get the version's higher limit for its live calls, names another agent's trial, or keeps a held trial call to be approved after the trial ended
    what happens only the key of the trial's own agent can name it; live calls get the live Card; after the end, the trial's calls are refused with trial_ended
    handlers TestDecideATrialsCallOnItsTrialCards apps/api/internal/handlers/proposals_trial_test.go:123
  • an 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 owner
    what happens approving a device sign-in requires a signed-in person; an API key gets 403 and no session is minted
    handlers TestDeviceAuth_APIKeyCannotApprove apps/api/internal/handlers/device_auth_test.go:330
  • A 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 body
    what happens The execute gate reads roles from policy, never from the payload, and refuses
    main TestExecuteGate_BodyRolesCannotEscalate apps/api/cmd/api/execute_role_gate_test.go:160
  • An API key past its expiry authenticates nowhere: every route the API registers answers 401 to it, an account key's and an agent's alike, as it does to a revoked key.

    someone tries A leaked key that was meant to stop working keeps reading or acting after its expiry date
    what happens authentication checks the key's expires_at against the clock before any route or handler runs
    main TestExpiredKeysAuthenticateNowhere apps/api/cmd/api/runtime_key_boundary_test.go:353
  • an 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 through
    what happens a lapsed mandate that covers the action is reported as expired, so the decide path refuses instead of treating the subject as unbounded
    mandate TestExpiredMandateDoesNotFallThroughToUnbounded apps/api/internal/mandate/mandate_test.go:125
  • an external approver's answer cannot go past its grant. Over its per-call ceiling, outside its Card, past a total, after its grant is withdrawn or expires, after the Card changes, or for its own call, the answer is refused and the hold stays as it was.

    someone tries have a connected approver service answer a held call outside what its grant covers
    what happens the answer is refused; the call stays held with its deadline unchanged, and nothing is drawn
    mandate TestExternalApproverBoundaries apps/api/internal/mandate/external_approver_test.go:66
  • a tool cannot speak for KIFF: it cannot write the dev.kiff/ result metadata that clients rely on.

    someone tries have a tool return _meta["dev.kiff/call"] claiming its call was approved
    what happens the tool's dev.kiff/ keys are removed from forwarded results, the first time and on replay, and the gateway writes its own call state; the tool's other metadata passes through
    gateway TestForwardedResultCannotSpeakForKIFF apps/gateway/internal/gateway/gateway_test.go:921
  • a 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 key
    what happens key creation and role grants require an agent binding for gateway_agent
    auth TestGatewayKeyMustBeBoundToAnAgent apps/api/internal/auth/agent_key_test.go:174
  • a trial's writes through the gateway get the decisions the same queue of real calls would get from the agent's Cards, each counting the trial's earlier allowed writes, and KIFF records nothing real for them: no draw, no held call, nothing for the owner to answer.

    someone tries an agent key sends trial calls inside and outside its Card, to use up the Card's total or fill the owner's queue without ever calling the tool
    what happens each trial call is answered allowed, held or refused as the same real queue would be, and the Card's draws and held calls stay empty
    handlers TestGatewayTrialDecidesAndRecordsNothing apps/api/internal/handlers/gateway_trial_test.go:128
  • Work 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 late
    what happens every retry is refused as owner_expired, the late approval is refused, and nothing is drawn
    mandate TestHeldWorkExpires apps/api/internal/mandate/hold_expiry_test.go:19
  • A 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 key
    what happens Key management requires a management identity. The runtime key is refused
    auth TestKeysHandler_RuntimeKeyCannotManage apps/api/internal/auth/keys_handler_test.go:447
  • a lifetime total never resets. Calls across days draw on one total, so a daily-looking budget cannot be spent once per day.

    someone tries spend the Card's total, wait for midnight (or 24 hours), spend it again
    what happens the next day's call is refused while the lifetime total is spent
    mandate TestLifetimeTotalNeverResets apps/api/internal/mandate/lifetime_test.go:25
  • reissuing a Card cannot reset its lifetime total, not by moving ValidFrom later and not by switching a daily total to a lifetime one: every draw the Card has made counts.

    someone tries spend most of the room, then reissue the Card with a later ValidFrom (or a new window) to get it back
    what happens the reissued Card still counts the earlier draws
    mandate TestLifetimeTotalSurvivesReissue apps/api/internal/mandate/lifetime_test.go:59
  • a sign-in token issued through one connect link works only at that link's URL.

    someone tries use a token issued through a connect link at the general gateway URL
    what happens the general URL refuses it
    gateway TestLinkURLAcceptsOnlyItsOwnTokens apps/gateway/internal/gateway/oauth_internal_test.go:105
  • a 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 binds
    what happens issue-time validation reads the action's declared parameter types and rejects the mandate
    mandate TestMandateSummingANonNumericParameterIsRefusedAtIssue apps/api/internal/mandate/mandate_test.go:263
  • only Setup's key reads another agent's Card through kiff_card; a taf's key that names another agent is refused, and reads nothing.

    someone tries call kiff_card with agent set to another agent, from a taf's gateway key
    what happens cardResult requires the setup_reader role before naming an agent
    gateway TestOnlySetupNamesAnAgentInKiffCard apps/gateway/internal/gateway/card_test.go:205
  • only Setup's key reads another agent's Card; a taf's own key sees only the Cards it holds, whatever agent it names.

    someone tries call GET /v1/me/card?agent=<another agent> with a gateway agent's key
    what happens the handler requires the setup_reader role to name an agent
    handlers TestOnlySetupReadsAnotherAgentsCard apps/api/internal/handlers/mandates_agent_card_test.go:210
  • an 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 through
    what happens it is held as one owner exception and every retry returns owner_required with the same handle; nothing is drawn
    mandate TestOutsideTheCardComesHome apps/api/internal/mandate/exception_test.go:85
  • an agent's gateway key pasted into a client reaches the same routes as an OAuth token for that agent, and only the two its own runtime needs besides (a person's access to that agent, and resolving their run grant): not the account's Cards, held work, event stream, agents or export.

    someone tries use an agent's pasted gateway key to read the rest of the account through GET /v1/me/* routes
    what happens the middleware applies the gateway route list to any agent-bound gateway_agent key, not only to OAuth tokens
    auth TestPastedGatewayKeyReachesOnlyGatewayRoutes apps/api/internal/auth/oauth_test.go:91
  • reading the list of pending calls decides, draws and sends nothing, and an agent's key sees only its own calls.

    someone tries read kiff_pending with another agent's key, or read it repeatedly hoping it sends the held call
    what happens the other key sees nothing, and reading never forwards; only the original call collects it, once
    gateway TestPendingListsAHeldCallUntilItIsCollected apps/gateway/internal/gateway/pending_test.go:57
  • one 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 yet
    what happens the per-action limit is checked before the totals and refuses with its own outcome
    mandate TestPerActionLimit apps/api/internal/mandate/per_action_test.go:40
  • revocation 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 it
    what happens revoked_at is never read from a request body and is excluded from the issue upsert, so a re-issue leaves the revocation standing
    handlers TestReIssuingDoesNotUnrevoke apps/api/internal/handlers/mandates_test.go:123
  • A read-only account key (role viewer, bound to no agent) reads the account's activity, held work and stream, and changes nothing: every write route the API registers, including ones added later, refuses it before any handler, and so do reads that need more than reading (the export, the audit log). The same role on an agent's key leaves it that agent's runtime key.

    someone tries A key minted to read the account writes through it (answers a hold, mints a key, changes a Card, halts, approves a device sign-in, leaves the account)
    what happens The route policy lets a read-only key make only GET and HEAD requests that need the read capability; it holds no other capability
    main TestReadOnlyAccountKeyOnlyReads apps/api/cmd/api/runtime_key_boundary_test.go:254
  • a refusal's next step is one the held call's own Card offers, and it stays a refusal: nothing is drawn, the call ends, and the agent can read what the owner asked it to do instead.

    someone tries refuse with a next step the Card does not list, or treat a refusal with a next step as permission to act
    what happens an unlisted step is rejected with ErrNextStepNotOnCard and the hold stays open; a listed one records the refusal, draws nothing and the call stays refused
    mandate TestRejectWithNextStep apps/api/internal/mandate/next_step_test.go:28
  • every spelling of kiff_card is the gateway's own tool. A tool connected under one before the name was reserved is neither listed nor reached.

    someone tries call a connected tool named KIFF_Card that tools/list hides
    what happens CallTool answers every reserved spelling as kiff_card before any invocation is begun
    gateway TestReservedSpellingNeverReachesAConnectedTool apps/gateway/internal/gateway/card_test.go:228
  • a call on a resource outside the Card comes home to its owner, and an approval covers that exact resource only.

    someone tries get inv-9 approved once, then redeem the same proposal id for inv-8, or a new proposal for inv-9
    what happens the approval binds to the resource in the request fingerprint; a new proposal is held again
    mandate TestResourceOutsideComesHomeAndApprovalBindsTheResource apps/api/internal/mandate/resource_scope_test.go:104
  • a Card scoped to named resources authorizes the action only on those resources.

    someone tries an agent holding a refund Card for invoice inv-1 refunds inv-9, or sends no invoice at all
    what happens the call is outside the Card (resource_not_on_card), checked before amounts, never read as "not covered"
    mandate TestResourceScope apps/api/internal/mandate/resource_scope_test.go:43
  • an unscoped Card covering the same action never widens a scoped one. Cards are conjunctive, so the scope binds.

    someone tries hold a scoped Card for inv-1 and a broad refund Card, and refund inv-9
    what happens the scoped Card is breached whichever order the Cards are read in
    mandate TestResourceScopeStacksWithUnscopedCard apps/api/internal/mandate/resource_scope_test.go:82
  • a 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 limit
    what happens issuing is gated on the management roles, the same separation that stops a runtime key minting sibling keys
    handlers TestRuntimeKeyCannotIssueItsOwnMandate apps/api/internal/handlers/mandates_test.go:65
  • a 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 tenant
    what happens the route policy lets a runtime key reach only RuntimeKeyRules; every other route, including ones added later, is refused
    main TestRuntimeKeysReachOnlyRuntimeRoutes apps/api/cmd/api/runtime_key_boundary_test.go:134
  • Setup's key acts on the account's own control server only on a Card of its own (Coach's), and still never on a vendor's tool that writes.

    someone tries Setup calls the control server's tool with no Card, or a vendor's write once the control server is connected
    what happens no Card of Setup's own is refused as not issued; the vendor's write is refused for the role
    handlers TestSetupActsOnTheControlServerOnlyOnItsCard apps/api/internal/handlers/setup_reads_decide_test.go:140
  • Setup's Card for its reads is issued only on the owner's approval of that connection, which KIFF checks itself (the device's signature over planque's approve request, a person who may connect tools, signed within a day), only by the connector key that connected the tools, and only for tools marked read-only. It allows a few reads a day and refuses past them.

    someone tries planque's connector key, or anyone holding one, grants an agent authority the owner never approved: another connection's or another account's approval, an old one, another person's device, a tool that writes, or a tool another key connected
    what happens each is a 403 and no Card is issued
    handlers TestSetupReadsCardNeedsTheOwnersApproval apps/api/internal/handlers/setup_reads_test.go:78
  • Setup's key (setup_reader) reads a read-only tool only on its own read Card, and can't call a tool that writes, whatever Card names it.

    someone tries Setup, which holds no tools, calls a tool that writes, or reads without the owner's approval of its reads
    what happens a write is refused for the role; a read with no Card of Setup's own is refused as not issued
    handlers TestSetupReadsOnlyWhatItsCardAllows apps/api/internal/handlers/setup_reads_decide_test.go:58
  • where 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 action
    what happens mandates are conjunctive, so every covering mandate must have room and the tighter limit decides
    mandate TestTighterMandateBindsWhenSeveralCover apps/api/internal/mandate/mandate_test.go:169
  • a trial its owner started sends its calls (kiff/tafs#173). With KIFF-Trial naming a draft KIFF says is being tried, a call goes the normal path: recorded, decided with the draft named (so KIFF decides it on the trial's own Cards), sent when allowed, held when not, and its result names the draft. KIFF-Trial-Run isn't needed, and is harmless.

    someone tries a version being tried issues one refund inside its trial Card and one outside it
    what happens the one outside is held for the owner and not sent; both are decided with the trial's draft, never as the live version's calls
    gateway TestTrialBeingTriedIsSentOnItsDraft apps/gateway/internal/gateway/trial_test.go:202
  • a version being tried is decided on its own trial Cards, and the live version on the agent's Cards, each with its own counters. Trying it changes nothing on the live Cards, and no call made for the agent sees a trial Card.

    someone tries start a trial of a version with a higher limit, then make the agent's ordinary calls, hoping they get the trial's limit, or the trial's spending counts against (or resets) the live Card
    what happens the agent's calls are decided on its live Card as before; the trial's calls only on the trial Cards, from zero, until they lapse in 30 days
    handlers TestTrialCardsAreTheVersionsAndApartFromTheLive apps/api/internal/handlers/trial_cards_test.go:75
  • a trial of an agent's next version is decided against the Cards as a real queue would be, its own earlier allowed writes counting toward the limits, and draws nothing real, holds nothing and asks no owner.

    someone tries run a trial's refunds over and over, inside and outside the Card, to use up its total or fill the owner's queue
    what happens each trial write gets the decision the same queue of real calls would get, and the Card's total and the owner's queue are unchanged
    mandate TestTrialDecidesAndRecordsNothing apps/api/internal/mandate/trial_test.go:27
  • a trial ends for good: going back, its runtime's sweep, or a new trial revoke its Cards, and only the agent's own key or someone who manages Cards can end it.

    someone tries keep a trial's higher limits after going back, start a second trial to hold two sets of trial Cards, or end another agent's trial with this agent's key
    what happens one trial per agent; an ended trial's Cards are revoked; another agent's key is told there is no such draft
    handlers TestTrialEndsAndRevokesItsCards apps/api/internal/handlers/trial_cards_test.go:155
  • installing a version being tried issues its Cards live and revokes its trial Cards, together, and the trial records that it was installed.

    someone tries install a tried version and keep its trial Cards in force beside the live ones, doubling its room
    what happens the trial Cards are revoked in the same issue as the live revision
    handlers TestTrialInstallEndsIt apps/api/internal/handlers/trial_cards_test.go:243
  • a trial's call is never sent, reads included. A call made with KIFF-Trial is decided against the agent's Cards and answered with that decision; it creates no invocation, records no request, draws nothing and never reaches the tool.

    someone tries run a trial of a new version that issues refunds inside and outside its Card through the gateway
    what happens each refund comes back with KIFF's decision (allowed, held) and "Nothing was sent"; the tool receives no call and nothing is recorded or drawn
    gateway TestTrialWriteIsDecidedAndNeverSent apps/gateway/internal/gateway/trial_test.go:71
  • an 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 anyway
    what happens revocation and moves invalidate open exceptions under the card's lock, and redemption rechecks the card under the same lock
    mandate TestUnusedApprovalIsWithdrawn apps/api/internal/mandate/exception_test.go:287
  • a held or refused call never reaches the tool. A call is forwarded only on an allowed decision: inside the Card, or an approved per-action exception that still fits the Card's totals.

    someone tries ask the gateway for a €5,000 refund on a Card that allows €500 per call
    what happens the €5,000 call is held with the owner's review link and not sent; the tool receives only the €500 call, and only €500 is drawn
    gateway TestWithinCardForwardsOutsideHolds apps/gateway/internal/gateway/gateway_test.go:491

One tenant cannot reach another

  • an account's drafts are its own. Another account's person can't read, confirm or discard one by its id.

    someone tries an owner of another account reads, confirms or discards a draft by its id
    what happens each answers 404, and the draft is unchanged
    handlers TestAnotherAccountCantReachADraft apps/api/internal/handlers/gate_c_test.go:62
  • one account cannot see, test, remove or decrypt another account's tool connections.

    someone tries copy another account's encrypted tool credential into your own connection
    what happens its seal is bound to the account it was made for, so it does not open; the other account's connection stays invisible
    connection TestConnectionsAreIsolatedByAccount apps/gateway/internal/connection/connection_test.go:328
  • 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 appear
    what happens Listing is scoped at the storage boundary, so tenant B's keys are never in the result to be filtered out
    auth TestKeysHandler_Tenants_Are_Isolated apps/api/internal/auth/keys_handler_test.go:245
  • Two 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 guess
    what happens Each tenant's leaves are salted with a per-tenant secret, so the guess produces a different hash and confirms nothing
    anchor TestLeafHashDifferentSaltsCrossTenantIsolation apps/api/internal/anchor/merkle_salt_test.go:54
  • a literal copy of a tool's credential in its result is removed before the result is stored, returned to the agent or replayed.

    someone tries connect a tool that echoes its bearer credential verbatim in a successful result
    what happens the credential is replaced with [redacted] before the result is stored, so neither the response nor a replay carries it
    gateway TestSuccessfulResultIsRedacted apps/gateway/internal/gateway/gateway_test.go:891
  • a connected tool cannot point KIFF at internal, loopback, link-local or cloud metadata addresses.

    someone tries connect a tool whose URL resolves to localhost or the cloud metadata address
    what happens the connection is refused before anything is contacted
    connection TestUntrustedURLsAreRefused apps/gateway/internal/connection/connection_test.go:417

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 genuine
    what happens The digest is recomputed from the receipt's own content, so the signature no longer recovers the declared signer
    receipt TestAnchorAttester_TamperedReceiptFailsOnchainVerify apps/api/internal/receipt/anchor_attester_test.go:143
  • A 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 actions
    what happens The build is refused. A receipt describes exactly one executed action or it is not issued
    receipt TestBuild_RejectsTraceWithMultipleExecutions apps/api/internal/receipt/build_test.go:313
  • The 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 to
    what happens The encoding is pinned to fixed bytes, so the build fails before a single receipt is signed against the new shape
    receipt 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 tell
    what happens Observed call counts are compared against recorded decisions, and the difference is reported as undecided calls
    handlers TestCoverage_ReportsCallsThatNeverReachedTheGate apps/api/internal/handlers/coverage_test.go:185

What happens when something breaks

  • a call already sent, or whose outcome is unknown, keeps its recorded outcome and key when the same operation comes again and its amount can't be read now.

    someone tries make the vendor's read fail between a call and its retry, so the retry reads as never sent and the agent does it again under a new id
    what happens the retry answers with the recorded outcome and key; a held call stays held, never decided without its amount
    gateway TestARetryKeepsItsOutcomeWhenTheAmountCantBeReadNow apps/gateway/internal/gateway/amount_test.go:109
  • an approved call is sent to the tool once, however many retries race to collect it.

    someone tries after Approve once, send ten identical retries of the held call at the same time
    what happens exactly one claims the call; the tool receives it once
    gateway TestApprovedHoldForwardsOnceUnderConcurrentRetries apps/gateway/internal/gateway/gateway_test.go:548
  • 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 composed
    what happens That section is marked unavailable and the rest still answers, rather than an empty section reading as a clean one
    evidence TestCompose_PostureReadError_Degrades apps/api/internal/evidence/composer_test.go:390
  • a call whose delivery is in doubt is reported as unknown and is never sent again by KIFF.

    someone tries kill the gateway after it claims a call for sending, then retry the call
    what happens after the lease the call reads unknown, and the retry does not reach the tool
    gateway TestCrashWhileForwardingIsUnknownAndNotResent apps/gateway/internal/gateway/gateway_test.go:785
  • When 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 tenant
    what happens Exactly one survives and the loser deletes the tenant it created, leaving no orphan
    tenant TestEnsureForSubject_LoserOfRaceCleansUpItsTenant apps/api/internal/tenant/ensure_test.go:270
  • When 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-request
    what happens The request is allowed. Blocking production traffic because our meter was uncertain is the worse failure
    usage TestLimiter_FlushFailureIsAllowedWhenUncertain apps/api/internal/usage/limiter_test.go:321
  • when 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 allow
    what happens Evaluate returns ErrUsageUnavailable and the caller must refuse, the opposite default to the billing limiter beside it, which allows when uncertain on purpose
    mandate TestMandateFailsClosedUnlikeTheUsageLimiter apps/api/internal/mandate/mandate_test.go:107
  • If 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 fails
    what happens The mutation rolls back. A suspended tenant with no audit record is not a state this system can reach
    handlers TestOps_Suspend_AuditFailureLeavesTenantUnchanged apps/api/internal/handlers/ops_audit_failure_test.go:55
  • planque confirms a halt by reading it back with its connector key, and that read never asks planque to confirm again, so one halt is one confirm, not a loop.

    someone tries a halt whose confirm re-enters itself, so the ack is never recorded and every dispatch read starts the same storm
    what happens planque's read only answers; the halt is confirmed once and reads halted
    handlers TestPlanquesReadBackConfirmsOnceWithoutLooping apps/api/internal/handlers/halts_test.go:209
  • if KIFF cannot record that a call was requested, the call is neither decided nor sent. A call with no record never reaches a tool.

    someone tries make the request record fail while an agent's call arrives
    what happens the gateway fails closed: the tool is not called and nothing is drawn
    gateway TestUnrecordedCallIsNotSent apps/gateway/internal/gateway/gateway_test.go:468

abuse

  • only the account's connector key says a vendor signed a connection out, and each sign-out alerts once an hour at most.

    someone tries an agent's key or a person's session sends sign-out alerts for another taf, or a flapping vendor floods the owner's phone
    what happens anything but a connector key gets 403; a second alert for the same grant within the hour is dropped
    handlers TestConnectionSignedOutAlertsOnceFromTheConnectorKey apps/api/internal/handlers/connection_signed_out_test.go:20

Authority is counted once, and never past a total

  • an approve-once waives a Card's total only when it is a count of 0 the owner reviewed on that hold ("Each call asks you first"), and only for that call: the call counts as used, and the next one asks again. A non-zero total, or any money total, is never waived by approving once.

    someone tries approve one call on a Card that asks about each call, then send more calls hoping the approval carries them; or approve once past a 1-a-day count or a money total
    what happens the next call is held again; a non-zero count or a money total gets can_approve_once false, and an approve-once of it waits as approved_no_room
    mandate TestApproveOnceWaivesOnlyACountOfZero apps/api/internal/mandate/exception_test.go:436
  • reading the Card is not a governed call. It is answered by the gateway: nothing is recorded, decided, drawn or sent to a tool.

    someone tries call kiff_card and expect it to count against a limit or reach a connected tool
    what happens CallTool answers kiff_card before any invocation is begun
    gateway TestCardToolReadsWithoutDeciding apps/gateway/internal/gateway/card_test.go:79
  • an approval cannot carry an action past a Card's total. If the total has no room when the approved action is retried, it waits and nothing is authorized.

    someone tries approve one refund over the per-action limit, spend the Card's total down, then retry the approved refund
    what happens the retry is answered approved_no_room: the approval is kept, nothing is drawn or authorized
    mandate TestNewCumulativeBreachAfterApprovalWaitsForRoom apps/api/internal/mandate/exception_test.go:338
  • no bonus without its audit entry. If the entry can't be written, the bonus is taken back.

    someone tries grant bonus tasks while the operator audit log is failing
    what happens grantBonus revokes the pack when the audit write fails
    handlers TestOps_BonusTasks_AuditFailureTakesTheBonusBack apps/api/internal/handlers/ops_bonus_test.go:92

privacy

  • sharing a taf lets someone use it, not read the account (RFC 050 decision 12). A person reads every call and hold of the tafs they manage, their own runs' calls, and, when they may answer holds, the holds of the tafs they use; an admin, or a person on an account from before roles, reads all of it.

    someone tries a viewer a taf is shared with reads the account's Record, or another person's held call by id
    what happens KIFF scopes the Record and held calls to the reader; another person's hold reads as missing
    handlers TestEachPersonReadsTheirOwnUse apps/api/internal/handlers/own_use_test.go:156

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, apps/gateway 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.