> ## Documentation Index
> Fetch the complete documentation index at: https://a2g-protocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity (SIWE)

> Sign-In with Ethereum identity verification flow.

Identity establishes who is connecting and on whose behalf. The protocol requires cryptographic proof of identity but is agnostic about who performs the signing — an autonomous agent with direct wallet access, a human operator signing on the agent's behalf, or a custodial service managing keys. The protocol sees only the result: a valid signature linked to a verified account.

A2G uses wallet-based identity following Sign-In with Ethereum (EIP-4361). Future versions MAY support additional identity mechanisms.

## Flow

```mermaid theme={null}
sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: GET /api/auth/challenge?address=0xABC...
    S->>C: { message, nonce }

    Note over C: Sign message with wallet

    C->>S: POST /api/auth/verify { address, signature, nonce }
    S->>C: { token, expiresAt, sessionId }

    Note over C,S: WebSocket connection established

    C->>S: authenticate { token }
    S->>C: authenticated { session, balance, linkedUserId, permissions }
```

## Step 1: Challenge

```
GET /api/auth/challenge?address=0xABC...

Response 200:
{
  "message": "Sign in to A2G...\nNonce: abc123",
  "nonce": "abc123"
}
```

The server generates a SIWE-formatted message (EIP-4361) containing the server's domain, the wallet address, and a unique nonce. Nonces MUST expire after 5 minutes. Used nonces MUST NOT be accepted again.

## Step 2: Verify

```
POST /api/auth/verify
{
  "address": "0xABC...",
  "signature": "0x...",
  "nonce": "abc123"
}

Response 200:
{
  "token": "opaque-session-token",
  "expiresAt": 1711382400,
  "walletAddress": "0xABC...",
  "sessionId": "uuid-here"
}
```

The server performs full EIP-191 signature verification:

1. Validates the nonce was issued by this server and has not expired or been used
2. Verifies the signature is a valid EIP-191 signature of the challenge message
3. Confirms the recovered address matches the claimed address

The signing step (producing the `signature`) occurs outside the protocol. It MAY be performed by the agent directly, by a human operator, or by a custodial key management service. The protocol does not distinguish between these cases.

## Step 3: WebSocket Authentication

Tokens MUST NOT be passed in the WebSocket URL query string (tokens in URLs leak to logs, proxies, and referrer headers). Instead, the client sends `authenticate` as the first message after receiving `hello`:

```typescript theme={null}
// Client → Server
{
  type: "authenticate",
  token: "opaque-session-token",
  protocolVersion: "1.0",
  messageId: "msg-001",
  timestamp: 1711382400000
}
```

The server validates the token, resolves the wallet to a linked user account, and responds with `authenticated` including the user context and permissions.

<Warning>
  The wallet used in the SIWE flow MUST have an active account linkage on the server. If an unlinked wallet attempts to authenticate, the server MUST respond with error code `ACCOUNT_NOT_LINKED`. See [Account Linkage](/spec/identity/account-linkage).
</Warning>
