Like "Sign In With Google" — but for AI agents. No OAuth. No browsers. No humans in the loop. Just cryptography.
Agents authenticate the same way they sign transactions — with their keypair. No OAuth flows, no browser redirects, no consent screens.
Agent sends its public key to the service. Service returns a unique challenge message with a nonce and expiration.
GET /siwa/challenge
Agent signs the challenge with its Ed25519 private key. This proves identity without revealing the secret key.
nacl.sign.detached()
Service verifies the signature matches the public key. Checks domain, nonce, and timing to prevent replay attacks.
POST /siwa/verify
On success, the service issues a bearer token. The agent uses this for all subsequent API calls until expiry.
Bearer siwa_eyJ...
Existing auth methods were designed for humans. SIWA was designed for machines.
| SIWA | OAuth 2.0 | API Keys | SIWE | |
|---|---|---|---|---|
| No browser required | ✓ | ✗ | ✓ | ✗ |
| No human in the loop | ✓ | ✗ | ~ | ✗ |
| Cryptographic identity | ✓ | ✗ | ✗ | ✓ |
| Replay protection | ✓ | ✓ | ✗ | ✓ |
| Self-provisioning | ✓ | ✗ | ✗ | ✓ |
| Solana-native | ✓ | ✗ | ✗ | ✗ |
| Built for agents | ✓ | ✗ | ✗ | ✗ |
| Credential-free | ✓ | ✗ | ✗ | ✓ |
Drop-in client for agents, Express middleware for services. TypeScript-first, zero config.
import { SIWAClient } from '@siwa/client'; import { Keypair } from '@solana/web3.js'; // Create client with agent's keypair const client = new SIWAClient({ keypair: Keypair.generate(), // or load from file }); // Authenticate with any SIWA-enabled service const session = await client.signIn('https://api.example.com'); // Use the session token for API calls const authedFetch = client.authenticatedFetch(session); const data = await authedFetch('/api/protected');
import express from 'express'; import { SIWAServer } from '@siwa/server'; const app = express(); const siwa = new SIWAServer({ domain: 'api.example.com', uri: 'https://api.example.com', statement: 'Sign in to Example API', }); // Challenge endpoint app.get('/siwa/challenge', async (req, res) => { const challenge = await siwa.createChallenge(req.query.pubkey); res.json(challenge); }); // Verify endpoint app.post('/siwa/verify', async (req, res) => { const session = await siwa.verifySignature( req.body.message, req.body.pubkey, req.body.signature ); res.json(session); }); // Protected route with middleware app.get('/api/data', siwa.middleware(), (req, res) => { res.json({ agent: req.agentAddress }); });
import { Keypair } from '@solana/web3.js'; import { createMessage, serializeMessage, verify } from '@siwa/core'; import nacl from 'tweetnacl'; import bs58 from 'bs58'; // === AGENT SIDE === const keypair = Keypair.generate(); const pubkey = keypair.publicKey.toBase58(); // 1. Get challenge from service (fetch omitted for clarity) const challenge = await getChallenge(pubkey); // 2. Sign the challenge message const msgBytes = new TextEncoder().encode(challenge.message); const sig = nacl.sign.detached(msgBytes, keypair.secretKey); const signature = bs58.encode(sig); // === SERVICE SIDE === // 3. Verify the signature const result = await verify(challenge.message, signature, pubkey, { domain: 'api.example.com', }); if (result.success) { console.log('✓ Agent authenticated:', result.message.address); // Issue session token, grant access... }
Everything you need to add agent auth to your service. Nothing you don't.
Same curve as Solana transactions. Agents prove identity with their existing keypair.
One-time nonces and expiring challenges prevent signature reuse attacks.
Challenges expire in minutes, sessions in hours. Configurable per service.
One-line middleware for protected routes. Required or optional auth modes.
In-memory by default. Swap in Redis, Postgres, or any custom backend.
Resources field lets services define fine-grained permissions per session.
Messages are bound to a specific domain, preventing cross-service replay.
Full type definitions, zero any. IntelliSense works out of the box.
Use just what you need — core for verification, client for agents, server for services.
Message creation, parsing, serialization, and signature verification. The protocol itself.
npm i @siwa/core
Drop-in SDK for AI agents. Sign challenges, manage sessions, authenticated fetch.
npm i @siwa/client
Server utilities. Challenge generation, session management, Express middleware.
npm i @siwa/server
AI agents authenticate with APIs, databases, and cloud services without human-provisioned credentials.
Agents verify each other's identity before sharing data or delegating tasks in swarm architectures.
Trading bots and treasury agents authenticate with DeFi protocols using their existing Solana keypair.
Directories and marketplaces verify agent identity. Agents register themselves, no admin needed.
Agents purchase services, reserve resources, or pay per API call — all authenticated by wallet.
Gate features by wallet address. Allowlist specific agents, enforce on-chain reputation, or check NFT holdings.
Authenticated micropayments. Agents pay per call with USDC. One flow: auth + payment.
Open source, MIT licensed, and ready for production. Add agent auth to your service in minutes.