Zero-Auth · Agent Signing · Replay Protection
AUTONOMOUS.ML operates on the principle that the enterprise network perimeter is the security boundary. There is no login wall and no external identity provider. Security is enforced at the agent-to-agent communication layer using HMAC-SHA256 message signing with runtime-rotatable secrets.
Zero External Identity Provider
No external OAuth portal in the critical path. The dashboard authenticates locally against the enterprise perimeter — operators already authenticated to the corporate network are not forced through a third-party identity provider that could be unreachable. Agent-to-agent communication is separately secured by HMAC-SHA256 signing over TLS 1.3.
Agent-to-Agent HMAC-SHA256 Signing
Every inter-agent API call carries three headers: x-agent-id (identity claim), x-agent-timestamp (Unix ms), and x-agent-signature (HMAC-SHA256 hex digest). The receiving agent verifies the signature before processing the request. An unsigned or incorrectly signed message is rejected with HTTP 401.
±30-Second Replay Window
The agentProcedure middleware rejects any message whose x-agent-timestamp is more than 30 seconds in the past or more than 5 seconds in the future. A valid signature on a stale message is still rejected — the timestamp is part of the signed payload.
Runtime Secret Rotation
The system.rotateAgentSecret tRPC mutation rotates the HMAC signing secret at runtime without restarting any process. It requires a valid agent signature on the rotation request itself (agentProcedure), so only a currently-trusted agent can trigger rotation. If no new secret is provided, a 48-byte cryptographically random hex string is generated automatically.
Agent-to-Agent Request Lifecycle
JSON.stringify({ agentId, timestamp: Date.now(), input })
HMAC-SHA256(payload, AGENT_SECRET) → 64-char hex digest
x-agent-id, x-agent-timestamp, x-agent-signature
TLS 1.3 (minimum) or mTLS for mutual authentication — HMAC provides payload integrity on top of transport encryption
Read x-agent-id, x-agent-timestamp, x-agent-signature
Reject if |now − timestamp| > 30 000 ms
HMAC-SHA256(reconstructed-payload, AGENT_SECRET)
crypto.timingSafeEqual(expected, received) — prevents timing attacks
Match → process request. Mismatch → 401 UNAUTHORIZED
Attack Surface Analysis
Every identified threat vector and its mitigation status. Threats marked ELIMINATED have been removed from the attack surface entirely; MITIGATED threats have active countermeasures that reduce risk to acceptable levels.
| Threat | Attack Vector | Mitigation | Severity | Status |
|---|---|---|---|---|
| Agent Impersonation | Rogue process sends requests claiming to be a trusted agent | HMAC signature — cannot forge without AGENT_SECRET | HIGH | MITIGATED |
| Message Tampering | Man-in-the-middle modifies payload in transit | HMAC covers the full payload — any modification invalidates the signature | HIGH | MITIGATED |
| Replay Attack | Captured valid message replayed after the original transaction | ±30s timestamp window — replays outside the window are rejected | MEDIUM | MITIGATED |
| Secret Compromise | AGENT_SECRET leaked via log, coredump, or insider threat | Runtime rotation via system.rotateAgentSecret — immediate invalidation | HIGH | MITIGATED |
| External Identity Provider Outage | OAuth portal unreachable — operators locked out | No external IdP in the critical path — local enterprise perimeter authentication only | CRITICAL | ELIMINATED |
| Network Eavesdropping | Passive tap on agent-to-agent traffic captures payload contents | TLS 1.3 minimum on all agent connections; mTLS recommended for mutual certificate verification | HIGH | MITIGATED |
| Timing Attack on Signature Comparison | Measure response time to infer correct signature bytes | crypto.timingSafeEqual() — constant-time comparison regardless of match position | LOW | MITIGATED |
| Brute-Force Secret Discovery | Enumerate HMAC outputs to recover the secret | 48-byte (384-bit) random secret — computationally infeasible to brute-force | LOW | MITIGATED |
| Unauthorised Secret Rotation | Attacker rotates secret to lock out legitimate agents | rotateAgentSecret requires agentProcedure — valid HMAC signature required to rotate | HIGH | MITIGATED |
Code Examples
import { buildAgentHeaders } from "./server/_core/agentSigning";
// Build signed headers for an outgoing agent-to-agent call
const headers = buildAgentHeaders("agent-host-01", {
action: "claimWorkItem",
workItemId: 4821,
});
// headers = {
// "x-agent-id": "agent-host-01",
// "x-agent-timestamp": "1741234567890",
// "x-agent-signature": "a3f9c2e1...64 hex chars",
// }
await fetch("/api/trpc/system.rotateAgentSecret", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ json: { newSecret: undefined } }),
});// In server/_core/trpc.ts — the middleware runs automatically
// on any procedure declared with agentProcedure
const requireAgentSignature = t.middleware(async ({ ctx, next }) => {
const { "x-agent-signature": sig, "x-agent-id": agentId,
"x-agent-timestamp": timestamp } = ctx.req.headers;
if (!sig || !agentId || !timestamp)
throw new TRPCError({ code: "UNAUTHORIZED", message: "Missing headers" });
const body = ctx.req.body ? JSON.stringify(ctx.req.body) : "";
const payload = JSON.stringify({ agentId, timestamp, body });
if (!verifyAgentSignature(payload, sig as string))
throw new TRPCError({ code: "UNAUTHORIZED", message: "Invalid signature" });
const age = Date.now() - parseInt(timestamp as string, 10);
if (age > 30_000 || age < -5_000)
throw new TRPCError({ code: "UNAUTHORIZED", message: "Timestamp out of window" });
return next({ ctx: { ...ctx, agentId } });
});
export const agentProcedure = t.procedure.use(requireAgentSignature);// Rotate the signing secret — callable by any trusted agent
// A new 48-byte random secret is generated if newSecret is omitted
const result = await trpc.system.rotateAgentSecret.mutate(
{ newSecret: undefined }, // auto-generate
{ headers: buildAgentHeaders("agent-host-01", {}) }
);
// result = {
// success: true,
// rotatedAt: "2026-03-02T15:43:00.000Z",
// secretLength: 96, // 48 bytes → 96 hex chars
// newSecret: "a3f9c2e1...", // distribute securely to peer agents
// }
// All signatures made with the OLD secret are now invalid.
// Peer agents must be updated with the new secret before
// they can make further agentProcedure calls.Required Environment Variables
| Variable | Purpose | Default |
|---|---|---|
| AGENT_SECRET | Primary HMAC signing secret for agent-to-agent communication. Rotate on schedule or after suspected compromise. | Falls back to JWT_SECRET |
| JWT_SECRET | Fallback signing secret if AGENT_SECRET is not set. Also used for any internal JWT operations. | Required |
Production Recommendation
Set AGENT_SECRET to a minimum 48-byte (96 hex character) random value generated with openssl rand -hex 48. Do not reuse the JWT_SECRET as the agent signing secret in production — use separate secrets for separate security domains. Rotate AGENT_SECRET at least every 90 days, or immediately after any suspected compromise.
Security Perimeter Model
Self-Provisioning TLS Certificate Lifecycle
AUTONOMOUS.ML ships a fully self-contained X.509 certificate authority. No external CA, no Let's Encrypt dependency, no manual OpenSSL commands. Omni provisions, rotates, and revokes certificates autonomously — operators interact through the TLS Certificates tab in the Omni Command Centre.
Root CA
A 2048-bit RSA self-signed root CA is generated on first use and stored in the database. It signs all leaf certificates. The private key is never returned over the API — it exists only in the server process memory and the database row.
Leaf Certificates
Each agent receives a dedicated leaf certificate signed by the root CA. The certificate encodes the agent's Common Name (CN), Subject Alternative Names (SANs), and a unique serial number. The private key is stored encrypted alongside the certificate.
Autonomous Rotation
The rotation scheduler runs every hour. Any certificate whose expiry is within the configured rotation window (default: 30 days) is automatically rotated — a new key pair and certificate are generated, the old certificate is revoked, and the new one is stored. No operator action required.
Provisioning Options
Every certificate is provisioned through the cert.provision tRPC mutation. The following parameters control the certificate's identity, validity, and rotation behaviour.
| Parameter | Type | Default | Description |
|---|---|---|---|
| commonName | string (required) | — | Certificate Common Name (CN). Typically the agent's fully-qualified hostname, e.g. agent.emea.autonomous.ml. |
| sans | string[] | [] | Subject Alternative Names. Accepts DNS names and IPv4 addresses. IPv4 addresses are automatically encoded as IP SANs; everything else is treated as a DNS SAN. |
| agentId | string? | undefined | Optional agent identifier stored alongside the certificate for inventory filtering. Does not affect the certificate itself. |
| validityDays | number | 365 | Certificate validity period in days. Maximum 3650 (10 years). For agent-to-agent mTLS, 365 days with 30-day rotation is recommended. |
| autoRotate | boolean | true | Whether the autonomous rotation scheduler should renew this certificate when it enters the rotation window. Set to false for certificates managed by an external process. |
| rotationDays | number | 30 | How many days before expiry the rotation scheduler triggers renewal. Must be less than validityDays. Recommended: 30 days for 365-day certs, 90 days for 3-year certs. |
Certificate Lifecycle States
Certificate is valid and within its validity period. The rotation window has not yet been reached.
Certificate is within the rotation window (default: 30 days before expiry). The scheduler will rotate it on the next hourly check.
Certificate has passed its notAfter date. Auto-rotation failed or was disabled. Agents using this certificate will fail mTLS handshakes.
Certificate has been explicitly revoked by an operator or superseded by a rotation. It should be removed from all agent trust stores immediately.
Autonomous Rotation Algorithm
The rotation scheduler runs on a configurable interval (default: 1 hour). On each tick, it executes the following algorithm atomically per certificate.
Query all certificates with status active or expiring_soon where autoRotate = true.
For each certificate, compute daysUntilExpiry = (notAfter - now) / 86400000. If daysUntilExpiry ≤ rotationDays, proceed to rotation.
Generate a fresh 2048-bit RSA key pair using the Node.js Web Crypto API (SubtleCrypto.generateKey). The old key is not reused.
Sign a new X.509 certificate with the root CA. The new certificate inherits the same CN, SANs, agentId, validityDays, autoRotate, and rotationDays as the original.
INSERT the new certificate row with status = active. The new serial number is unique (crypto.randomUUID()).
UPDATE the old certificate row: status = revoked, autoRotate = false. The old PEM and key remain in the database for audit purposes.
Emit a cert_rotated WebSocket event to all connected Omni Command Centre clients so the TLS Certificates tab updates in real time.
Deployment Options
The certificate management system supports three deployment models depending on the enterprise's existing PKI posture.
Standalone Internal CA
Default- Zero external dependencies
- Works fully air-gapped
- Omni manages the entire lifecycle
- No operator PKI knowledge required
- Root CA not trusted by OS/browser by default
- Must distribute root CA PEM to all agent trust stores
- No CRL/OCSP distribution point
Recommended for greenfield deployments, air-gapped environments, and development/staging.
Subordinate CA
Enterprise- Leaf certs trusted by enterprise PKI chain
- CRL/OCSP handled by enterprise CA
- Compliant with corporate certificate policy
- Requires enterprise CA administrator to sign the AUTONOMOUS.ML intermediate CA CSR
- More complex initial setup
Recommended when the enterprise already operates a Microsoft AD CS, HashiCorp Vault PKI, or EJBCA instance.
Bring Your Own Certificates
Advanced- Full control over certificate parameters
- Can use HSM-backed keys
- Compatible with any CA
- Autonomous rotation disabled (autoRotate = false)
- Operator responsible for renewal and distribution
- No Omni-managed lifecycle
Recommended when certificates are issued by a hardware security module (HSM) or a regulated CA that requires manual approval.
Configuring mTLS Between Agents
Mutual TLS (mTLS) requires both the client agent and the server agent to present and verify certificates. The following steps configure mTLS using certificates provisioned through Omni.
// Load certificate and key from Omni DB
const cert = await getCert(agentCertId);
// Configure HTTPS server with mTLS
const server = https.createServer({
cert: cert.pemCert,
key: cert.pemKey,
ca: rootCaPem, // Root CA PEM from Omni
requestCert: true, // Require client cert
rejectUnauthorized: true // Reject unknown CAs
}, app);// Load client certificate from Omni DB
const clientCert = await getCert(clientCertId);
// Configure HTTPS agent with client cert
const agent = new https.Agent({
cert: clientCert.pemCert,
key: clientCert.pemKey,
ca: rootCaPem, // Trust the same root CA
});
// Use in fetch / axios / got
fetch(targetUrl, { agent });Recommended TLS Configuration
| Parameter | Recommended Value | Rationale |
|---|---|---|
| TLS version | TLS 1.3 minimum | TLS 1.2 is acceptable but TLS 1.3 eliminates the RSA key exchange and removes weak cipher suites entirely. |
| Cipher suites | TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 | Both provide authenticated encryption (AEAD). AES-256-GCM is hardware-accelerated on modern CPUs; ChaCha20 is preferred on CPUs without AES-NI. |
| Key type | RSA-2048 (current) or ECDSA P-256 (future) | RSA-2048 is NIST-approved through 2030. ECDSA P-256 provides equivalent security with smaller keys and faster handshakes. |
| Certificate validity | 365 days with 30-day rotation window | Short validity limits the blast radius of a compromised certificate. 30-day rotation window provides a buffer for rotation failures. |
| requestCert | true (mTLS) | Requiring a client certificate prevents any unauthenticated process on the network from reaching agent APIs, even if it has network access. |
| rejectUnauthorized | true | Certificates not signed by the AUTONOMOUS.ML root CA (or the enterprise intermediate CA) are rejected. Prevents MITM via rogue internal CA. |
7-Layer Security Architecture
AUTONOMOUS.ML implements a defense-in-depth strategy across seven concentric security layers. Each layer is independently hardened and assumes the layers outside it may be compromised. Controls at each layer are mapped to NIST SP 800-53, ISO 27001, SOC 2 Type II, and PCI DSS.
┌─────────────────────────────────────────────────────────────────┐ │ LAYER 7 — PHYSICAL (Datacenter access, supply chain) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ LAYER 6 — IDENTITY (MFA, RBAC, PAM, Zero Trust) │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ LAYER 5 — DATA (AES-256, DLP, backup, HMAC) │ │ │ │ │ │ ┌───────────────────────────────────────────────┐ │ │ │ │ │ │ │ LAYER 4 — APPLICATION (SAST, DAST, secrets) │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────┐ │ │ │ │ │ │ │ │ │ LAYER 3 — HOST (EDR, hardening, patch) │ │ │ │ │ │ │ │ │ │ ┌───────────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ LAYER 2 — NETWORK (VPN, IDS/IPS) │ │ │ │ │ │ │ │ │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ LAYER 1 — PERIMETER │ │ │ │ │ │ │ │ │ │ │ │ │ │ (Firewall, WAF, DDoS) │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌───────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ AGENT HOST + AI │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ (Protected Core) │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └───────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ └───────────────────────────────────┘ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘
Perimeter Layer
NIST AC-17, SC-7 · ISO 27001 A.13.1 · SOC 2 CC6.6
Stateful packet inspection with application-layer filtering. Block all inbound traffic except explicitly whitelisted ports. Egress filtering to prevent data exfiltration.
OWASP Core Rule Set v3.3+ for the OCC web interface. Block SQLi, XSS, CSRF, path traversal, and HTTP request smuggling. Rate limiting per IP.
Layer 3/4 volumetric attack mitigation at the network edge. Layer 7 application-layer DDoS protection for the OCC API endpoint.
Network Layer
NIST SC-7, SI-4 · ISO 27001 A.13.1, A.13.2 · SOC 2 CC6.6, CC7.2
Agent Host, AI Decision Module, and Azure DevOps integration each reside in separate VLANs. Inter-VLAN traffic is explicitly permitted only on required ports.
Operator access to the OCC requires VPN or ZTNA client. Split-tunnelling disabled to prevent lateral movement from compromised operator workstations.
Suricata or Snort with AUTONOMOUS.ML-specific rules for anomalous agent communication patterns, unexpected outbound connections, and HMAC replay attempts.
Host Layer
NIST SI-2, CM-6 · ISO 27001 A.12.6 · SOC 2 CC7.1
CIS Benchmark Level 2 for Windows Server 2022 (Agent Host) and RHEL 9 (AI inference nodes). Disable unused services, enforce AppLocker/SELinux policies, remove default accounts.
Microsoft Defender for Endpoint or CrowdStrike Falcon on all agent nodes. Real-time behavioural monitoring, memory scanning, and automated isolation on detection.
Critical patches applied within 72 hours of release. Agent Host .NET runtime updated within 30 days of security releases. Automated patch compliance reporting.
Application Layer
NIST SA-11, SI-10 · ISO 27001 A.14.2 · SOC 2 CC8.1
SonarQube or Semgrep on every pull request. CodeQL for .NET Agent Host. Zero high/critical findings policy before merge. Results published to security dashboard.
OWASP ZAP automated scan against OCC staging environment on every release. Burp Suite Enterprise for quarterly deep scans. API fuzzing via RESTler.
Dependabot or Snyk for all npm and NuGet dependencies. License compliance check (GPL contamination prevention). Transitive dependency graph analysis.
Azure Key Vault for production. HashiCorp Vault for on-premises. No secrets in environment variables, config files, or source code. Automated secret rotation every 90 days.
Data Layer
NIST SC-28, CP-9 · ISO 27001 A.10.1, A.12.3 · SOC 2 A1.2
AES-256-GCM for all database fields containing agent configuration, system prompts, and audit logs. BitLocker/LUKS full-disk encryption on all agent nodes.
TLS 1.3 minimum for all agent-to-agent and agent-to-OCC communication. mTLS for agent-to-agent with HMAC-SHA256 payload signing as a second integrity layer.
Inspect outbound traffic for PII, credentials, and source code patterns. Block exfiltration of Azure DevOps tokens, connection strings, and model weights.
Daily encrypted backups of agent configuration, audit logs, and certificate store. RTO 4 hours, RPO 24 hours. Quarterly restore drills with documented results.
Identity Layer
NIST AC-2, AC-6, IA-2 · ISO 27001 A.9.2 · SOC 2 CC6.1, CC6.2
FIDO2/WebAuthn hardware tokens for operator access to OCC. TOTP as fallback. SMS/voice MFA explicitly prohibited. Phishing-resistant MFA required for admin accounts.
Three roles: Operator (OCC access, instruction dispatch), Admin (configuration changes, secret rotation), Auditor (read-only audit log access). Principle of least privilege enforced.
Just-in-time privileged access for Agent Host administration. Session recording for all privileged sessions. Automatic session termination after 30 minutes of inactivity.
Never trust, always verify. Every API call authenticated and authorised regardless of network location. Continuous validation of device health posture before granting access.
Physical Layer
NIST PE-2, PE-3, SR-3 · ISO 27001 A.11.1, A.11.2 · SOC 2 CC6.4
ISO 27001-certified datacenter with biometric access, CCTV, and 24/7 security personnel. No unescorted vendor access. Hardware asset tracking with tamper-evident seals.
Hardware sourced from approved vendors only. Firmware verified against vendor-signed manifests before deployment. SBOM (Software Bill of Materials) maintained for all agent node software.
NIST SP 800-88 media sanitisation for all decommissioned hardware. Certificate of destruction required for storage media containing agent configuration or audit logs.