Skip to content

Security

All API requests (except GET /health) require an API key:

Authorization: Bearer <your-api-key>

API keys are:

  • Created and managed in the dashboard.
  • Scoped to a single project.
  • Transmitted over HTTPS only.
  • Revocable at any time.

User-facing authentication (dashboard, hosted form management) will use Clerk for:

  • Email/password and social login
  • Session management
  • Organization-based multi-tenancy

API keys will remain the primary auth mechanism for programmatic access (CLI, SDK, agent integration).

Webhooks are signed with HMAC-SHA256 to verify they originated from AgentsForms:

X-AgentsForms-Signature: sha256=<hmac-hex-digest>

How to verify:

import { createHmac, timingSafeEqual } from 'node:crypto';
function verifySignature(
payload: string, // Raw request body
signature: string, // X-AgentsForms-Signature header
secret: string // Secret from webhook registration
): boolean {
const expected = `sha256=${createHmac('sha256', secret).update(payload).digest('hex')}`;
try {
return timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
} catch {
return false;
}
}

Best practices:

  • Use timingSafeEqual (or equivalent) to prevent timing attacks.
  • Store the webhook secret in an environment variable, never in code.
  • Rotate secrets periodically.

Cloudflare D1 encrypts data:

  • At rest: AES-256 encryption via Cloudflare’s infrastructure.
  • In transit: TLS 1.3 for all client ↔ API and API ↔ D1 connections.
  • Backups: Point-in-time recovery with encrypted snapshots.

Form definitions are validated with Zod schemas before storage:

  • Field id: regex-restricted to [a-zA-Z0-9_.-] with max 64 chars.
  • Field count: capped at 100 to prevent unbounded storage.
  • Slug: regex-restricted to [a-z0-9][a-z0-9-]{0,62}[a-z0-9].
  • All strings sanitized for length constraints.

API responses never reflect raw database errors — they are caught and returned as structured internal_error responses.

  • All endpoints require HTTPS (TLS 1.3 minimum).
  • HTTP requests are automatically redirected to HTTPS by Cloudflare.
  • HSTS is enabled with a 1-year max-age.

If you discover a security issue, please report it to [email protected]. Do not open a public issue.