Security
API authentication
Section titled “API authentication”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.
Planned: Clerk auth
Section titled “Planned: Clerk auth”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).
Webhook signing
Section titled “Webhook signing”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.
D1 encryption
Section titled “D1 encryption”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.
Input validation
Section titled “Input validation”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.
Transport security
Section titled “Transport security”- 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.
Reporting vulnerabilities
Section titled “Reporting vulnerabilities”If you discover a security issue, please report it to [email protected]. Do not open a public issue.