Guardian API
Authentication

Authentication

Guardian API uses wallet-based authentication via message signing.

Overview

Most Guardian endpoints are public (read-only). Write operations require authentication via Solana wallet signature.

Public Endpoints

These endpoints don't require authentication:

  • GET /api/health - Health check
  • GET /api/vaults - List vaults (paginated)
  • GET /api/vaults/:id - Get vault details
  • GET /api/transactions - List transactions
  • GET /api/analytics - Get analytics
  • GET /api/actions/:vault/:nonce - Get Blink metadata

Protected Endpoints

These endpoints require wallet signature:

  • POST /api/vaults - Create vault
  • PATCH /api/vaults/:id - Update vault
  • POST /api/actions/:vault/:nonce/approve - Approve override
  • POST /api/webhooks - Create webhook subscription

Authentication Flow

1. Generate Message

Create a message to sign:

const message = `Sign this message to authenticate with Aegis Guardian.\n\nTimestamp: ${Date.now()}`;

2. Sign with Wallet

Sign the message with your Solana wallet:

import { Keypair } from '@solana/web3.js';
import bs58 from 'bs58';
 
const keypair = Keypair.fromSecretKey(secretKey);
const messageBytes = new TextEncoder().encode(message);
const signature = await keypair.sign(messageBytes);
const signatureBase58 = bs58.encode(signature);

3. Include in Request

Add signature to request headers:

const response = await fetch('https://aegis-guardian-production.up.railway.app/api/vaults', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Wallet-Address': keypair.publicKey.toBase58(),
    'X-Signature': signatureBase58,
    'X-Message': message,
  },
  body: JSON.stringify({
    name: 'My Vault',
    agentSigner: '...',
    dailyLimit: 1000000000,
  }),
});

Example: Complete Authentication

import { Keypair } from '@solana/web3.js';
import bs58 from 'bs58';
 
async function authenticatedRequest(
  endpoint: string,
  method: string = 'GET',
  body?: any
) {
  const keypair = Keypair.fromSecretKey(/* your secret key */);
 
  // Generate message
  const message = `Sign this message to authenticate with Aegis Guardian.\n\nTimestamp: ${Date.now()}`;
 
  // Sign message
  const messageBytes = new TextEncoder().encode(message);
  const signature = keypair.sign(messageBytes);
  const signatureBase58 = bs58.encode(signature);
 
  // Make request
  const response = await fetch(`https://aegis-guardian-production.up.railway.app${endpoint}`, {
    method,
    headers: {
      'Content-Type': 'application/json',
      'X-Wallet-Address': keypair.publicKey.toBase58(),
      'X-Signature': signatureBase58,
      'X-Message': message,
    },
    body: body ? JSON.stringify(body) : undefined,
  });
 
  if (!response.ok) {
    throw new Error(`Request failed: ${response.statusText}`);
  }
 
  return await response.json();
}
 
// Usage
const vault = await authenticatedRequest('/api/vaults', 'POST', {
  name: 'My Vault',
  agentSigner: agentPublicKey.toBase58(),
  dailyLimit: 1_000_000_000,
});

SDK Integration

The Aegis SDK handles authentication automatically:

import { AegisClient } from '@aegis-vaults/sdk';
 
const client = new AegisClient({
  cluster: 'devnet',
  guardianApiUrl: 'https://aegis-guardian-production.up.railway.app',
});
 
// SDK handles authentication
client.setWallet(keypair);
await client.createVault({...}); // Automatically signed

Security Best Practices

  1. Use HTTPS - Always use HTTPS for API requests
  2. Timestamp Messages - Include timestamp to prevent replay attacks
  3. Short-Lived Signatures - Generate new signatures for each request
  4. Secure Key Storage - Never expose private keys in client-side code
  5. Verify Signatures - Guardian verifies all signatures server-side

Next Steps