Agent Security Model

Overview

Agents are trusted components that execute deployment tasks on targets. Their security model ensures:

Agent Registration Flow

Implementation note (2026-05-09): the implemented HTTP control plane uses POST /api/v1/release-orchestrator/agents/registration-tokens for the operator-created one-time token and POST /api/v1/release-orchestrator/agents to consume that token. The local compose path is devops/compose/scripts/launch-agent-core.ps1: it reuses existing local enrollment material when present, otherwise calls the bootstrap script to create the token, register the agent, and write the issued PEM bundle to ignored local files. It then starts the agent-core service through the canonical compose chain and waits for a heartbeat. Use agent-bootstrap.ps1 -NoComposeUp or the Bash bootstrap with --no-compose-up only when another installer owns process launch. The older conceptual /api/v1/agents/register and agent JWT-token steps below are retained as product direction, not the current implemented endpoint shape. Registration is fail-closed: the internal CA must issue the client certificate before release.agents receives an active agent row, and the store writes the active row plus public certificate PEM in one operation.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    AGENT REGISTRATION FLOW                                  │
│                                                                             │
│  1. Admin generates registration token (one-time use)                       │
│     POST /api/v1/admin/agent-tokens                                        │
│     Response: { token: "reg_xxx", expiresAt: "..." }                       │
│                                                                             │
│  2. Agent starts with registration token                                    │
│     ./stella-agent --register --token=reg_xxx                              │
│                                                                             │
│  3. Agent requests mTLS certificate                                         │
│     POST /api/v1/agents/register                                           │
│     Headers: X-Registration-Token: reg_xxx                                 │
│     Body: { name, version, capabilities, csr }                             │
│     Response: { agentId, certificate, caCertificate }                      │
│                                                                             │
│  4. Agent establishes mTLS connection                                       │
│     Uses issued certificate for all subsequent requests                    │
│                                                                             │
│  5. Agent requests short-lived JWT for task execution                       │
│     POST /api/v1/agents/token (over mTLS)                                  │
│     Response: { token, expiresIn: 3600 }                                   │
│                                                                             │
│  6. Agent refreshes token before expiration                                 │
│     Token refresh only over mTLS connection                                │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

mTLS Communication

All agent-to-core communication uses mutual TLS:

┌─────────────────────────────────────────────────────────────────────────────┐
│                    AGENT COMMUNICATION SECURITY                             │
│                                                                             │
│  ┌──────────────┐                          ┌──────────────┐                │
│  │    AGENT     │                          │  STELLA CORE │                │
│  └──────┬───────┘                          └──────┬───────┘                │
│         │                                         │                         │
│         │  mTLS (mutual TLS)                      │                         │
│         │  - Agent cert signed by Stella CA       │                         │
│         │  - Server cert verified by Agent        │                         │
│         │  - TLS 1.3 only                         │                         │
│         │  - Perfect forward secrecy              │                         │
│         │◄────────────────────────────────────────►│                         │
│         │                                         │                         │
│         │  Encrypted payload                      │                         │
│         │  - Task payloads encrypted with         │                         │
│         │    agent-specific key                   │                         │
│         │  - Logs encrypted in transit            │                         │
│         │◄────────────────────────────────────────►│                         │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

TLS Requirements

Implementation note (2026-05-09): Release Orchestrator now owns a file-backed internal agent CA. FileBackedInternalAgentCa creates or loads the root PFX from ReleaseOrchestrator:AgentCertificateAuthority:RootPfxPath, writes an optional public root PEM to RootCertificatePemPath, and signs agent client certificates during registration. The agent-runtime HTTP endpoints receive the client certificate from the TLS layer and MtlsPollingAgentTaskTransport validates the presented certificate against that internal CA before accepting a poll or signed result. Kestrel may be configured to pass client certificates through without relying on OS trust via ReleaseOrchestrator:AgentCertificateAuthority:AllowTlsHandshakeClientCertificatePassThrough so the app-layer CA check is authoritative.

RequirementValue
ProtocolTLS 1.3 only
Cipher SuitesTLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256
Key ExchangeECDHE with P-384 or X25519
Certificate KeyRSA 3072-bit by default for the internal CA and issued client certs
Certificate Validity24 hours by default for issued client certs

Certificate Management

Certificate Structure

interface AgentCertificate {
  subject: {
    CN: string;        // Agent name
    O: string;         // "Stella Ops"
    OU: string;        // Tenant ID
  };
  serialNumber: string;
  issuer: string;      // Stella CA
  validFrom: DateTime;
  validTo: DateTime;
  extensions: {
    keyUsage: ["digitalSignature", "keyEncipherment"];
    extendedKeyUsage: ["clientAuth"];
    subjectAltName: string[];  // Agent ID as URI
  };
}

