The full SIWS message format specification, including field definitions, grammar, verification process, and security considerations.
Abstract
This specification defines a standardized message format and Ed25519 verification process that lets Solana wallet owners authenticate with off-chain services without on-chain transactions.
Motivation
Solana wallets are widely deployed, yet no standard exists for using them as authentication credentials. Ad-hoc implementations lead to:
- Inconsistent user experiences
- Security vulnerabilities
- Lack of interoperability
This specification addresses these issues with a secure, human-readable message format and verification process.
Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Additional terms:
- Wallet: A cryptographic keypair capable of signing messages using Ed25519
- Relying Party: The service requesting authentication
- Message: The human-readable string presented to the user for signing
Message Format
A SIWS message MUST conform to the following structure:
${domain} wants you to sign in with your Solana account:
${address}
${statement}
URI: ${uri}
Version: ${version}
Nonce: ${nonce}
Issued At: ${issuedAt}
Expiration Time: ${expirationTime}
Not Before: ${notBefore}
Request ID: ${requestId}
Cluster: ${cluster}
Resources:
- ${resources[0]}
- ${resources[1]}
- ...Required Fields
| Field | Description | Format |
|---|---|---|
domain | RFC 3986 authority requesting authentication | authority per RFC 3986 |
address | Solana wallet address | Base58-encoded Ed25519 public key |
uri | RFC 3986 URI identifying the authentication target | URI per RFC 3986 |
version | SIWS specification version | 1 |
nonce | Randomized token for replay protection | Alphanumeric, >=8 characters |
issuedAt | Message creation timestamp | ISO 8601 datetime |
cluster | Solana network identifier | mainnet-beta | devnet | testnet |
Optional Fields
| Field | Description | Format |
|---|---|---|
statement | Human-readable purpose description | UTF-8 string, no \n |
expirationTime | Message expiration timestamp | ISO 8601 datetime |
notBefore | Message validity start timestamp | ISO 8601 datetime |
requestId | Application-specific request identifier | String |
resources | Resources being authorized | Array of RFC 3986 URIs |
Field Definitions
domain
RFC 3986 authority matching the requesting origin. MUST NOT include a scheme or path. Relying parties MUST reject mismatched domains.
address
Base58-encoded Ed25519 public key (32 bytes, 43-44 characters). The signature MUST be verified against this key.
uri
Valid RFC 3986 URI. SHOULD match the endpoint receiving the authentication request.
version
MUST be 1 for this specification.
nonce
At least 8 alphanumeric characters from a CSPRNG. Relying parties MUST:
- Generate a unique nonce per authentication attempt
- Store nonces server-side with an expiration time
- Reject unknown, expired, or previously used nonces
- Invalidate nonces after successful verification
Recommendation: Use >=16 bytes of randomness, Base58 or hex encoded.
issuedAt
ISO 8601 datetime in UTC (Z suffix).
statement
OPTIONAL. MUST NOT contain newline characters. SHOULD describe the authentication purpose.
expirationTime
OPTIONAL. Relying parties MUST reject messages past this time.
Recommendation: 5-15 minutes from issuedAt.
notBefore
OPTIONAL. Relying parties MUST reject messages before this time.
cluster
REQUIRED. One of mainnet-beta, devnet, testnet. Relying parties MUST validate to prevent cross-cluster replay.
resources
OPTIONAL. Each resource MUST be a valid RFC 3986 URI.
Signature Verification
Solana uses Ed25519 for message signing. Verification MUST proceed as follows:
- Encode the message string as UTF-8 bytes
- Decode the signature from Base58 (64 bytes)
- Decode the public key from Base58 (32 bytes)
- Verify using Ed25519:
ed25519.verify(signature, message, publicKey)
Message Grammar
The message format is defined using ABNF (RFC 5234):
siws-message = domain-line LF address-line LF LF
[ statement-line LF LF ]
field-lines
domain-line = domain " wants you to sign in with your Solana account:"
address-line = address
statement-line = statement
field-lines = uri-field LF version-field LF nonce-field LF
issued-at-field LF
[ expiration-field LF ]
[ not-before-field LF ]
[ request-id-field LF ]
cluster-field LF
[ resources-field ]
uri-field = "URI: " uri
version-field = "Version: " version
nonce-field = "Nonce: " nonce
issued-at-field = "Issued At: " iso8601-datetime
expiration-field = "Expiration Time: " iso8601-datetime
not-before-field = "Not Before: " iso8601-datetime
request-id-field = "Request ID: " request-id
cluster-field = "Cluster: " cluster
resources-field = "Resources:" LF resource-list
resource-list = 1*( "- " uri LF )
domain = authority ; RFC 3986
address = 43*44BASE58CHAR
uri = URI ; RFC 3986
version = "1"
nonce = 8*ALPHANUM
statement = 1*( %x20-7E ) ; printable ASCII, no newlines
request-id = 1*( %x20-7E )
cluster = "mainnet-beta" / "devnet" / "testnet"
iso8601-datetime = ; ISO 8601 datetime with Z suffix
ALPHANUM = ALPHA / DIGIT
BASE58CHAR = %x31-39 / %x41-48 / %x4A-4E / %x50-5A / %x61-6B / %x6D-7A
LF = %x0ASecurity Considerations
Replay Attacks
Captured signatures reused for unauthorized authentication. Single-use nonces MUST be enforced with expiration (RECOMMENDED: 5 minutes). expirationTime provides defense in depth.
Cross-Site Request Forgery
Signatures obtained from one site used on another. domain MUST be verified server-side and uri binds authentication to a specific endpoint. Relying parties MUST reject domain/URI mismatches.
Phishing
Users deceived into signing messages for malicious sites. Wallets SHOULD display the complete message before signing and warn on unfamiliar domains. domain and statement help users identify the requesting party.
Nonce Compromise
Leaked or predicted nonces enable replay attacks. Generate nonces using CSPRNG, store server-side only, bind to session or client identifiers, and enforce expiration.
Test Vectors
Vector 1: Minimal Message
example.com wants you to sign in with your Solana account:
7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
Sign in to Example
URI: https://example.com/auth
Version: 1
Nonce: k8sj2n4b
Issued At: 2024-01-15T12:00:00Z
Cluster: mainnet-beta
Vector 2: Complete Message
app.example.com wants you to sign in with your Solana account:
7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
Access your dashboard and manage settings.
URI: https://app.example.com/api/auth
Version: 1
Nonce: f7k2m9p4x1
Issued At: 2024-01-15T12:00:00.000Z
Expiration Time: 2024-01-15T12:10:00.000Z
Not Before: 2024-01-15T12:00:00.000Z
Request ID: req_abc123
Cluster: mainnet-beta
Resources:
- https://app.example.com/api/profile
- https://app.example.com/api/settings