Agent DocsDeveloper documentation
Admin Guide

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:

  1. RBAC -- Platform roles (consumer, builder, admin) gate access to apps and API endpoints. Enforced by services/api-gateway/src/middleware/auth-middleware.ts.
  2. 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.
  3. 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

TierSourceDescription
0HashiCorp VaultVault KV v2 at platform/credentials/{tenantId}/{type}
1User BYOKPer-user bring-your-own-key (BYOK types and OAuth)
2Agent OverridePer-agent credential override
3Tenant DefaultTenant-level shared credential
4EnvironmentPlatform-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

ArticleRequirementImplementation
Art. 9Risk management3-tier risk classification (assistive/semi-autonomous/autonomous)
Art. 13TransparencyTool calls and reasoning visible in chat; HITL flows
Art. 14Human oversightHITL gateway for high-risk tools and delegations
Art. 15AccuracyHallucination 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

ArticleRequirementImplementation
Art. 5(1)(c)Data minimizationPII redaction in guardrail event storage
Art. 15Right of accessDSAR export via dsar_requests table
Art. 17Right to erasureDSAR forget requests, gdpr-forget memory action
Art. 25Privacy by designAES-256-GCM encryption, credential tier isolation
Art. 30Processing recordsMemory 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 = false in agent config
  • UpstreamAuthority configured (e.g., aws_pca or disk)
  • TRUST_AGENT_HEADERS set to false
  • 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)
  • blockOnHighSeverity set to true
  • Seccomp profiles applied to sandbox pods

Credentials

  • CREDENTIAL_ENCRYPTION_KEY generated 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