Skip to content

Security Implementation

dev-mondoshawan edited this page Apr 16, 2026 · 1 revision

Security Implementation

**Referenced Files in This Document** - [backend/src/services/bagsAuthVerifier.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/services/bagsAuthVerifier.js) - [backend/src/services/pkiChallenge.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/services/pkiChallenge.js) - [backend/src/middleware/rateLimit.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/middleware/rateLimit.js) - [backend/src/middleware/errorHandler.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/middleware/errorHandler.js) - [backend/src/models/queries.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/models/queries.js) - [backend/server.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/server.js)

Table of Contents

  1. Introduction
  2. Authentication
  3. Authorization
  4. Data Protection
  5. Rate Limiting
  6. Error Handling
  7. Security Headers
  8. Best Practices

Introduction

AgentID implements a comprehensive security model based on Ed25519 cryptographic signatures, challenge-response mechanisms, and defense-in-depth practices. This document details the security architecture and implementation.

Authentication

Ed25519 Signature Verification

AgentID uses Ed25519 digital signatures for all authentication:

  • Registration: Agents must sign a challenge message with their Ed25519 private key
  • Verification: PKI challenge-response uses Ed25519 signatures
  • Flagging: Flag submissions require Ed25519 signatures

Bags Authentication Wrapper

The Bags authentication flow:

  1. Initialize: Request challenge from Bags API
  2. Sign: Client signs challenge with private key
  3. Verify: Server verifies signature using tweetnacl
  4. Complete: Submit to Bags callback for API key
// Signature verification example
const nacl = require('tweetnacl');
const bs58 = require('bs58');

function verifySignature(message, signature, pubkey) {
  const messageBytes = bs58.decode(message);
  const signatureBytes = bs58.decode(signature);
  const pubkeyBytes = bs58.decode(pubkey);
  
  return nacl.sign.detached.verify(messageBytes, signatureBytes, pubkeyBytes);
}

PKI Challenge-Response

Prevents spoofing through time-bound challenges:

  1. Server generates UUID nonce and challenge string
  2. Challenge stored with expiration timestamp
  3. Client signs challenge and returns signature
  4. Server verifies signature and marks challenge complete
  5. Single-use enforcement prevents replay attacks

Authorization

Role-Based Access

Current implementation uses signature-based authorization:

  • Anyone can read public agent data
  • Only key holders can modify their agent records
  • Flag submissions require reporter's signature

Capability Verification

Agent capabilities are stored and verified:

  • Stored as JSONB in PostgreSQL
  • Validated during registration
  • Used for discovery and filtering

Data Protection

Input Validation

All inputs are validated:

  • Pubkey format (88 characters, base58)
  • Signature format (base58)
  • Required field presence
  • Data type validation

SQL Injection Prevention

Parameterized queries throughout:

// Safe - uses parameterized query
const result = await query('SELECT * FROM agents WHERE pubkey = $1', [pubkey]);

// Unsafe - never do this
const result = await query(`SELECT * FROM agents WHERE pubkey = '${pubkey}'`);

XSS Prevention

Output encoding for HTML/XML:

function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

Rate Limiting

Express-rate-limit middleware protects all endpoints:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP'
});

app.use('/api/', limiter);

Stricter limits for authentication endpoints:

  • Registration: 10 requests per 15 minutes
  • Challenge issuance: 20 requests per 15 minutes

Error Handling

Security-conscious error handling:

  • Generic error messages in production
  • Detailed logging server-side
  • No stack traces leaked to clients
  • Proper HTTP status codes
// Error handler middleware
function errorHandler(err, req, res, next) {
  console.error(err); // Log full error
  
  const status = err.status || 500;
  const message = process.env.NODE_ENV === 'production' 
    ? 'Internal server error' 
    : err.message;
  
  res.status(status).json({ error: message });
}

Security Headers

Helmet.js provides security headers:

const helmet = require('helmet');
app.use(helmet());

This enables:

  • Content Security Policy
  • X-DNS-Prefetch-Control
  • X-Frame-Options
  • Strict-Transport-Security
  • X-Download-Options
  • X-Content-Type-Options
  • X-Permitted-Cross-Domain-Policies
  • Referrer-Policy

Best Practices

Secret Management

  • Never commit secrets to version control
  • Use environment variables
  • Rotate API keys regularly
  • Use secrets management in production

HTTPS

Always use HTTPS in production:

  • TLS 1.2 or higher
  • Valid certificates
  • HSTS enabled

Monitoring

Monitor for security events:

  • Failed authentication attempts
  • Rate limit violations
  • Unusual traffic patterns
  • Error spikes

Dependencies

Keep dependencies updated:

npm audit
npm update

CORS

Restrict CORS in production:

const cors = require('cors');
app.use(cors({
  origin: process.env.CORS_ORIGIN,
  credentials: true
}));

Clone this wiki locally