Security Architecture
This document describes the security architecture of the Octomil platform. It covers how identity, authorization, tenant isolation, key management, and auditing work together to protect federated learning workloads where sensitive data never leaves edge devices.
Architecture Overview
The security model is organized in four layers. Each layer operates independently so that a compromise in one layer does not automatically grant access to another.
Identity and Access
- User auth: passkeys/OAuth or enterprise SSO
- Device auth: short-lived device access tokens + refresh tokens
- Authorization: org-scoped RBAC (
owner,admin,member) and scoped API/device tokens
API Authentication Flow
All API requests must include a valid credential. The server validates credentials in this order:
- Bearer token: Extracted from the
Authorizationheader. The server validates the token signature, expiry, and organization scope. Used by dashboard sessions and SDK clients. - API key: Extracted from the
X-API-Keyheader. The server validates the key and looks up the corresponding org and scopes. Used for server-to-server integrations. - Device token: Extracted from the
Authorizationheader with a device identifier. The server validates the token and checks that the device is registered and active. Used by mobile and edge SDKs.
If no valid credential is found, the server returns 401 Unauthorized. If the credential is valid but the user lacks permission for the requested resource, the server returns 403 Forbidden.
Device Authentication Flow
Device authentication uses a two-phase flow to avoid embedding long-lived secrets on untrusted hardware. See Device Token Lifecycle for the full flow.
- Bootstrap phase: The backend (trusted) calls Octomil with an org API key to obtain a short-lived bootstrap token. This token is passed to the device through a secure channel (e.g., app provisioning, QR code, MDM push).
- Exchange phase: The device SDK sends the bootstrap token to
/api/v1/device-auth/bootstrap. The server validates the token, registers the device, and returns an access token + refresh token pair. - Operational phase: The device uses the access token for all API calls. When the access token expires, the SDK transparently refreshes it using the refresh token.
Token Lifecycle Overview
| Token Type | Issued By | TTL | Refresh | Revocable |
|---|---|---|---|---|
| User session token | Auth service | Configurable | Via session cookie | Yes, via logout or admin revoke |
| API key | Admin via dashboard | No expiry (rotate manually) | N/A | Yes, via dashboard or API |
| Device bootstrap token | Backend service | Short-lived | No | Yes, single-use |
| Device access token | Octomil server | Short-lived (configurable) | Via refresh token | Yes, via SDK or admin |
| Device refresh token | Octomil server | Long-lived (configurable) | On use (rotated) | Yes, via SDK or admin |
RBAC Roles and Scopes
| Role | Scope | Capabilities |
|---|---|---|
owner | Full | All operations including billing, workspace deletion, member management |
admin | Management | Device management, model uploads, experiment creation, member invites |
member | Operational | View dashboard, submit training updates, view models and experiments |
Scoped API tokens can further restrict access. For example, a token with devices:read scope can list devices but cannot register new ones. Scopes are enforced at the router level.
Tenant Isolation
- Resource access is org-boundary enforced at API layer
- Cross-tenant reads/writes are denied by org checks and role gates
How Tenant Isolation Works
Every resource query is automatically scoped to the caller's organization. The org_id is extracted from the authenticated token and injected into every database query at the service layer — not just the API layer. There is no API endpoint that accepts org_id as a request parameter; it always comes from the token. This prevents parameter tampering.
Cross-Tenant Protection
- Model artifacts are stored under org-specific prefixes with access controls
- All database records are scoped to the owning organization
- Background jobs validate organization ownership before processing
Key Material and Secrets
- Backend API keys remain server-side only
- Device bootstrap token is short-lived and exchanged for device auth session
- Secrets are stored in deployment secret manager (never in client apps)
Secret Storage by Environment
| Secret | Development | Production |
|---|---|---|
| JWT signing key | Auto-generated fallback | Secret manager |
| Database credentials | Local config (gitignored) | Secret manager |
| Storage credentials | Local config (gitignored) | Cloud IAM role |
| Third-party API keys | Local config (gitignored) | Secret manager |
In production, the server reads secrets from environment variables injected by the deployment platform. Secrets are never logged, never included in error responses, and never stored in the database.
Key Rotation
- JWT signing keys: Rotate quarterly. The server supports graceful key rotation with no downtime.
- API keys: Rotate on compromise or quarterly. Use the dashboard to generate a new key and deprecate the old one.
- Database credentials: Rotate via your deployment platform's secret rotation mechanism.
Network Security
TLS
All traffic between clients and the Octomil API is encrypted with TLS 1.2 or higher. The platform enforces HTTPS and returns HSTS headers.
- Client-to-API: TLS terminated at the load balancer
- API-to-database: TLS enforced on all database connections
- API-to-storage: HTTPS enforced for all object storage operations
Rate Limiting
Rate limiting is enforced per-org and per-IP to prevent abuse. Limits vary by endpoint category, with stricter limits on authentication endpoints and more permissive limits on training data submission. Rate limit responses include Retry-After headers.