An educational demonstration of Zero Trust security principles for AI agent systems using SPIFFE/SPIRE for workload identity and Open Policy Agent (OPA) for fine-grained access control.
This demo showcases a document management system where:
- Users have department-based access rights (Engineering, Finance, Admin, HR)
- AI Agents have capability-based restrictions
- Delegation requires permission intersection (user AND agent must both have access)
- Every request is authenticated via mTLS and authorized via OPA policies
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Web Dashboard │────▶│ User Service │────▶│ Agent Service │
│ │ │ │ │ (gateway) │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
┌─────────────────┐ ┌────────▼────────┐
│ OPA Service │◀────│Document Service │
└─────────────────┘ └─────────────────┘
Agent Service discovers A2A agents from Kagenti AgentCard CRs
and proxies invocations after OPA authorization:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Agent Service │────▶│ Credential │────▶│ AWS STS │
│ (invoke) │ │ Gateway │ │ (AssumeRole) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
▼ ┌──────▼────────┐ ┌────────▼────────┐
A2A Agents │ OPA Service │ │ S3 (scoped) │
(summarizer-*, └───────────────┘ └─────────────────┘
reviewer-*)
No SPIRE required. Uses mocked identities to demonstrate the concepts.
git clone https://github.com/redhat-et/zero-trust-agent-demo.git
cd zero-trust-agent-demo
./scripts/setup-kind.sh
kubectl apply -k deploy/k8s/overlays/mock
kubectl -n spiffe-demo wait --for=condition=ready pod --all --timeout=120s
open http://localhost:8080Full SPIFFE/SPIRE integration with real X.509 SVIDs and mTLS.
git clone https://github.com/redhat-et/zero-trust-agent-demo.git
cd zero-trust-agent-demo
./scripts/setup-kind.sh
./scripts/setup-spire.sh
kubectl apply -k deploy/k8s/overlays/ghcr
kubectl apply -f deploy/spire/clusterspiffeids.yaml
kubectl -n spiffe-demo wait --for=condition=ready pod --all --timeout=120s
open http://localhost:8080See docs/DEMO_SCENARIOS.md for detailed scenarios and permission matrices.
| User | Departments | SPIFFE ID |
|---|---|---|
| Alice | Engineering, Finance | spiffe://demo.example.com/user/alice |
| Bob | Finance, Admin | spiffe://demo.example.com/user/bob |
| Carol | HR | spiffe://demo.example.com/user/carol |
Agents are discovered from Kagenti AgentCard CRs. Same agent image
can be deployed multiple times with different names and OPA scopes.
Naming scheme: {function}-{scope}.
| Agent | Scope | Description |
|---|---|---|
| summarizer-hr | hr | HR document summarizer |
| summarizer-tech | finance, engineering | Technical document summarizer |
| reviewer-ops | engineering, admin | Operations document reviewer |
| reviewer-general | all | General document reviewer |
See docs/deployment/AGENT_DEPLOYER_GUIDE.md for the full agent
deployment workflow.
- Direct User Access: Alice accesses Engineering Roadmap → ✅ ALLOWED
- Agent Without Delegation: reviewer-general accesses Finance Report → ❌ DENIED (no user context)
- Delegated Access: Alice delegates to summarizer-tech for Engineering doc → ✅ ALLOWED
- Permission Reduction: Alice delegates to summarizer-hr for Engineering doc → ❌ DENIED (summarizer-hr lacks engineering)
- Cross-scope: Carol delegates to summarizer-hr for HR doc → ✅ ALLOWED (both have hr)
The credential gateway extends the permission intersection model to external services. It translates JWT delegation claims into scoped AWS STS credentials:
Effective S3 Access = User Departments ∩ Agent Capabilities → STS Session Policy
| Scenario | Intersection | S3 Prefixes Accessible |
|---|---|---|
| Alice + summarizer-tech | {engineering, finance} | engineering/*, finance/* |
| Alice + summarizer-hr | {} (empty) | None (403 Denied) |
| Carol + summarizer-hr | {hr} | hr/* |
| Bob + reviewer-ops | {admin} | admin/* |
Run the interactive demo:
oc port-forward -n spiffe-demo svc/credential-gateway 8090:8080 &
./scripts/demo-credential-gateway.sh- Cryptographic Workload Identity: SPIFFE IDs backed by X.509 certificates
- Verified Workload Identity: Every service-to-service call carries cryptographic identity proof (mTLS or signed JWT)
- Policy-Based Access Control: OPA evaluates Rego policies on every request
- Permission Intersection: Agent access = User permissions ∩ Agent capabilities
- Agents Cannot Act Autonomously: Agents MUST have user delegation context
- Short-Lived Credentials: SVIDs have 1-hour TTLs and auto-rotate
- Scoped External Credentials: AWS STS session policies enforce permission intersection natively
See docs/README.md for the full documentation index.
| Document | Description |
|---|---|
| Demo Scenarios | Permission matrices and walkthrough scenarios |
| Policy Reference | OPA policy design, modules, and examples |
| Learning Guide | Deep dive into Zero Trust, SPIFFE/SPIRE, mTLS, and OPA |
| API Testing | API endpoints and curl commands for testing |
| Architecture | System design and component overview |
| Document | Description |
|---|---|
| Security | Threat model, trust boundaries, incident response |
| Operations | Deployment, monitoring, troubleshooting runbook |
| ADR | Title |
|---|---|
| ADR-0001 | SPIFFE/SPIRE for Workload Identity |
| ADR-0002 | Permission Intersection for AI Agent Delegation |
| ADR-0003 | OPA for Policy Evaluation |
| ADR-0004 | Kustomize for Deployment Variants |
| ADR-0005 | Separate Health Ports for mTLS Services |
| ADR-0006 | S3 Document Storage |
| ADR-0009 | OpenTelemetry Token Visualization |
| ADR-0010 | RFC 8693 Act Claim Chaining |
| Document | Description |
|---|---|
| Contributing | Guidelines for contributors |
| OpenShift vs Kubernetes | Platform comparison |
Want to modify the code? See CONTRIBUTING.md for guidelines.
git clone https://github.com/redhat-et/zero-trust-agent-demo.git
cd zero-trust-agent-demo
# Build all services
make build
# Run locally (without Kubernetes)
./scripts/run-local.sh
# Open dashboard
open http://localhost:8080make build # Build all services
make run-local # Run services locally
make test # Run tests
make test-policies # Run OPA policy tests
make setup-kind # Create Kind cluster
make deploy-k8s # Deploy to Kubernetes
make help # Show all commandszero-trust-agent-demo/
├── pkg/ # Shared packages
│ ├── config/ # Viper configuration
│ ├── logger/ # slog-based colored logger
│ ├── metrics/ # Prometheus metrics
│ └── spiffe/ # SPIFFE workload client
├── opa-service/ # Policy evaluation service
├── document-service/ # Protected resource server
├── user-service/ # User workload simulation
├── agent-service/ # Agent gateway: discovery + A2A invoke
├── web-dashboard/ # Interactive demo UI
├── credential-gateway/ # JWT → scoped AWS credentials
├── summarizer-service/ # Go A2A summarizer agent
├── reviewer-service/ # Go A2A reviewer agent
├── kagenti-summarizer/ # Python A2A summarizer agent
├── kagenti-reviewer/ # Python A2A reviewer agent
├── sample-documents/ # Markdown docs with YAML front matter
├── deploy/ # Deployment configurations
│ ├── kind/ # Kind cluster config
│ ├── k8s/ # Kustomize base and overlays
│ │ ├── base/ # Shared K8s resources
│ │ └── overlays/ # mock, local, ghcr, openshift
│ └── spire/ # SPIRE Helm values and registrations
├── docs/ # Documentation
│ ├── adr/ # Architecture Decision Records
│ ├── deployment/ # Platform-specific guides
│ ├── dev/ # Development process docs
│ ├── ARCHITECTURE.md # System design
│ ├── SECURITY.md # Security documentation
│ └── OPERATIONS.md # Operations runbook
├── scripts/ # Deployment scripts
└── Makefile # Build and run commands
- Languages: Go 1.25 (infrastructure services), Python 3.12 (A2A agents)
- CLI/Config: Cobra + Viper
- Logging:
log/slogwith colored output - Policy Engine: Open Policy Agent (OPA) with Rego
- Identity: SPIFFE/SPIRE (mock mode for local dev)
- Agent Protocol: A2A (Google a2a-python SDK)
- Agent Lifecycle: Kagenti operator (AgentCard discovery, SPIFFE binding)
- Deployment: Kind (local), OpenShift (production)
- CI/CD: GitHub Actions with multi-arch builds (amd64/arm64)
- Styling: Red Hat Design System