> ## Documentation Index
> Fetch the complete documentation index at: https://docs.socket.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet Authorization: Signatures, Nonces, and Enforcement

> How SocketFi wallets verify passkey signatures, use sequential nonces to block replay attacks, and enforce authorization on-chain before any state change.

Authorization is the mechanism that makes SocketFi wallets secure. It is distinct from authentication: authentication answers *who are you?*, while authorization answers *are you allowed to do this right now?* Every state-changing wallet operation — transfers, contract calls, policy updates, credential rotation, recovery — must carry a valid authorization before the wallet contract will execute it. Without a passing authorization check, the operation is rejected on-chain. No exceptions.

## Authentication vs Authorization

It is easy to conflate these two concepts, but they serve different purposes in the SocketFi architecture:

|                       | Authentication                  | Authorization                         |
| --------------------- | ------------------------------- | ------------------------------------- |
| **Question answered** | Who are you?                    | Can you do this?                      |
| **When it happens**   | Sign-in / session creation      | Every state-changing wallet operation |
| **What it produces**  | A session token                 | A signed authorization message        |
| **What verifies it**  | SocketFi authentication service | The wallet smart contract on Soroban  |
| **Example**           | Face ID unlocks the app         | Face ID approves a 100 USDC transfer  |

Authentication gives your application a session. Authorization gives the wallet contract proof that the current operation was explicitly approved by the wallet's owner.

## Authorization Message Structure

Before a wallet operation executes, an authorization message is constructed and signed by the user's passkey. The message binds together everything relevant to the operation:

```text theme={null}
Authorization Message
─────────────────────────────────
Wallet address    CDXXXXXXXXXX...   ← which wallet is acting
Action            transfer          ← what operation is being authorized
Arguments         { to: "...", amount: 100 }   ← exact parameters
Nonce             42                ← must match wallet's current nonce
Expiration        ledger 12500      ← authorization expires after this ledger
```

The user's passkey signs this exact message. The wallet contract independently reconstructs the expected message from the transaction context and verifies that the signature matches. If any field differs — including the nonce or expiration — verification fails.

## The Nonce System

The nonce is a sequential counter stored in the wallet's on-chain state. It starts at `0` when the wallet is created and increments by 1 after every successfully executed state-changing operation. Its purpose is to prevent replay attacks.

**How nonces prevent replay attacks:**

```text theme={null}
Transaction submitted:  Nonce = 42
Wallet verifies:        Expected nonce = 42  ✅
Execution succeeds
Wallet nonce becomes:   43

Replay attempt:         Nonce = 42
Wallet verifies:        Expected nonce = 43  ❌
Execution rejected
```

Without nonces, an attacker who intercepted a valid authorization signature could resubmit it repeatedly. With sequential nonces, each authorization is one-time-use: once a nonce is consumed, that exact authorization can never be reused.

**Nonce flow for every transaction:**

```text theme={null}
1. SDK reads current wallet nonce
2. SDK constructs authorization message with nonce = current
3. User signs the message with their passkey
4. Wallet verifies: signature valid + nonce matches expected
5. Transaction executes
6. Wallet nonce increments to current + 1
```

## Expiration Windows

Every authorization message includes a `valid_until` ledger number. The wallet contract checks the current Stellar ledger sequence against this value before executing. Authorizations that exceed their window are rejected even if the signature is valid.

```text theme={null}
Current ledger:   12,480
Authorization:    valid_until = 12,500

12,480 < 12,500 → ✅ Within window, proceed

Later attempt:
Current ledger:   12,510
Authorization:    valid_until = 12,500

12,510 > 12,500 → ❌ Expired, reject
```

Keeping expiration windows short (seconds to minutes, not hours) reduces the risk window if an authorization message is intercepted in transit.

## What Requires Authorization

Every operation that changes wallet state requires a valid authorization. Read-only operations do not.

<CardGroup cols={2}>
  <Card title="Asset Transfers" icon="arrow-right-arrow-left">
    Sending any asset from the wallet to another address.
  </Card>

  <Card title="Contract Calls" icon="code">
    Invoking any method on a Soroban smart contract through the wallet.
  </Card>

  <Card title="Policy Changes" icon="sliders">
    Adding, removing, or modifying spending limits, contract allowlists, or other wallet policies.
  </Card>

  <Card title="Credential Updates" icon="key">
    Rotating the passkey credential bound to the wallet (requires the current credential's authorization).
  </Card>
</CardGroup>

<Note>
  Account recovery follows a separate authorization path — it does not require the current credential (which is lost), but instead requires identity verification through the recovery system. See [Recovery](/smart-wallet/recovery) for details.
</Note>

## Verification Pipeline

The wallet contract runs every authorization through this pipeline before execution:

```text theme={null}
Incoming operation
  ↓
① Verify passkey signature
    Does the signature match the expected authorization message?
    Does the signing key match the wallet's bound credential?
  ↓
② Verify nonce
    Does the nonce in the message match the wallet's current nonce?
  ↓
③ Verify expiration
    Is the current ledger before the valid_until ledger?
  ↓
④ Verify policies
    Do all configured wallet policies approve this operation?
  ↓
Execute
  ↓
Increment nonce
```

Failure at any stage stops execution immediately. The wallet state is not modified.

## Authorization Failure Reasons

When an authorization check fails, the wallet returns a specific failure reason:

| Failure                   | Cause                                                      | Resolution                                                   |
| ------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
| **Invalid signature**     | Signature does not match the bound credential's public key | User must re-authorize with the correct passkey              |
| **Invalid nonce**         | Nonce in message does not match wallet's current nonce     | SDK fetches a fresh nonce and reconstructs the authorization |
| **Expired authorization** | Current ledger is past the `valid_until` value             | User must re-authorize with a new expiration window          |
| **Unauthorized action**   | The operation type is not permitted for this credential    | Check whether recovery authorization is needed instead       |
| **Policy violation**      | A wallet policy rejected the operation                     | See [Policies](/smart-wallet/policy) for evaluation details  |

## Security Properties

The authorization system provides four concrete security guarantees:

<AccordionGroup>
  <Accordion title="Ownership enforcement">
    Only operations signed by the wallet's bound passkey credential are authorized. The wallet contract verifies the signature against the stored public key on every operation — there is no administrative override.
  </Accordion>

  <Accordion title="Replay protection">
    The sequential nonce system ensures each authorization is consumed exactly once. An authorization signed for nonce 42 cannot be replayed once the wallet's nonce has advanced to 43.
  </Accordion>

  <Accordion title="Time-bound validity">
    The `valid_until` expiration window ensures that stale or intercepted authorizations cannot be submitted indefinitely. Authorization windows should be kept as short as practical for your use case.
  </Accordion>

  <Accordion title="On-chain enforcement">
    Authorization is enforced by the Soroban wallet contract itself, not by SocketFi's off-chain infrastructure. There is no intermediary that can bypass or override the on-chain verification logic.
  </Accordion>
</AccordionGroup>
