Skip to main contentPASS
Read the docs

Reference

Security model

Threat assumptions, what the architecture is designed to constrain, and the risks it explicitly does not remove.

A permission layer is only as honest as its threat model. PASS constrains a specific class of risk — unauthorized action by an actor who is nonetheless capable of signing and whose transaction is nonetheless valid. It does not constrain everything else. This page states the trust assumptions the architecture makes, walks the failure scenarios it was designed against, and names the residual risk that survives each one.

The distinction that runs through all of it is the one PASS is built on. A private key establishes control: the holder can sign. A protocol establishes validity: the instruction is well formed and executable. Neither establishes authority. Every scenario below is an examination of where authority can still be lost, weakened, or asserted incorrectly.

Trust assumptions

The architecture does not assume an honest actor. It assumes only that honesty cannot be observed: the signing key may be held by software that is compromised, misconfigured, or reasoning badly, and none of those states are visible from a valid signature. An authorization layer that is correct only for well-behaved actors is not an authorization layer. That is the point of mandates.

It does assume certain things. Those assumptions form the perimeter of the model, and what lies outside them is residual risk.

AssumptionWhat depends on it
Issuers attest truthfully about subjectsCredential-gated policy
Adapters decode calldata correctlyEvery asset, action and value check
Preflight is evaluated on the real execution pathThe entire enforcement guarantee
Value oracles report prices within toleranceTransaction and daily limits
Mandate authors write the authority they intendAll policy outcomes
The underlying chain orders and finalizes honestlyExecution itself

The sections that follow examine what happens when each of these assumptions breaks. Where one fails, PASS generally narrows the blast radius; it does not always eliminate the loss.

Compromised actor key

Take the running example. Actor 0x81...29F acts for subject 0x3A...F02 under a mandate whose allowed assets are AAPL and NVDA, whose maximum transaction is $2,500, whose daily exposure limit is $10,000, whose venues are approved adapters only, which requires the credential STOCK_TOKEN_ELIGIBLE, and which blocks bridging. Suppose the key is stolen outright.

The attacker now has full control. They can sign anything. What they cannot do is widen the mandate, because the mandate is not held by the key and is not a client-side configuration the signer supplies.

STOLEN KEY SIGNS INTENT
        |
        v
ADAPTER DERIVES INTENT      <- asset, action, value
        |
        v
POLICY CHECK                <- mandate, not signer
        |
        v
BLOCKED: ASSET_NOT_ALLOWED

An attempt to move value into an asset the mandate does not list returns ASSET_NOT_ALLOWED. An attempt to bridge returns ACTION_NOT_ALLOWED. An attempt to move $50,000 in one call returns TX_LIMIT_EXCEEDED, because the transaction ceiling is $2,500. In-policy trades accumulate against the daily limit instead: four $2,500 trades consume the $10,000 window, and the fifth returns DAILY_LIMIT_EXCEEDED until the window resets. Suspension of the mandate returns MANDATE_SUSPENDED on the next attempt and requires no key rotation to take effect. An expiry that has passed returns MANDATE_EXPIRED with no intervention at all, which is why bounded duration is a mitigation and not a formality.

The residual risk is real. Inside the mandate, the attacker is indistinguishable from the legitimate actor. They can trade AAPL and NVDA at up to $2,500 per transaction and up to $10,000 per day, and every one of those transactions is correctly authorized. The bound is the mandate, and the loss ceiling is whatever the mandate permits before a human or a monitoring system suspends it. Compromise is contained, not prevented.

Malicious or buggy executor

An executor is whatever component submits the transaction after preflight returns AUTHORIZED. If that component is compromised, it may attempt to submit something other than what was evaluated, or to submit an authorized decision more than once.

The architectural requirement is that a decision binds to a specific Execution Intent, not to an actor in general. A decision that does not carry the identity of the intent it approved is a bearer token: anyone holding it can spend it on something else. Binding means the decision names what it approved and stays valid only for that.

interface Decision {
  outcome: 'AUTHORIZED' | 'BLOCKED';
  reason: ReasonCode;
  intentHash: Hash; // the exact call that was evaluated
  actor: Address;
  mandate: MandateRef;
  adapter: AdapterRef;
  validUntil: Timestamp; // narrow, not open-ended
  nonce: Uint256; // single use
}

