Skip to content

Security Model

Paul Rigor edited this page Jun 25, 2026 · 1 revision

Security Model

Overview

ADEPT implements defense-in-depth security across three tiers: TLS termination at the reverse proxy, JWT validation at the API gateway, and fine-grained authorization at the orchestration layer. All inter-service communication uses authenticated credentials, and code execution runs in hardened sandboxes.

Authentication Flow

  1. Client sends HTTPS request to Nginx (TLS termination)
  2. Nginx forwards (plaintext internal) to Agent Gateway
  3. Agent Gateway validates JWT signature with Keycloak
  4. On success, Agent Gateway proxies request + User Context Headers to Orchestration Service
  5. Orchestration Service processes and responds

The Agent Gateway acts as a pure authentication proxy -- it validates identity but delegates all business logic to the Orchestration Service.

Authorization (RBAC)

Role-Based Access Control is enforced via Keycloak groups embedded in JWT claims:

Group Permissions
admin Full system access, user management, tool registration
gateway-service Service-to-service communication, health checks
notebook-users Standard agent interaction, file operations

Principle of Least Privilege: Users receive only the permissions required for their role. Tool access is further restricted by per-tool ACL rules beyond group membership.

Per-Tool ACL

Each registered tool specifies which groups may invoke it:

# Tool access filtered at runtime
authorized_tools = await tool_manager.get_authorized_tools(
    user_id=user.id,
    groups=user.groups  # From JWT claims
)

Users only see and can invoke tools their group membership permits.

Sandbox Security

The sandbox_mcp_server executes user-submitted code in isolated containers with multiple security layers:

Control Implementation
Container isolation Dedicated container per execution
No network access Network disabled during code execution
Resource limits CPU, memory, and time constraints enforced
Non-root execution Code runs as unprivileged user
Import restrictions Dangerous modules blocked at import time
Timeout enforcement Hard kill after configurable deadline

Code Execution Guardrails

Before execution, submitted code is analyzed for policy violations:

  • Blocked imports: os.system, subprocess, socket, network libraries
  • Filesystem restrictions: Write access limited to session-scoped temp directory
  • Resource caps: Memory ceiling and CPU time limits prevent resource exhaustion
  • Output limits: stdout/stderr truncated to prevent memory bombs

Defense in Depth: Even if code bypasses import restrictions, container-level controls (no network, resource limits, non-root) provide secondary containment.

Kernel-Level Syscall Filtering (nsjail)

For deployments requiring maximum isolation, ADEPT supports optional kernel-level syscall filtering via nsjail. When enabled, all code execution occurs inside a seccomp-BPF jail that blocks 22 dangerous system calls.

Deployment Type nsjail Setting Rationale
Exploratory research false (default) LLM-generated code needs flexible filesystem and package management
Digital twins / lab automation true Code targets physical equipment; syscall restrictions prevent unintended I/O
Classified environments true Defense-in-depth is mandatory
Multi-tenant (untrusted users) true Container isolation alone is insufficient for adversarial inputs

Security Level Configuration

Level Import Policy Use Case
strict Whitelist (approved scientific libraries only) Untrusted user code, public-facing deployments
medium (default) Blacklist (blocks known-dangerous imports) General-purpose deployments with authenticated users
permissive Same as medium HPC environments needing license-server network access

Network Egress Control

By default, sandbox containers have no external network access. Operators can selectively allowlist specific hosts and ports via a YAML configuration file validated at container startup. The allowlist uses nftables rules with Pydantic schema validation.

Response Hardening (CSP)

All responses from nginx_proxy include a Content-Security-Policy header that prevents browser-side exfiltration of sensitive model output. This blocks attacks where a model is tricked into emitting external image/script references.

Service Communication

Inter-service authentication uses OAuth2 Client Credentials flow. Service credentials are:

  • Generated during stack bootstrap
  • Stored in credential directories (not environment variables)
  • Retrieved via the SecretsManager with file-based lookup
  • Rotatable without service restart via credential regeneration

Session Isolation

User data is isolated at multiple levels:

Level Mechanism
File storage Per-session directories: data/uploaded_files/{session_id}/
Vector stores Session-scoped ChromaDB collections
Code execution Isolated containers with session-scoped filesystems
Agent state PostgreSQL checkpoints keyed by thread ID
Tool context Multi-tier session IDs propagated through all calls

Credential Management

ADEPT uses file-based secret retrieval as the default pattern:

Lookup order:
1. /run/secrets/{SECRET_NAME}    (Docker/K8s secrets mount)
2. /app/credentials/{SECRET_NAME} (Credentials directory)
3. os.getenv("{SECRET_NAME}")     (Environment variable fallback)

This approach supports Docker Compose, Kubernetes, and local development without code changes.

Clone this wiki locally