Skip to content
GitLab

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.

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.

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
}
ClaimPurpose
subUnique user identifier
emailUser email for display and notifications
tenant_idTenant isolation — every downstream query is scoped to this tenant
teamsTeam memberships for access control on confidential and restricted products
rolesPlatform roles for RBAC enforcement
data_classification_clearanceMaximum data classification level this user can access

The CLI supports two authentication methods:

Terminal window
# Method 1: Login with an API token
akili auth login <token>
# Method 2: Check current auth status
akili auth status
# Method 3: Retrieve raw token for scripting
akili auth token

Tokens are stored in ~/.config/akili/config.toml under the active profile. The CLI never stores passwords.

Authorization is enforced at the service layer using JWT claims. There is no separate authorization service — the JWT carries all necessary permission data.

RolePermissions
viewerRead products, query serving endpoints
developerCreate and update products, manage connections
deployerDeploy products, trigger executions
adminTenant management, user management, governance configuration
platform_adminCross-tenant operations (platform-level only)

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:

governance.yaml
access:
teams:
- finance
- analytics
deny:
- field-ops

When a user queries a product with column-level classification, columns above their clearance are automatically masked:

ColumnClassificationUser Clearance: internal
customer_segmentbusiness.internalVisible
country_codepublicVisible
emailpii.contactMasked (****)
customer_idpii.identifierMasked (****)

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
SourceDestinationPortsPurpose
akili-platformakili-data9030, 8181, 9092API to StarRocks, Lakekeeper, Redpanda
akili-platformakili-infra5432API to PostgreSQL
akili-computeakili-data9030, 8181, 9092, 80Dagster to data services + Ceph
traefikakili-platform3000, 8080Ingress to Portal and API
Default**Deny all (zero-trust baseline)

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

Akili uses Bitnami Sealed Secrets for GitOps-compatible secret management:

  1. Secrets are encrypted with the cluster’s public key using kubeseal
  2. The encrypted SealedSecret YAML is committed to Git
  3. The Sealed Secrets controller decrypts them in-cluster
  4. Only the in-cluster controller can decrypt — even with Git access, secrets are safe
Terminal window
# Encrypt a secret for the cluster
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
# Commit the sealed secret to Git
git add sealed-secret.yaml && git commit -m "Add database credentials"

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

The platform follows a strict policy on sensitive data:

Data TypeStorage Policy
User passwordsNever stored — delegated to Authentik
API tokensStored only in user’s local config file
Connection credentialsKubernetes secrets only — never in DB
Infrastructure tokensBFF server-side only — never sent to browser

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.