Security & Compliance
SPIFFE identity, Sigstore, Cedar policies, audit trail
Security and Compliance Guide
This guide covers the security architecture, access control, guardrails, credential management, audit trail, and compliance mappings of the Enterprise Agentic AI Platform.
Security Architecture Overview
The platform treats every agent as an untrusted workload. This zero-trust posture is enforced through three layered authorization mechanisms:
- RBAC -- Platform roles (
consumer,builder,admin) gate access to apps and API endpoints. Enforced byservices/api-gateway/src/middleware/auth-middleware.ts. - ABAC / Cedar Policies -- Attribute-based policies evaluate principals, actions, resources, and conditions with default-deny and forbid-overrides-permit semantics. Engine:
services/api-gateway/src/lib/policy-engine.ts. - IBAC (SPIFFE) -- Every agent receives a cryptographic SPIFFE identity (SVID). Agent-to-agent calls are authenticated via mTLS or JWT-SVIDs. Middleware:
services/api-gateway/src/middleware/spiffe-middleware.ts.
A request must pass all applicable layers before it is allowed.
Agent Identity (SPIFFE/SPIRE)
How SVIDs Work
Each agent is issued a SPIFFE Verifiable Identity Document (SVID) by the SPIRE server with a 15-minute TTL (default_x509_svid_ttl = "900s" in infra/spire/server.conf), auto-rotated before expiry. The SPIRE agent exposes a Workload API socket at /run/spire/sockets/agent.sock (see infra/spire/agent.conf).
Identity Format
Agent: spiffe://agentic-platform/tenant/{tenantId}/agent/{agentId}
Service: spiffe://agentic-platform/platform/{serviceName}
n8n: spiffe://agentic-platform/agents/n8n/{workflowId}
The SPIFFE middleware parses all three formats using SPIFFE_ID_PATTERN, SPIFFE_PLATFORM_PATTERN, and SPIFFE_N8N_AGENT_PATTERN.
n8n Identity Injector Sidecar
n8n workflows cannot request SVIDs directly. The identity-injector sidecar (spiffe://agentic-platform/platform/n8n-runtime) issues JWT-SVIDs on their behalf, validated by checking the sub/spiffe_id claim, issuer, and expiration.
SVID Renewal and Monitoring
The SPIFFE validator (services/api-gateway/src/lib/spiffe-validator.ts) tracks SVID states: valid, expiring (within 10 min of expiry), expired, and revoked. Admins can revoke SVIDs via revokeAgentIdentity() and view all states via getIdentityInventory().
Register agents with SPIRE using infra/spire/register-agents.sh:
./infra/spire/register-agents.sh tenant-1 agent-1 # specific agent
./infra/spire/register-agents.sh # all dev entries
4-Dimension Access Control
All four dimensions are default-deny. Full details and Cedar examples in docs/ACCESS_CONTROL.md.
Dimension 1: User to Agent
Controls agent visibility via public, restricted, or private settings. Enforcement at API Gateway (L1) filters server-side -- no client-side filtering. Groups come from IdP via SCIM 2.0, JIT, or bundled Keycloak.
Dimension 2: Agent to Tool
Explicit tool allowlist per agent. The check in services/api-gateway/src/middleware/tool-grant-check.ts evaluates: embedded grants, DB tool_grants table, Tool Set grants, per-tool conditions (Redis rate limits, time windows, HITL), and a Cedar PDP overlay. Tools are risk-classified (low/medium/high/critical).
Dimension 3: Agent to Agent
Bilateral authorization: source must list target in canInvoke AND target must list source in invocableBy. Enforced by services/api-gateway/src/middleware/interaction-policy-check.ts with self-invocation prevention, delegation depth cap (5), status checks, and capability attenuation (child's effective permissions = intersection of parent's and child's grants, per services/api-gateway/src/lib/capability-attenuation.ts).
Dimension 4: Agent to Model
Model Access PEP (services/api-gateway/src/middleware/model-access-pep.ts) checks denied models, allowed models/tags (eu-hosted, open-source), cost caps, and Cedar policy. Denied models trigger automatic fallback to a configured alternative.
Default-Deny Enforcement
The Cedar engine uses strict fail-closed behavior: unrecognized scopes, policy types, and conditions all return false. No matching policy means access denied.
Cedar Policy Authoring
Policy Record Structure
Policies in the policies table contain: name, type (entitlement, tool-access, interaction, model-access), scope, priority (lower = higher), conditions (JSON or raw Cedar DSL), actions, and status.
Common Patterns
Permit group access to restricted agents:
permit(principal, action == Action::"chat", resource)
when { resource.visibility == "restricted" &&
principal.groups.containsAny(resource.allowed_groups) };
Block privilege escalation (assistive cannot invoke autonomous):
forbid(principal, action == Action::"delegate", resource)
when { principal.risk_classification == "assistive" &&
resource.risk_classification == "autonomous" };
EU data sovereignty (deny external models for a tenant):
forbid(principal, action == Action::"model:invoke", resource)
when { context.tenantId == "government-agency" &&
resource.isExternallyHosted == true };
Policy Testing
Test before activation via the simulator:
POST /api/admin/access/simulate
Body: { dimension, principalId, action, resourceId }
Returns: { allowed, reason, matchedPolicies[] }
The engine returns full diagnostics showing matched policies and condition results.
Input/Output Guardrails
Engine: services/api-gateway/src/lib/guardrails.ts.
Input Guardrails (checkInputGuardrails())
- PII Detection -- Emails, phone numbers, SSNs (
critical), credit cards (critical), IBANs, passports, IPs. - Prompt Injection -- System prompt overrides, role switching, extraction attempts, encoding bypasses.
- Jailbreak Prevention -- DAN-style attacks, developer mode activation, hypothetical bypasses.
- Toxicity -- Violent and abusive language patterns.
Content is blocked on critical triggers, or high triggers when blockOnHighSeverity is true (default).
Output Guardrails (checkOutputGuardrails())
- PII Leak Prevention -- Same patterns applied to agent output.
- Hallucination Detection (EU AI Act Art. 15) -- Fabricated references, confidence hedging density, self-contradictions.
- Toxicity -- Applied to generated content.
PII in guardrail events is redacted via redactPII() before database storage (GDPR Art. 5(1)(c)).
Per-Agent Configuration
{ inputPolicies: ['pii-detection', 'prompt-injection', 'jailbreak'],
outputPolicies: ['pii-detection', 'toxicity', 'hallucination'],
blockOnHighSeverity: true }
Code execution agents also pass through services/api-gateway/src/lib/code-scan-guardrails.ts for pre-sandbox scanning of shell escapes and dangerous imports.
Credential Management
Implementation: services/api-gateway/src/lib/credential-resolver.ts.
5-Tier Resolution Hierarchy
| Tier | Source | Description |
|---|---|---|
| 0 | HashiCorp Vault | Vault KV v2 at platform/credentials/{tenantId}/{type} |
| 1 | User BYOK | Per-user bring-your-own-key (BYOK types and OAuth) |
| 2 | Agent Override | Per-agent credential override |
| 3 | Tenant Default | Tenant-level shared credential |
| 4 | Environment | Platform-global fallback (env vars) |
Encryption
AES-256-GCM with a 32-byte key from CREDENTIAL_ENCRYPTION_KEY env var. Each credential gets a unique 16-byte IV. The GCM auth tag provides integrity verification.
OAuth and API Keys
OAuth tokens auto-refresh when expiring within 5 minutes; failures notify the user via WebSocket. API keys use ak_* prefix, stored as SHA-256 hashes -- raw keys are never persisted.
Audit Trail
Tamper-Proof Log
The audit_events and guardrail_events tables are protected by PostgreSQL triggers preventing UPDATE and DELETE (SOC 2 CC7.2):
-- services/api-gateway/src/db/migrations/0010_audit_events_immutability.sql
CREATE TRIGGER audit_events_immutable
BEFORE UPDATE OR DELETE ON audit_events
FOR EACH ROW EXECUTE FUNCTION prevent_audit_modification();
What Gets Logged
Each audit event records: agentId, tenantId, action, outcome (allow/deny), riskLevel, dimension (1-4), reasoning, principalId, resourceId, policyId, and timestamp.
Behavioral Baselines
Rolling statistical baselines (services/api-gateway/src/lib/behavioral-baselines.ts) detect anomalies via sigma thresholds: 1-sigma = info, 2-sigma = warning, 3-sigma = critical. Tracked: latency, token usage, cost, error rate, tool call count.
Memory Audit Log
The memory_audit_log table records all memory operations (create, read, update, delete, consolidate, export, gdpr-forget) with actor and user context for GDPR compliance.
Compliance Frameworks
Compliance posture tracked via compliance_snapshots table with per-framework scores and trends.
EU AI Act
| Article | Requirement | Implementation |
|---|---|---|
| Art. 9 | Risk management | 3-tier risk classification (assistive/semi-autonomous/autonomous) |
| Art. 13 | Transparency | Tool calls and reasoning visible in chat; HITL flows |
| Art. 14 | Human oversight | HITL gateway for high-risk tools and delegations |
| Art. 15 | Accuracy | Hallucination detection in output guardrails |
NIST AI RMF
- Govern -- Cedar policies, RBAC, tenant isolation
- Map -- Agent/tool/model risk classification
- Measure -- Behavioral baselines, eval suite, compliance scoring
- Manage -- Guardrails, HITL, SVID revocation, agent suspension
ISO 42001
Policy management (Cedar PDP), risk assessment (4-dimension access control), performance evaluation (baselines, anomaly detection), improvement (compliance trend tracking).
GDPR
| Article | Requirement | Implementation |
|---|---|---|
| Art. 5(1)(c) | Data minimization | PII redaction in guardrail event storage |
| Art. 15 | Right of access | DSAR export via dsar_requests table |
| Art. 17 | Right to erasure | DSAR forget requests, gdpr-forget memory action |
| Art. 25 | Privacy by design | AES-256-GCM encryption, credential tier isolation |
| Art. 30 | Processing records | Memory audit log |
DSAR requests (dsar_requests table) support export and forget types with status tracking (pending/in-progress/completed/failed).
Production Security Checklist
Identity and Authentication
- External IdP configured per tenant (Keycloak, Azure AD, or OIDC)
- SCIM 2.0 sync enabled for group provisioning
- JWT validation enabled (not mock auth headers)
- Role-based token TTLs configured (admin shortest-lived)
SPIFFE/SPIRE
- SPIRE server on production backend (PostgreSQL, not SQLite)
-
insecure_bootstrap = falsein agent config - UpstreamAuthority configured (e.g.,
aws_pcaordisk) -
TRUST_AGENT_HEADERSset tofalse - SVID monitoring alerts for expiring/expired states
Access Control
- All four dimensions configured for every agent
- No wildcard
*grants in production - Tool risk levels reviewed and assigned
- Interaction topology reviewed for privilege escalation
- Model access policies set for data-sovereign tenants
- Policies tested via simulator endpoint
Guardrails
- Input guardrails enabled (
pii-detection,prompt-injection,jailbreak) - Output guardrails enabled (
pii-detection,toxicity,hallucination) -
blockOnHighSeverityset totrue - Seccomp profiles applied to sandbox pods
Credentials
-
CREDENTIAL_ENCRYPTION_KEYgenerated and stored securely - HashiCorp Vault deployed for Tier 0 resolution
- OAuth refresh flow tested end-to-end
- API keys use expiration dates
Audit and Compliance
- Immutability triggers applied (
0010_audit_events_immutability.sql) - DSAR workflow tested (export and forget paths)
- Memory audit logging enabled
- Behavioral baseline alerting active
- Audit event archival strategy defined
Network and Infrastructure
- TLS at ingress, database, and Redis connections
- SPIRE agent socket not exposed outside the node
- Kubernetes network policies restrict inter-pod communication
- Container images scanned for vulnerabilities