A resubmission that changes the call no longer matches intentHash. A replay of the same call fails on nonce. A submission after the window closes fails on validUntil. Each of these returns INVALID_EXECUTION_CONTEXT rather than executing against a stale approval. Where a decision cannot be bound to the executed call in this way, the check belongs at execution time rather than being handed forward at all.

Residual risk: an executor can always decline to act. Censorship and liveness are outside what an authorization layer can guarantee. A silent executor produces no unauthorized transaction, but it also produces no transaction, and strategies that depend on timely execution are exposed to that.

Malicious or incorrect adapter

The adapter model exists because calldata cannot be trusted to describe itself. A four-byte selector and an opaque argument blob tell a policy engine almost nothing about what will actually happen. The adapter is the component that turns a raw call into a validated Execution Intent with a named asset, a named action and a computed value.

This makes the adapter the most consequential component in the system. An adapter that decodes a bridge call as a swap, or reports the wrong token address, or undercounts notional value, defeats every downstream check while every check appears to pass. Policy evaluated against a wrong intent produces a confidently wrong AUTHORIZED.

Two structural properties limit this. Adapters are enumerated rather than open: a call routed through an adapter the mandate does not list returns ADAPTER_NOT_ALLOWED, so an attacker cannot introduce a permissive decoder merely by deploying one and routing a call through it. And an adapter that cannot fully decode a call must fail rather than approximate: preflight must refuse an intent it cannot validate, returning INVALID_EXECUTION_CONTEXT rather than guessing at the missing fields.

Residual risk: a listed adapter that is wrong is trusted while it is wrong. Adapter correctness is a review and governance problem, and it does not have a purely cryptographic answer.

Credentials: missing, expired, revoked

Subject 0x3A...F02 holds passport 0x7F...94A, which carries IDENTITY_VERIFIED, NON_US_PERSON, EEA_ELIGIBLE, AML_CHECKED and STOCK_TOKEN_ELIGIBLE. The mandate requires the last of these.

Credential state is evaluated at preflight, not at mandate issuance. A credential absent from the passport returns MISSING_CREDENTIAL. One past its validity window returns CREDENTIAL_EXPIRED. One withdrawn by its issuer returns CREDENTIAL_REVOKED. The design consequence is that eligibility is a live condition: losing a credential narrows authority on the next evaluation without touching the mandate or the key.

Residual risk concentrates in propagation. Revocation is only as fast as the mechanism that publishes it and as fresh as the data preflight reads. Between the moment an issuer decides to revoke and the moment preflight observes it, the credential still evaluates as valid. The architecture supports privacy-preserving credential models and external attestations, which can reduce what a verifier must learn about a subject, but they do not shorten that window.

Compromised or careless issuer

An issuer that signs a false attestation — through compromise, negligence, or a broken verification process — creates a passport that is cryptographically sound and factually wrong. Policy that gates on AML_CHECKED inherits the quality of whoever issued AML_CHECKED.

PASS makes this failure attributable rather than invisible. Attestations name their issuer, so a mandate can require a credential from a specific issuer, and a compromised issuer's credentials can be distrusted as a set. Attributability is a meaningful property and it is not the same as prevention.

Residual risk: the truth of an attestation is a real-world claim, and no onchain system verifies real-world claims. It verifies who asserted them.

Price data and value limits

Transaction and daily limits are denominated in value, which means they depend on a price input. If that input is stale, thin, or manipulable, the limits move with it. An attacker who can depress a reported price can make a transaction that should exceed $2,500 evaluate as under it, and the resulting AUTHORIZED is correct with respect to the data and wrong with respect to reality.

Three practices narrow this. Prefer price sources that are costly to move. Treat stale data as a failure rather than as a fallback. Refuse to evaluate a value-bound policy without a usable price, rather than defaulting to permissive. None of that makes the limit better than its input. Oracle risk is a category PASS depends on and does not remove.

Policy misconfiguration

