Skip to main contentPASS
Read the docs

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

MechanismEstablishesDoes not establishScope
Key and signatureControl of an account, integrity of the payloadPurpose, limits, entitlementOne account
Account-level permissionsBounded delegation for a signerFinancial meaning, portability, external verifiabilityOne account implementation
Protocol validationValidity of an instruction for that protocolWhether the caller was permitted to issue itOne protocol
Application logicInternal authorization and workflow controlAnything the actor can carry or a counterparty can verifyOne application
Model instructionExpressed intent, behavioural steeringAn enforcement boundary readable by other partiesInside 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   -> AUTHORITY

The 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 CHANGE

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