WebAuth
in package
Implements SEP-10 Web Authentication protocol
This class provides a complete implementation of the SEP-10 (Stellar Web Authentication) protocol, which enables wallets and clients to prove they control a Stellar account by signing a challenge transaction provided by an anchor's authentication server.
The authentication flow consists of three steps:
- Request a challenge transaction from the server
- Sign the challenge with the client's private key(s)
- Submit the signed challenge back to the server to receive a JWT token
The JWT token can then be used to authenticate subsequent requests to other SEP services such as SEP-24 (hosted deposits/withdrawals), SEP-31 (cross-border payments), or SEP-12 (KYC). The token typically has a limited validity period.
This implementation supports standard accounts, muxed accounts, and client domain verification for non-custodial wallets.
SECURITY WARNINGS:
-
Sequence Number Validation (CRITICAL): Always verify the challenge transaction has sequence number 0. This ensures the transaction cannot be executed on the Stellar network. A non-zero sequence number could allow a malicious server to trick clients into signing executable transactions that transfer funds or modify account settings. This validation prevents transaction execution attacks.
-
Server Signature Verification (CRITICAL): Always verify the challenge is signed by the server's signing key from stellar.toml. This prevents man-in-the-middle attacks where an attacker intercepts the authentication flow and provides a fake challenge to capture client signatures. The server signature proves the challenge originated from the legitimate authentication server.
-
Time Bounds Validation (HIGH): Verify the challenge transaction's time bounds are valid and the current time falls within them. Time bounds prevent replay attacks by limiting challenge validity to approximately 15 minutes. Expired challenges should never be signed or submitted, as they may have been intercepted and are being replayed by an attacker.
-
JWT Token Security (HIGH): Store JWT tokens securely and never expose them in logs, URLs, or insecure storage. Tokens grant access to authenticated services and should be treated as credentials. Use HTTPS for all requests with tokens. Respect token expiration times and request new authentication when tokens expire. Tokens should never be shared between different users or applications.
-
Home Domain Validation (HIGH): Verify the home domain in the challenge matches the expected service. This prevents domain confusion attacks where a challenge for one service is used to authenticate with another. Always validate the first operation's key matches "<expected_domain> auth".
-
Network Passphrase: Use the correct network passphrase (testnet or pubnet) when signing. Mixing passphrases can lead to signature validation failures or security vulnerabilities. Verify the network passphrase matches your intended network before proceeding with authentication.
Tags
Table of Contents
Methods
- __construct() : mixed
- Constructor.
- fromDomain() : WebAuth
- Creates a WebAuth instance by loading the needed data from the stellar.toml file hosted on the given domain.
- jwtToken() : string
- Get JWT token for wallet.
- setMockHandler() : void
- Set a mock HTTP handler for testing purposes.
Methods
__construct()
Constructor.
public
__construct(string $authEndpoint, string $serverSigningKey, string $serverHomeDomain, Network $network[, Client|null $httpClient = null ]) : mixed
Parameters
- $authEndpoint : string
-
Endpoint to be used for the authentication procedure. Usually taken from stellar.toml.
- $serverSigningKey : string
-
The server public key, taken from stellar.toml.
- $serverHomeDomain : string
-
The server home domain of the server where the stellar.toml was loaded from.
- $network : Network
-
The network used.
- $httpClient : Client|null = null
-
Optional http client to be used for requests.
fromDomain()
Creates a WebAuth instance by loading the needed data from the stellar.toml file hosted on the given domain.
public
static fromDomain(string $domain, Network $network[, Client|null $httpClient = null ]) : WebAuth
e.g. fromDomain("soneso.com", Network::testnet())
Parameters
- $domain : string
-
The domain from which to get the stellar information
- $network : Network
-
The network used.
- $httpClient : Client|null = null
-
Optional http client to be used for requests.
Tags
Return values
WebAuthjwtToken()
Get JWT token for wallet.
public
jwtToken(string $clientAccountId, array<string|int, KeyPair> $signers[, int|null $memo = null ][, string|null $homeDomain = null ][, string|null $clientDomain = null ][, KeyPair|null $clientDomainKeyPair = null ][, callable|null $clientDomainSigningCallback = null ]) : string
Executes the complete SEP-10 authentication flow: requests a challenge, validates it, signs it with the provided signers, and submits it to obtain a JWT token.
Parameters
- $clientAccountId : string
-
The account id of the client/user to get the JWT token for (G... or M... address).
- $signers : array<string|int, KeyPair>
-
Array of KeyPair objects (with secret keys) used to sign the challenge transaction. Must include signers with sufficient weight to meet the server's threshold requirements. For accounts that don't exist, must include the master key. For existing accounts, must provide signers that meet the required threshold (typically medium threshold). Minimum: 1 signer. The combined weight must satisfy server authentication requirements.
- $memo : int|null = null
-
optional, ID memo of the client account if muxed and accountId starts with G
- $homeDomain : string|null = null
-
optional, used for requesting the challenge depending on the home domain if needed. The web auth server may serve multiple home domains.
- $clientDomain : string|null = null
-
optional, domain of the client hosting it's stellar.toml. If clientDomain is provided, you also need to provide the clientDomainKeyPair or a clientDomainSigningCallback for client domain transaction signing.
- $clientDomainKeyPair : KeyPair|null = null
-
optional, KeyPair of the client domain account including the seed (used for signing the transaction if client domain is provided)
- $clientDomainSigningCallback : callable|null = null
-
Optional callback for SEP-10 client domain verification when signing cannot be performed locally. The callback receives a base64-encoded transaction envelope XDR string and must return the same transaction signed by the client domain account as a base64-encoded transaction envelope XDR string. Used when the client domain signing key is not available locally (e.g., signing occurs on a separate server). Callback signature: function(string $transactionXdr): string
Tags
Return values
string —JWT token that can be used to authenticate requests to protected services.
setMockHandler()
Set a mock HTTP handler for testing purposes.
public
setMockHandler(MockHandler $handler) : void
Replaces the HTTP client with one using the provided mock handler. This allows tests to simulate authentication server responses without making actual HTTP requests.
Parameters
- $handler : MockHandler
-
Guzzle mock handler with predefined responses.