Daevix Docs

Security Model

Open as Markdown

Daevix's security posture, principles, trust boundaries, and built-in platform guarantees.

Security Model

Core Posture: Never Trust the Agent

The platform treats the agent process as untrusted. This is not a pessimistic assumption - it is the only correct assumption, because:

  1. The agent might not be ours - Operators can run any agent code (BYOA). The platform cannot guarantee what’s running inside the container.
  2. The agent could modify itself - Depending on its access level, an agent may alter its own binary, configuration, or behavior. Even without admin rights, it may find ways to act outside its intended scope.
  3. The agent acts autonomously - It makes decisions that are not fully predictable by the operator.
  4. LLMs can be manipulated - Prompt injection, jailbreaking, and adversarial inputs are real risks that can cause agents to take unintended actions.

Therefore, all security controls exist outside the agent process, at layers the agent cannot subvert (or at least, where subversion is detectable).

Principles

Authenticate at Every Boundary

Every component-to-component interaction requires authentication:

FlowMechanism
Agent → EnclavePlatform JWT (ES256, 5-minute lifetime)
Agent → LLM proxyNetproxy-forwarded identity (service-signed headers) or platform JWT - see Agent identity
Enclave → Control PlaneAPI key (SHA-256 hashed)
Operator (dvx CLI) → Control Plane APIOperator JWT (IAM-issued)

No component accepts unauthenticated requests for state-changing operations. The only unauthenticated endpoint is GET /v1/agent/discover (read-only enclave capabilities).

Defense in Depth

No single control is sufficient. Daevix layers network controls, host controls, platform controls, and (optionally) agent-level controls. A failure at one layer should be caught by the next.

Least Privilege

  • Agents receive only the credentials they need (scoped secrets, short-lived JWTs).
  • Kubernetes agents run as non-root (UID 1000) with automountServiceAccountToken: false.
  • NetworkPolicy restricts agent egress to DNS, the enclave, the proxy, and the public internet - no east-west traffic to private services.
  • The enclave cannot run database migrations. Only the control plane can.

Secrets Never at Rest in Plaintext

  • All tokens (bootstrap, refresh, enclave API keys) are stored as SHA-256 hex digests. The database never sees raw tokens.
  • Agent secrets are encrypted with AES-256-GCM (random 12-byte nonce, prepended to ciphertext). Decrypted only during delivery to the agent.

Fail Closed

  • Missing or invalid authentication → 401.
  • CIDR mismatch → 403.
  • Token replay → revoke the entire token family + 409.
  • Unknown errors → generic 500 to the client, real error logged server-side.
  • No fallback to insecure modes in production.

Four Control Layers

Daevix uses a defense-in-depth model with four layers of security controls, each enforced at a level the agent cannot easily bypass.

Layer 1: Network Controls

Network controls restrict what the agent can reach. These are enforced by the organization’s network infrastructure - firewalls, load balancers, and cloud security groups.

ControlDescription
Egress filteringAgents can only reach services they need. A K8s deployment agent doesn’t need access to the email server.
TLS inspectionOrganizations can use TLS-intercepting proxies to inspect agent traffic, using corporate CA certificates baked into the base image.
DNS filteringBlock access to known-bad domains, restrict to approved services.
Network segmentationAgent hosts placed in a dedicated network segment with its own rules, separate from production and employee workstations.

In Kubernetes deployments, Daevix enforces network isolation per agent via NetworkPolicy. Each agent namespace gets a policy (agent-isolation) that:

  • Denies all ingress
  • Allows egress to DNS (port 53)
  • Allows egress to the enclave (ports 8444/8445)
  • Allows egress to the internet (excluding private ranges 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)

Layer 2: Host Controls

Agent hosts should have the same security controls as any managed endpoint in the organization.