This is the most likely failure in practice and the least exotic. A mandate that permits more than intended is enforced exactly as written. There is no interpretive layer, and AUTHORIZED means the instruction matched the policy — not that the policy was wise.

A mandate whose author meant $2,500 and wrote $2,500,000 is a functioning mandate. So is one with an unrestricted asset list and no expiry. Both authorize behaviour their author would not have approved, and both do so correctly. The corresponding design guidance is unglamorous: prefer an explicit expiry, prefer enumerated assets over open ones, prefer limits sized to the strategy rather than to convenience, and treat a mandate as a document under review rather than a one-time setup step.

Residual risk: authorization cannot detect intent. A deliberately broad mandate is indistinguishable from a carefully considered one.

Administrative and governance risk

Whoever can issue, amend or suspend a mandate holds authority over the authority layer itself. If that power sits behind a single key, the permission system inherits that key's risk. If it sits behind a governance process, it inherits that process's risk, including capture and coercion.

The relevant properties are separation and observability: the party that can widen a mandate should not be the party that operates under it, and changes should be visible after the fact. MANDATE_SUSPENDED and ACTOR_NOT_AUTHORIZED describe outcomes the administrative layer produces; they say nothing about whether the administrative action was legitimate.

Integration risk

A check placed where it can be bypassed is not a check. If preflight runs as an advisory call in application code while the underlying contract accepts direct transactions from the actor's key, the actor can route around the permission layer entirely, and nothing in the Reason Codes will indicate that it happened.

The integration model treats this as the primary correctness question: authorization must sit on the path that capital actually takes. An authorization layer that is optional at execution time is documentation.

Smart-contract risk

Any onchain implementation of this architecture carries the risk that any contract system carries. Logic errors, upgrade-path errors and composition errors are possible in authorization contracts exactly as they are elsewhere, and an error in a permission contract is more consequential than most because it sits in front of capital.

The soundness of an architecture and the security of an implementation of it are separate engineering questions, verified by separate means: one by specification review, the other by code review, testing and audit. This page addresses the first. It does not stand in for the second, and no reading of it should be treated as evidence about a particular codebase.

Target protocols carry their own contract risk. Authorizing a swap says the swap was permitted. It says nothing about whether the venue executing it is sound.

Threat and residual-risk summary

ThreatConstraintResidual risk
Actor key stolenMandate bounds asset, action, venue and valueFull loss up to the mandate's limits
Executor compromisedDecision binds to one intent, once, for a bounded windowCensorship and non-execution
Adapter incorrectAdapters enumerated; undecodable calls refusedA listed adapter is trusted while wrong
Credential revokedLive evaluation at preflightPropagation delay before revocation is seen
Issuer compromisedAttestations attributable to issuerFalse claims valid until distrusted
Price manipulatedValue limits evaluated per intentLimits inherit oracle quality
Mandate too broadPolicy enforced as writtenIntent is not inferable from policy
Governance captureSeparation of issuance from operationAuthority over authority is a trusted role
Bypassed integrationEnforcement on the execution pathAn off-path check constrains nothing
Contract defectNarrow, reviewable authorization surfaceImplementation risk remains until code is reviewed and tested

What PASS does not protect against

PASS answers whether an actor was permitted to take an action. It does not answer whether the action was a good one. The following are outside the model, and treating them as inside it would be a misreading of what an authorization layer is.

Market loss. An authorized trade in an allowed asset within all limits can lose money. Nothing in a mandate expresses a view on price.

Bad strategy. An actor that trades correctly, in policy, into a poor thesis produces AUTHORIZED on every transaction and a loss at the end of them.

Protocol insolvency and counterparty failure. If a venue, issuer of a tokenized asset, or lending market fails, permission at the moment of execution offers no recovery. Authority is not credit analysis.

Deliberately broad authority. A mandate written to permit a large action permits it. Where an operator grants unbounded authority, the architecture records and enforces that grant faithfully, which is the correct behaviour and not a protection.

Everything downstream of a correct AUTHORIZED. Once policy has been satisfied, execution proceeds into an environment governed by market structure, contract behaviour and chain conditions. PASS constrains the decision to act. It does not constrain the world the action lands in.