Web3 Authentication
To "Sign in with Cardano," users cryptographically prove control of their stake address by signing a unique challenge with their wallet’s private key via CIP-8. This guide shows how to integrate Weld for wallet interactions, craft and sign challenges, verify signatures on your server, and extend authentication with on-chain business logic. (i.e. NFT gating, checking delegation status, wallet whitelisting, etc...)
Core Components
FrontEnd UI (Browser): Initiates the request. We recommend a library like Weld to handle different wallet APIs.
Wallet UI (e.g., Lace, Vespr, Eternl): Holds the user's private key and creates the signature.
Backend Server: Verifies the signature to authenticate the user.
Authentication Flow
1. FrontEnd UI: Create and Sign Payload
Get Address: Retrieve the user's stake address from the connected wallet.
Create Payload: Construct a unique message including the stake address to prevent replay attacks (e.g.,
"Auth for MyDApp: stake1u..."
).Sign Payload: Use the wallet's
signData
function to sign the payload. The wallet returns aCOSE_Sign1
structure (the proof).Send Proof: Send the
COSE_Sign1
proof and the user's public key to the backend server.
2. Backend Server: Verify Proof & Apply Business Logic
The server receives the COSE_Sign1
proof, which contains a protected header (with the user's address), the original payload, and the signature. It must perform these checks:
Check 1: Key Matches Address
Hash the public key received from the client.
Extract the public key hash from the
address
in the proof's protected header.Verify they match. This confirms the public key belongs to the address in the proof.
Check 2: Signature is Valid
Using a crypto library, verify the
signature
against theprotected header
andpayload
.This confirms the proof was signed by the user's private key and hasn't been tampered with.
Check 3: Business Logic Hooks (Optional) With the address cryptographically verified, you can now implement custom business logic. Examples include:
Token/NFT Gating: Query a Cardano API (e.g., Blockfrost, Koios) to confirm the wallet's UTXOs contain a required asset policy ID or fingerprint.
Stake & Delegation Checks: Use the stake address to check delegation status, stake pool, or total ADA balance against your requirements.
Wallet Whitelists/Blacklists: For higher security applications, you might maintain a list of approved stake addresses.
Session Management: If you're using a session-based authentication system, set a secure cookie on the client to grant access.
Replay Protection: The payload should include a
timestamp
. On the server, enforce a time-to-live (TTL) to reject signatures that are too old.Domain Separation: The payload should include the
uri
of the request origin and a specificaction
description. The server must validate these fields to prevent a signature from one domain being reused on another (phishing) and to ensure the user approved the specific action intended.
3. FrontEnd UI: Render Authenticated UI State
Render Authenticated UI State: Once the server has verified the signature, it can grant access to the user's authenticated UI state.
Full Examples
https://github.com/Cardano-Forge/anvil-api/blob/main/docs/developer-tools/guides/transaction/README.mdLast updated
Was this helpful?