ControlDescription
EDRCrowdStrike, SentinelOne, Wazuh, etc. Detects malicious behavior, provides response capabilities.
Audit loggingauditd capturing syscalls, process execution, file access, network connections. Shipped to SIEM.
File integrity monitoringDetect unexpected changes to critical files (including the agent binary itself).
Mandatory access controlsSELinux or AppArmor profiles to limit what the agent process can do, even with root access.
Immutable infrastructureAgents can run on read-only root filesystems with writable scratch space, making persistent compromise harder.

In Kubernetes, agent pods run with a restricted security context:

  • runAsNonRoot: true
  • UID/GID 1000
  • automountServiceAccountToken: false
  • fsGroup: 1000

Layer 3: Platform Controls

Controls provided natively by Daevix at the platform level.

ControlDescription
Identity revocationInstantly revoke all agent credentials, rendering it unable to authenticate to any service.
Credential scopingExternal identities scoped to minimum required permissions. An agent gets the IAM role it needs, not admin.
Audit trailComplete record of agent creation, bootstrap, credential issuance, rotation, and revocation.
Token hashingAll tokens (bootstrap, refresh) stored as SHA-256 digests. The database never sees raw tokens.
Secrets encryptionAgent secrets encrypted at rest with AES-256-GCM. Decrypted only during bootstrap/renewal.
CIDR-bound JWTsOptional IP binding that prevents token use from outside the agent’s network. See IP Binding.
Short-lived agent identityAgents authenticate with enclave-issued platform JWTs (ES256, 5-minute lifetime); agents reaching the LLM proxy through the netproxy are identified by service-signed headers. See Agent identity.
Refresh token familiesFamily-based rotation with replay detection. Reusing an old refresh token revokes the entire family.
JTI blacklistingOptional Redis-backed instant JWT revocation. Without Redis, revocation takes up to 5 minutes (token expiry).
LLM content inspectionContent security pipeline inspects all LLM traffic for PII, API key leaks, secret exposure, and custom patterns. Policies cascade Platform > Org > Agent with immutable floors. See LLM Content Policy.
Model restrictionAllowlist or blocklist which LLM models agents can use. Enforced at the proxy before the request reaches the upstream provider.
Execution-time policy engineThree-layer architecture (inspectors → policy engine → enforcers) evaluates tool calls from LLM responses against operator-defined policies. Supports allow, deny, alert, and require_approval actions. Both LLM proxy and network proxy share the same inspection library and policy engine.
Approval workflowTool calls matching require_approval policies enter an escalation-tier workflow. Tiers progress from LLM Judge auto-resolution to human approval by an operator (dvx policy approvals). Per-agent and org-wide limits prevent approval queue flooding. Approvals are scoped via canonicalized tool call hashing.
Fail-closed policy cacheWhen the execution-time policy cache is cold or stale and the database is unreachable, all actions are denied by default. Operators can configure fail-open as an org-wide setting (requires org:manage permission and compensating controls acknowledgment). Every fail-open event is logged at WARN level.
Kill switchThe enclave can terminate agent compute immediately, without waiting for graceful shutdown (dvx agent isolate).

Layer 4: Agent-Level Controls (Platform Runtime Only)

If the agent uses the platform-provided runtime, additional controls are available. These are explicitly best-effort - they run inside the agent’s trust boundary and could be bypassed by a modified agent.

ControlDescription
Tool call inspectionAll tool calls logged with arguments and results. Operators can set alert policies.
LLM API proxyRoute LLM calls through the platform proxy for logging and spend control enforcement.
Human-in-the-loop gatesCertain tool calls can require operator approval before execution.
Behavioral policiesRules like “never commit directly to main” enforced at the tool level.

Token Security

Platform JWTs

  • Algorithm: ES256 (ECDSA P-256) - algorithm confusion attacks are rejected
  • Lifetime: 5 minutes
  • Subject: agent:<id>
  • Issued by the enclave, not the control plane
  • Optionally CIDR-bound to the agent’s network

Agent identity