Certificate Renewal

Agents automatically renew certificates before expiration:

  1. Agent detects certificate expiring within 30 days
  2. Agent generates new CSR with same identity
  3. Agent submits renewal request over existing mTLS connection
  4. Authority issues new certificate
  5. Agent transitions to new certificate seamlessly

Secrets Management

Secrets are NEVER stored in the Stella database. Only vault references are stored.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    SECRETS FLOW (NEVER STORED IN DB)                        │
│                                                                             │
│  ┌──────────────┐        ┌──────────────┐        ┌──────────────┐          │
│  │    VAULT     │        │  STELLA CORE │        │    AGENT     │          │
│  │  (Source)    │        │  (Broker)    │        │  (Consumer)  │          │
│  └──────┬───────┘        └──────┬───────┘        └──────┬───────┘          │
│         │                       │                       │                   │
│         │                       │ Task requires secret  │                   │
│         │                       │                       │                   │
│         │ Fetch with service   │                       │                   │
│         │ account token        │                       │                   │
│         │◄───────────────────────                       │                   │
│         │                       │                       │                   │
│         │ Return secret        │                       │                   │
│         │ (wrapped, short TTL) │                       │                   │
│         │────────────────────────►                       │                   │
│         │                       │                       │                   │
│         │                       │ Embed in task payload │                   │
│         │                       │ (encrypted)          │                   │
│         │                       │────────────────────────►                   │
│         │                       │                       │                   │
│         │                       │                       │ Decrypt           │
│         │                       │                       │ Use for task      │
│         │                       │                       │ Discard           │
│                                                                             │
│  Rules:                                                                     │
│  - Secrets NEVER stored in Stella database                                 │
│  - Only Vault references stored                                            │
│  - Secrets fetched at execution time only                                  │
│  - Secrets not logged (masked in logs)                                     │
│  - Secrets not persisted in agent memory beyond task scope                 │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Task Security

Task Assignment

interface AgentTask {
  id: UUID;
  type: TaskType;
  targetId: UUID;
  payload: TaskPayload;
  credentials: EncryptedCredentials;  // Encrypted with agent's public key
  timeout: number;
  priority: TaskPriority;
  idempotencyKey: string;
  assignedAt: DateTime;
  expiresAt: DateTime;
}

Credential Scoping

Task credentials are:

Task Execution Isolation

Agents execute tasks with isolation:

interface TaskExecutionContext {
  // Process isolation
  workingDirectory: string;      // Unique per task
  processUser: string;           // Non-root user
  networkNamespace: string;      // If network isolation enabled

  // Resource limits
  memoryLimit: number;           // Bytes
  cpuLimit: number;              // Millicores
  diskLimit: number;             // Bytes
  networkEgress: string[];       // Allowed destinations

  // Cleanup
  cleanupOnComplete: boolean;
  cleanupTimeout: number;
}

Agent Capabilities

Agents declare capabilities that determine what tasks they can execute:

interface AgentCapabilities {
  docker?: DockerCapability;
  compose?: ComposeCapability;
  ssh?: SshCapability;
  winrm?: WinrmCapability;
  ecs?: EcsCapability;
  nomad?: NomadCapability;
}

interface DockerCapability {
  version: string;
  apiVersion: string;
  runtimes: string[];
  registryAuth: boolean;
}

interface ComposeCapability {
  version: string;
  fileFormats: string[];
}

Heartbeat Protocol

interface AgentHeartbeat {
  agentId: UUID;
  timestamp: DateTime;
  status: "healthy" | "degraded";
  resourceUsage: {
    cpuPercent: number;
    memoryPercent: number;
    diskPercent: number;
    networkRxBytes: number;
    networkTxBytes: number;
  };
  activeTaskCount: number;
  completedTasks: number;
  failedTasks: number;
  errors: string[];
  signature: string;  // HMAC of heartbeat data
}

Heartbeat Validation

  1. Verify signature matches expected HMAC
  2. Check timestamp is within acceptable skew (30s)
  3. Update agent status based on heartbeat content
  4. Trigger alerts if heartbeat missing for >90s

Agent Revocation

When an agent is compromised or decommissioned:

  1. Certificate added to CRL (Certificate Revocation List)
  2. All pending tasks for agent cancelled
  3. Agent removed from target assignments
  4. Audit event logged
  5. New agent can be registered with same name (new identity)

Security Checklist

ControlImplementation
IdentitymTLS certificates signed by internal CA
AuthenticationCertificate-based + short-lived JWT
AuthorizationTask-scoped credentials
EncryptionTLS 1.3 for transport, envelope encryption for secrets
IsolationProcess sandboxing, resource limits
AuditAll task assignments and completions logged
RevocationCRL for compromised agents
Secret handlingVault integration, no persistence

References