Security Architecture
Akili enforces security at every layer — authentication at the API gateway, claims-based authorization in the service layer, network segmentation between namespaces, and sealed secrets for credential management. The platform follows a zero-trust model where every request is verified, every connection is encrypted, and every credential is scoped to the minimum required access.
Authentication
Section titled “Authentication”OIDC with Authentik
Section titled “OIDC with Authentik”Akili uses Authentik as the identity provider, implementing the OpenID Connect (OIDC) authorization code flow.
%%{init: {'sequence': {'mirrorActors': false, 'messageMargin': 40}}}%%
sequenceDiagram
participant User as Developer
participant Portal as Portal (Next.js)
participant Auth as Authentik (OIDC)
participant API as Control Plane API
User->>Portal: Access portal
Portal->>Auth: Redirect to OIDC login
Auth->>Auth: Authenticate user
Auth->>Portal: Authorization code
Portal->>Auth: Exchange code for tokens
Auth->>Portal: ID token + access token
Portal->>API: API request with Bearer token
API->>API: Validate JWT, extract claims
API->>Portal: Response (tenant-scoped)
The Portal uses NextAuth v5 for session management. All API calls from the Portal route through the Next.js BFF (Backend for Frontend) layer, which attaches the access token to outgoing requests. Infrastructure credentials (ArgoCD, Prometheus) never reach the browser.
JWT Claims
Section titled “JWT Claims”Every authenticated request carries a JWT with these claims:
{ "sub": "user-uuid-123", "email": "developer@example.com", "tenant_id": "550e8400-e29b-41d4-a716-446655440000", "teams": ["data-engineering", "analytics"], "roles": ["developer", "deployer"], "data_classification_clearance": "confidential", "iat": 1710590400, "exp": 1710594000}| Claim | Purpose |
|---|---|
sub | Unique user identifier |
email | User email for display and notifications |
tenant_id | Tenant isolation — every downstream query is scoped to this tenant |
teams | Team memberships for access control on confidential and restricted products |
roles | Platform roles for RBAC enforcement |
data_classification_clearance | Maximum data classification level this user can access |
CLI Authentication
Section titled “CLI Authentication”The CLI supports two authentication methods:
# Method 1: Login with an API tokenakili auth login <token>
# Method 2: Check current auth statusakili auth status
# Method 3: Retrieve raw token for scriptingakili auth tokenTokens are stored in ~/.config/akili/config.toml under the active profile. The CLI never stores passwords.
Authorization
Section titled “Authorization”Claims-Based RBAC
Section titled “Claims-Based RBAC”Authorization is enforced at the service layer using JWT claims. There is no separate authorization service — the JWT carries all necessary permission data.
| Role | Permissions |
|---|---|
viewer | Read products, query serving endpoints |
developer | Create and update products, manage connections |
deployer | Deploy products, trigger executions |
admin | Tenant management, user management, governance configuration |
platform_admin | Cross-tenant operations (platform-level only) |
Classification-Based Access Control
Section titled “Classification-Based Access Control”Data access is further restricted by classification clearance:
User clearance: confidential
Can access: - public products (public < confidential) - internal products (internal < confidential) - confidential products (confidential = confidential)
Cannot access: - restricted products (restricted > confidential)For confidential and restricted products, the user must also be a member of an explicitly granted team:
access: teams: - finance - analytics deny: - field-opsColumn-Level Masking
Section titled “Column-Level Masking”When a user queries a product with column-level classification, columns above their clearance are automatically masked:
| Column | Classification | User Clearance: internal |
|---|---|---|
customer_segment | business.internal | Visible |
country_code | public | Visible |
email | pii.contact | Masked (****) |
customer_id | pii.identifier | Masked (****) |
Network Security
Section titled “Network Security”Namespace Isolation
Section titled “Namespace Isolation”The platform uses Kubernetes network policies to enforce namespace-level isolation:
%%{init: {'flowchart': {'curve': 'basis'}}}%%
flowchart TB
subgraph akili-platform["akili-platform namespace"]
API[Control Plane API]
PORTAL[Portal]
end
subgraph akili-data["akili-data namespace"]
SR[StarRocks]
LK[Lakekeeper]
RP[Redpanda]
end
subgraph akili-compute["akili-compute namespace"]
DAGSTER[Dagster]
JOBS[Compute Jobs]
end
subgraph akili-infra["akili-infra namespace"]
PG[PostgreSQL]
CEPH[Ceph RGW]
end
API --> SR
API --> PG
DAGSTER --> SR
DAGSTER --> LK
DAGSTER --> RP
DAGSTER --> CEPH
PORTAL --> API
Network Policy Rules
Section titled “Network Policy Rules”| Source | Destination | Ports | Purpose |
|---|---|---|---|
akili-platform | akili-data | 9030, 8181, 9092 | API to StarRocks, Lakekeeper, Redpanda |
akili-platform | akili-infra | 5432 | API to PostgreSQL |
akili-compute | akili-data | 9030, 8181, 9092, 80 | Dagster to data services + Ceph |
traefik | akili-platform | 3000, 8080 | Ingress to Portal and API |
| Default | * | * | Deny all (zero-trust baseline) |
TLS Everywhere
Section titled “TLS Everywhere”All inter-service communication uses TLS:
- External ingress: TLS termination at Traefik with Let’s Encrypt certificates (cert-manager)
- Internal services: mTLS between namespaces via service mesh or direct TLS configuration
- Database connections: TLS required for PostgreSQL connections
- Event bus: TLS for Redpanda client connections
Secrets Management
Section titled “Secrets Management”Sealed Secrets
Section titled “Sealed Secrets”Akili uses Bitnami Sealed Secrets for GitOps-compatible secret management:
- Secrets are encrypted with the cluster’s public key using
kubeseal - The encrypted SealedSecret YAML is committed to Git
- The Sealed Secrets controller decrypts them in-cluster
- Only the in-cluster controller can decrypt — even with Git access, secrets are safe
# Encrypt a secret for the clusterkubeseal --format yaml < secret.yaml > sealed-secret.yaml
# Commit the sealed secret to Gitgit add sealed-secret.yaml && git commit -m "Add database credentials"Credential Rotation
Section titled “Credential Rotation”Connection credentials are stored as Kubernetes secrets and referenced by connection name:
- Credentials are never stored in manifests or the control plane database
- Connection test (
akili connection test) verifies credentials are valid - Rotation requires updating the Kubernetes secret and resealing
What Is Never Stored
Section titled “What Is Never Stored”The platform follows a strict policy on sensitive data:
| Data Type | Storage Policy |
|---|---|
| User passwords | Never stored — delegated to Authentik |
| API tokens | Stored only in user’s local config file |
| Connection credentials | Kubernetes secrets only — never in DB |
| Infrastructure tokens | BFF server-side only — never sent to browser |
Audit Trail
Section titled “Audit Trail”Every security-relevant action is logged to the audit trail:
- Authentication events (login, logout, token refresh)
- Authorization failures (access denied, classification violation)
- Data mutations (create, update, delete)
- Governance actions (deletion requests, retention changes)
- Administrative operations (tenant creation, role changes)
Audit records include tenant_id, user_id, action, resource, timestamp, and correlation_id. The audit log is append-only and exempt from retention policies.
Related
Section titled “Related”- Multi-Tenancy — tenant isolation model
- Governance Model — classification and access control
- System Architecture — platform layers and components