An agent’s identity is its short-lived platform JWT, issued by the enclave at bootstrap and rotated continuously (ES256, 5-minute lifetime). There are two paths by which an agent’s identity reaches the LLM proxy:

  1. Netproxy-forwarded identity. When agent traffic flows through the network proxy (the default for managed agents), the netproxy attaches a service-signed X-Dvx-Service-Authorization header alongside X-Dvx-* identity headers. The LLM proxy verifies the service signature cryptographically and trusts the identity it carries. This is the path the default Claude Code agent uses, and it’s how an agent can forward its own upstream LLM credentials while the platform still tracks who it is.
  2. Platform JWT (direct). Agents that talk to the LLM proxy directly present their enclave-issued platform JWT via Authorization: Bearer … or the Anthropic-style x-api-key header.

A note on mTLS. Earlier versions identified agents to the LLM proxy with short-lived mTLS client certificates. That path was removed - long-lived agent connections don’t re-read a rotating client certificate, so 5-minute certs broke mid-session, and carrying a third auth path added complexity for no benefit. Service-to-service mTLS between platform components (enclave, control plane, relay) is unaffected.

Bootstrap Tokens

  • Random 32 bytes
  • SHA-256 hashed before storage
  • 1-hour expiry
  • Single-use - burned on first exchange
  • Plaintext returned once on creation, never stored

Refresh Tokens

  • 24-hour lifetime
  • Single-use with family-based rotation
  • SHA-256 hashed before storage
  • Replay detection: reusing an old token from the same family revokes the entire family
  • Used to obtain new platform JWT + new refresh token

Platform Security Guarantees

These properties are built into the codebase. Operators benefit from them without additional configuration.

JWT Algorithm Restriction

All JWT validators enforce ES256 only. Algorithm confusion attacks (e.g., accepting none or HS256 with a public key as the signing secret) are rejected at the library level. Both operator JWTs and platform JWTs go through the same strict validation: signature verification, issuer, audience, and expiration checks.

Platform JWT validation in HTTP contexts additionally enforces CIDR binding when the client_cidr claim is present (see IP Binding).

Tenant Isolation

Every API query is scoped by organization_id extracted from the caller’s JWT. The platform never trusts organization identity from request bodies - it always uses the cryptographically verified value from the token. There is no API path that can return data across organizations.

This holds for IAM administration as well. The control plane exposes an operator-facing IAM-management surface (/api/v1/iam/*) that can mutate IAM data - accounts, organizations, RBAC role assignments, and OAuth2 clients - making it a second writer to the IAM tables (which dvx iam otherwise owns). Every such operation is gated by RBAC (members:*, org:manage, clients:manage) and is strictly org-scoped from the operator JWT claims - no route accepts a client-supplied organization id, including for platform-admin. A leaked operator token can therefore only ever touch its own tenant’s IAM data. The control plane and IAM already share one database and trust domain, so this write boundary stays inside an existing trust domain rather than crossing a new one.

SQL Injection Prevention

All database queries are generated by sqlc as parameterized statements with type-safe Go bindings. No SQL is constructed by string concatenation anywhere in the codebase.

Error Masking

All API error responses use RFC 9457 Problem Details (application/problem+json). Internal details - stack traces, SQL errors, file paths - are never exposed to clients. Errors are logged server-side with full context for debugging, while clients receive sanitized messages.

Cryptographic Randomness

All security-sensitive random values (tokens, nonces, CSRF tokens) are generated using cryptographically secure sources (crypto/rand in Go, crypto.getRandomValues() in the browser).

Logging Hygiene

The platform uses structured logging and enforces a strict boundary: security-relevant events (authentication outcomes, status transitions, token lifecycle) are logged, while sensitive values (raw tokens, plaintext secrets, database credentials, private keys) are never written to logs.

Audit Trail Integrity

Daevix uses a tombstone pattern (soft deletes) for data deletion - no security-relevant data is hard-deleted. Tables have a deleted_at column, and all read queries filter on active records. This preserves a complete audit trail of agent creation, credential issuance, and lifecycle transitions.