API Authentication
REST API authentication is opt-in. When theAGTOS_API_KEY environment variable is set, all /api/* endpoints require a Bearer token.
/healthand sub-paths — for monitoring and health checks/metrics— for Prometheus scraping/api/credentials— localhost-only, needed during onboarding
crypto.timingSafeEqual to prevent timing attacks.
Rate Limiting
All API endpoints are rate-limited using a token bucket algorithm per client IP:| Scope | Default | Config Variable |
|---|---|---|
General API (/api/*) | 100 req/min | API_RATE_LIMIT |
| Chat, Tasks, Credentials | 20 req/min | CHAT_RATE_LIMIT |
X-RateLimit-Remaining). Exceeded requests receive 429 Too Many Requests.
Credential Encryption
API keys for cloud providers (Claude, OpenAI, OpenRouter) are encrypted at rest using AES-256-GCM:- Algorithm: AES-256-GCM (authenticated encryption)
- Key derivation: PBKDF2 with 100,000 iterations
- Salt: Configurable via
AGTOS_CREDENTIAL_SALT(hex-encoded 16 bytes) - IV: Random 16 bytes per encryption
In development, a default secret is used and the salt is randomized per restart. In production, set both
AGTOS_CREDENTIAL_SECRET and AGTOS_CREDENTIAL_SALT for persistent encrypted credential storage.Device Authentication
Hardware devices (ESP32, browsers) authenticate using per-device shared secrets. The secret is hashed with SHA-256 before storage — the plaintext is never persisted. Devices progress through a trust lifecycle:| Trust Level | Value | Meaning |
|---|---|---|
| Anonymous | 0 | No authentication |
| Basic | 1 | API key authenticated |
| Verified | 2 | Device-specific secret provided |
| Trusted | 3 | Verified + established history |
Input Validation
All POST endpoints validate input with Zod schemas:- Text limits: Chat messages max 10,000 characters, memory questions max 2,000 characters
- Body size: Request bodies capped at 1 MB
- ID format: Path parameter IDs must match
^[a-zA-Z0-9\-_]+$(1-128 characters) - Type safety: All fields are type-checked with constraints (min/max, enums, patterns)
400 Bad Request with field-level error details.
Network Security
CORS
Cross-Origin Resource Sharing is configured viaCORS_ORIGIN:
tauri://localhost, https://tauri.localhost) are always included automatically.
Credential Storage Endpoint
POST /api/credentials is localhost-only — requests from non-loopback addresses receive 403 Forbidden. This ensures API keys can only be stored from the same machine during onboarding.
mDNS
mDNS device discovery is opt-in (AGTOS_MDNS_ENABLED=false by default). When enabled, agtOS broadcasts its presence on the local network for zero-config ESP32 discovery. Disable in untrusted network environments.
Data Privacy
- BYOK (Bring Your Own Key) — agtOS never stores or transmits your API keys to any third party. Keys are encrypted locally and used only for direct API calls to the providers you configure.
- Local-first — all processing (voice, memory, scheduling) runs on your machine. Cloud providers receive only the messages you send to them.
- Memory controls — configurable retention period (default 30 days), per-user privacy settings, and explicit delete APIs.
- No telemetry — agtOS does not collect usage data, analytics, or crash reports.
Production Checklist
Set credential encryption secrets
Set
AGTOS_CREDENTIAL_SECRET and AGTOS_CREDENTIAL_SALT for persistent credential storage across restarts.