Security
ExtractForm follows security best practices for authentication, data handling, and webhook delivery.
Authentication
- Bearer tokens only — no cookie-based auth
- Access tokens expire after 15 minutes (configurable)
- Refresh tokens rotate on each use; old sessions are revoked
- API keys are hashed at rest; plaintext shown only once at creation
- Auth endpoints are rate-limited (5 requests/min for login/register)
API keys
- Prefix:
ef_live_(configurable viaAPI_KEY_PREFIX) - Store keys as secrets — never commit to version control
- Revoke immediately if compromised via
DELETE /api/auth/api-keys/:id - Keys inherit user role and cannot exceed account permissions
- Optional expiration date per key
Webhook security
- All outbound webhooks are signed with HMAC-SHA256
- Signing secrets encrypted at rest with
WEBHOOK_ENCRYPTION_KEY - Verify signatures using the raw request body
- Reject timestamps older than 5 minutes to prevent replay
- Use
X-Webhook-Idfor idempotent processing
OAuth token storage
Integration OAuth tokens (Google Drive, Dropbox) are encrypted at rest using WEBHOOK_ENCRYPTION_KEY. Never expose tokens in API responses.
Production checklist
| Item | Action |
|---|---|
JWT_ACCESS_SECRET | Set a strong random value (not changeme) |
WEBHOOK_ENCRYPTION_KEY | 64 hex characters (32 bytes) |
| HTTPS | Terminate TLS at your reverse proxy |
| CORS | Restrict CORS_ORIGINS to your frontend domain |
| API keys | Use per-environment keys with minimal scope |
| File uploads | Configure MAX_FILE_SIZE appropriately |
| Database | Use authenticated MongoDB in production |
Data handling
- Documents are stored in local filesystem or S3-compatible storage
- Extractions are stored in MongoDB linked to the owning user
- Jobs are scoped to the authenticated user — cross-user access returns
404 - Soft-delete patterns used for API keys and webhook endpoints
Reporting issues
Report security vulnerabilities privately via your project's designated contact channel. Do not open public issues for security bugs.