Overview
The permission gap
Why keys, wallet permissions, protocol validation, application logic and model instructions each solve a different problem than a portable financial mandate.
Every system that moves capital has to answer some version of the same question before it acts: is this permitted. In practice that question is split across several layers, each of which answers a narrower version of it well, and none of which answers the whole of it. What is missing is not a feature in any one of those layers. It is a layer.
Take a concrete sequence. Actor 0x81...29F decides to acquire a tokenized equity on
behalf of a subject. It holds a key. It constructs a call to a venue. The call is well
formed, the signature verifies, the venue's own checks pass, and state changes. At no
point in that sequence does any component establish that this actor was permitted to buy
this asset, at this size, at this venue, on behalf of this subject, today. Each layer did
its job correctly. The question of authority was never assigned to any of them.
Five mechanisms are commonly offered as an answer. Each solves a real problem. None of them is a portable financial mandate, and it is worth being precise about why.
Private keys and signatures
A valid signature proves that whoever produced it had access to the private key for an account, and that the signed payload was not altered in transit. This is the foundation the rest of the system rests on, and it is a strong one: cryptographic control is verifiable by anyone, requires no trusted intermediary, and fails closed.
What a signature does not carry is purpose. One key signs a $500 purchase of AAPL and a transfer of the entire balance across a bridge, and both signatures verify identically. Nothing in the signing operation encodes an asset restriction, a size limit, a subject, or a condition that had to hold beforehand.
This is tolerable when the keyholder and the accountable party are the same person, and the gap between intent and execution is a human decision. The gap becomes load-bearing under delegation. When a key is operated by an autonomous process rather than by the person answerable for the position, "the key signed it" and "this was authorized" stop being the same statement. The signature remains valid evidence of control. It was never evidence of authority.
Wallet and account-abstraction permission systems
Session keys, spending caps, module permissions, guard hooks and custody transaction policies exist precisely because the previous point is understood. They solve a real problem and they solve it well: they reduce the blast radius of a delegated signer. A session key that can call two contracts and spend at most a fixed amount per day is meaningfully safer than a key that can do anything. A system that delegates signing to an automated process should use them.
Three properties limit them as a general authority layer.
The first is scope. These permissions are properties of one account implementation. A configuration installed in a smart account governs that account. It does not travel to a second account, a different wallet standard, a custody provider, or another chain. Authority ends up re-expressed, by hand, once per account, and re-expression is where divergence enters.
The second is vocabulary. Account-level permissions are naturally expressed in terms of calls and tokens: target address, function selector, allowance per token per period. That is the correct vocabulary for constraining a signer. It is not the vocabulary in which financial authority is written.
// A call-level permission constrains a signer.
interface CallPermission {
target: Address; // one contract
selector: string; // one function
tokenAllowance: bigint; // per token, per period
validUntil: number;
}
// Financial authority is a different statement.
interface Mandate {
actor: Address; // 0x81...29F
subject: Address; // 0x3A...F02, the party on whose behalf it acts
allowedAssets: string[]; // AAPL, NVDA
allowedActions: string[]; // BUY, SELL, not BRIDGE
maxTransactionValue: number; // 2500
dailyExposureLimit: number; // 10000
requiredCredentials: string[]; // STOCK_TOKEN_ELIGIBLE
allowedVenues: AdapterId[]; // approved adapters only
validUntil: number;
}These sketches are conceptual interface definitions, not an API. The second statement can be compiled down into a set of the first, but the compilation discards the subject, the credential condition, the cross-venue aggregate and the reason. What survives is a set of allowances that approximated a mandate on the day it was written, with no record of what it meant.
The third is verifiability. An account-level permission is enforced by the account and legible to whoever can read that account's state. It is not a statement a counterparty, venue, auditor or issuer can evaluate independently of that implementation, and it says nothing about the actor when the actor operates through a different account.
Protocol-level validation
Protocols validate. A lending market checks collateral ratios. An automated market maker checks slippage bounds and deadlines. A token contract checks balances and allowances, and a permissioned token may additionally enforce transfer restrictions, allowlists or role-gated functions. That work is necessary, and where a protocol enforces permissioning directly, the enforcement is real.
But validity is a property of an instruction relative to the protocol's own state machine. It answers whether the protocol can execute this call correctly. It does not answer whether the caller should have issued it. A protocol has no view of the actor's mandate, of the subject on whose behalf the actor acts, of limits defined outside the protocol's accounting, or of what the same actor did elsewhere ten minutes ago. Permissioning that a protocol does carry is defined by that protocol for its own purposes. It is not a general statement of the actor's authority, and was never intended to be.
The cross-venue case makes this structural rather than incidental. A daily exposure limit of $10,000 across all activity cannot be enforced by any single venue, because no single venue sees the whole of the activity. There is no place inside a protocol to put a constraint that is not about that protocol.
Application-level permission logic
Inside applications, permission logic is frequently the most developed work of its kind anywhere in the execution path. Trading systems, treasury platforms and brokerage backends encode who may trade what, at what size, with approval thresholds, dual authorization, pre-trade risk checks and audit trails. Institutions have refined these controls over decades, and they work.
Their limits are limits of boundary, not of quality. The logic lives inside one application: an actor authorized there carries nothing when it acts through anything else. The logic is not verifiable by counterparties, because a venue that receives the resulting transaction sees a signed call, and the check that preceded it is asserted rather than evidenced. And the logic does not travel with the actor, because it was never a property of the actor. It is a property of the system the actor happened to be inside.
Natural-language instruction to a model
Constraints written into a prompt or system message are a legitimate control. They steer behaviour, encode nuance that is awkward to formalize, and reduce error at very low cost. Autonomous actors can increasingly make and execute decisions, and giving them explicit written limits improves what they do.
It is, however, a different kind of thing from an enforcement boundary. An instruction is a probabilistic input to a decision process. Adherence is likely, not guaranteed, and it degrades under long contexts, ambiguous states, tool failures and adversarial input. The actor need not be adversarial for the boundary to fail; ordinary error is sufficient.
The more structural point holds even for a model that follows its instructions perfectly. The instruction exists only inside the actor. No other party in the execution path can read it. The venue cannot evaluate it, the counterparty cannot verify it, and the accountable institution cannot demonstrate afterwards which limit was in force at the moment of execution. A constraint that only one participant can see produces no artefact anyone else can check.
Where each layer stops
| Mechanism | Establishes | Does not establish | Scope |
|---|---|---|---|
| Key and signature | Control of an account, integrity of the payload | Purpose, limits, entitlement | One account |
| Account-level permissions | Bounded delegation for a signer | Financial meaning, portability, external verifiability | One account implementation |
| Protocol validation | Validity of an instruction for that protocol | Whether the caller was permitted to issue it | One protocol |
| Application logic | Internal authorization and workflow control | Anything the actor can carry or a counterparty can verify | One application |
| Model instruction | Expressed intent, behavioural steering | An enforcement boundary readable by other parties | Inside the actor |
Read down the last column. Every mechanism is anchored to something: an account, a protocol, an application, a runtime. Financial authority is anchored to none of them. It is a relationship between an actor, a subject and a set of limits, and it is supposed to hold wherever the actor acts.
CAN IT SIGN? -> key -> CONTROL
IS IT WELL FORMED? -> protocol -> VALIDITY
WAS IT PERMITTED? -> nothing -> AUTHORITYThe gap, stated precisely
There is no layer that expresses financial authority in financial terms — actor, subject, asset, action, transaction limit, cumulative limit, credential condition, venue constraint, validity period — independently of any single account implementation, application or venue, and evaluates it at the point where an action becomes irreversible.
Three properties are required together, and each is what makes the other two useful.
Financial vocabulary, because a constraint that has been compiled down into allowances can no longer be read, reviewed or explained as a mandate. Independence, because authority that is a property of one account or one application is not a property of the actor and does not survive the actor moving. Evaluation at the boundary, because a check that runs somewhere other than immediately before execution is advice: correct at the moment it ran, and unbinding on what happens next.
PROPOSED EXECUTION
|
v
NORMALIZE / VALIDATE <- adapter derives intent
|
v
AUTHORITY EVALUATION <- the missing layer
|
v
AUTHORIZED | BLOCKED + REASON
|
v
IRREVERSIBLE STATE CHANGEThe last line is why position matters. Onchain execution has no settlement window in which an authorization error can be caught and unwound. Whatever is going to be checked has to be checked before the call, not reconciled after it.
Why the gap becomes load-bearing now
The gap is not new. It was historically filled by a person: an operator, a desk, a compliance function that knew the mandate and stood between the instruction and the market. That arrangement held because a person sat at the boundary, and human latency functioned as an implicit rate limit.
Where an actor originates a decision, constructs the call and signs it without a person at each step, there is nowhere left for informal authority to sit. This is not a claim that autonomous actors are untrustworthy. It is a claim about representation. Authority that exists only as an understanding between people cannot be evaluated by a machine and cannot be shown to a counterparty. To survive automation, it has to become data.
That is what the rest of this documentation defines. A passport is a credential container holding attestations about a subject, issued by an issuer. A mandate binds an actor to that subject and states what the actor may do, within which limits and for how long, assembled from policies that are individually enforceable. An adapter decodes a proposed call into a validated Execution Intent, because calldata cannot be trusted to describe itself. Preflight evaluates that intent against the mandate before execution and returns a decision carrying a deterministic Reason Code.
The codes are the difference between a boundary and a bare refusal. Under the mandate
sketched above, a $4,000 purchase of AAPL is blocked with TX_LIMIT_EXCEEDED: the maximum
transaction value is $2,500, and the excess is the reason. A bridging call is blocked with
ACTION_NOT_ALLOWED, a purchase routed outside the approved venues with
ADAPTER_NOT_ALLOWED. Credential conditions resolve the same way. Passport 0x7F...94A
carries STOCK_TOKEN_ELIGIBLE alongside IDENTITY_VERIFIED, NON_US_PERSON,
EEA_ELIGIBLE and AML_CHECKED, so it meets the mandate's requirement; an otherwise
identical purchase for a subject whose passport lacks that credential is blocked with
MISSING_CREDENTIAL. Each outcome names the constraint that produced it, which is what
makes the result reviewable by an operator, an auditor and the actor itself.
What this does not close
The gap described here is an authorization gap, and closing it leaves market, smart-contract, oracle and governance risk exactly where they were — the security model sets out those boundaries and the assumptions the architecture depends on.