AI Agent Zero Trust Pipeline: SPIFFE/SPIRE + Cedar in Practice
Giving agents cryptographic identity without hardcoded secrets, and deterministically controlling every action through policy
Recommended background knowledge: Kubernetes Pod and ServiceAccount concepts, basic principles of mTLS. This article is optimized for backend/infrastructure engineers with cloud-native operations experience.
Environments where AI agents query databases, call external APIs, and orchestrate other agents are spreading rapidly. But as "whom" are these agents acting? Most organizations still rely on hardcoded API keys or long-lived tokens. Gartner projects that by 2028, more than 15% of enterprise work decisions will be handled by agentic AI — and it's worth considering what happens when those agents operate with unverified credentials.
Reports from HashiCorp and others in the industry show that machine identities (service accounts, API keys, bot credentials) now outnumber human identities in enterprise environments by tens of times. Publicly demonstrated PoCs (proof-of-concepts) by security researchers have shown scenarios where a jailbroken agent autonomously performs reconnaissance, credential theft, and data exfiltration.
After reading this article, you will understand a complete Zero Trust pipeline that grants AI agents a cryptographic identity (SVID) without hardcoded secrets, and deterministically controls every agent action through Cedar policies.
This article walks through, step by step, how to issue identities to agent processes using SPIFFE/SPIRE and connect them to the Cedar policy engine to form a consistent pipeline of identity verification → policy evaluation → access allow/deny.
Core Concepts
SPIFFE and SPIRE: How to Answer "Who Is This Process?"
SPIFFE (Secure Production Identity Framework For Everyone) is an open standard that assigns cryptographically verifiable identities to workloads in cloud-native environments. Instead of static secrets like API keys or passwords, the platform itself attests to "the environment in which this process is running."
SPIRE (SPIFFE Runtime Environment) is the reference implementation of this specification, composed of two components: SPIRE Server and SPIRE Agent.
┌─────────────────────────────────────────────────────┐
│ SPIRE Server │
│ - 트러스트 번들(Root CA) 관리 │
│ - 등록된 워크로드 항목 저장 │
│ - SVID 서명 및 발급 │
└──────────────────────┬──────────────────────────────┘
│ mTLS
┌──────────────────────▼──────────────────────────────┐
│ SPIRE Agent (DaemonSet) │
│ - 노드 어테스테이션 (k8s_sat / AWS IID / GCP GCE) │
│ - 워크로드 어테스테이션 (PID, k8s Service Account) │
│ - Workload API (Unix socket) 제공 │
└──────────────────────┬──────────────────────────────┘
│ Unix Socket
┌─────────────▼─────────────┐
│ AI 에이전트 프로세스 │
│ SVID 수령 및 자동 갱신 │
└───────────────────────────┘Attestation: The process of verifying a workload's identity using evidence collected from the surrounding environment. In Kubernetes environments, the
k8s_sat(Service Account Token) ork8s_psat(Projected Service Account Token) attestor is most commonly used. It directly confirms via the kubelet API whether "this Pod is genuinely running as theorchestratorservice account in theai-agentsnamespace."
SPIFFE defines the "language of identity," while SPIRE issues that identity in a real environment. Next, it's Cedar's turn to determine what is permitted using the issued identity.
SVID: Two Forms That Carry Identity
When SPIRE verifies a workload, it issues an SVID (SPIFFE Verifiable Identity Document). A SPIFFE ID is a URI in the form spiffe://trust-domain/path, expressed in two formats.
| Format | Structure | Verification Method | Suitable Environment |
|---|---|---|---|
| X.509-SVID | SPIFFE ID inserted in the SAN URI field of an X.509 certificate | Verify certificate signature with trust bundle (Root CA) | mTLS, service mesh (Istio, Envoy) |
| JWT-SVID | JWT signed by the SPIRE Server | Verify signature with SPIRE's JWKS endpoint or Workload API bundle | HTTP REST API, Authorization header |
# X.509-SVID 발급 확인
spire-agent api fetch x509 \
-socketPath /run/spire/sockets/agent.sock
# 출력 예시:
# SPIFFE ID: spiffe://prod.example.com/ns/ai-agents/sa/orchestrator
# 유효기간: 5분 (TTL 설정에 따라)
# Subject Alternative Name URI: spiffe://prod.example.com/ns/ai-agents/sa/orchestratorWhen Cedar's Policy Decision Point (PDP) receives a JWT-SVID, it verifies the signature using SPIRE's trust bundle (JWKS endpoint or Workload API bundle) and then extracts the SPIFFE ID. Only identities verified this way are used in Cedar policy evaluation.
Cedar: Policy as Code, Decisions Made Predictable
Cedar is an open-source policy language developed by AWS that expresses access control rules using the PARC model (Principal, Action, Resource, Context). Compared to OPA (Rego), its syntax is more intuitive, and it supports policy analysis, enabling detection of policy conflicts or unreachable rules at the CI stage before deployment.
// Cedar 정책의 기본 구조
permit (
principal is WorkloadIdentity, // 누가
action == Action::"invoke_model", // 무엇을
resource == ModelEndpoint::"gpt-v2" // 어디에
)
when {
principal.spiffe_id == "spiffe://prod.example.com/ns/ai-agents/sa/orchestrator"
};forbid-wins principle: In Cedar, when a
forbidand apermitrule both match,forbidalways takes precedence. The default policy is deny-all, so any request without an explicitpermitis denied.
Note that attributes like principal.spiffe_id in Cedar policies do not exist automatically. You must define the WorkloadIdentity entity type and its attributes in schema.json as shown in the practical application section below — skipping this step will cause cedar validate to return an error.
The Complete Zero Trust Pipeline Flow
SPIFFE defines the identity, SPIRE issues it, and Cedar makes decisions based on that identity. When all three layers are combined, the following flow is complete.
AI 에이전트 프로세스 기동
↓
SPIRE Agent: 워크로드 어테스테이션
(kubelet API → Pod 서비스어카운트·네임스페이스 검증)
↓
SPIRE Server: X.509-SVID 또는 JWT-SVID 발급
↓
에이전트가 SVID를 제시하며 서비스 호출
↓
Policy Decision Point (PDP)
JWT-SVID 검증(JWKS/트러스트 번들) → SPIFFE ID 추출 → Cedar 정책 평가
↓
접근 허용 or 거부 (기본: deny-all) + 결정 로깅Practical Application
Example 1: Kubernetes AI Agent Pipeline — From SPIRE Configuration to mTLS
This is a scenario for deploying an AI inference server (vLLM, Triton, etc.) and an orchestration agent on Kubernetes. We deploy the SPIRE Agent as a DaemonSet, issue an SVID to the agent Pod, and establish mTLS with the model serving server.
Step 1: Define the Cedar Schema
To use principal.spiffe_id in Cedar policies, you must first register the WorkloadIdentity entity type and its attributes in the schema. Without this file, cedar validate will return an error stating the attribute is unknown.
// schema.json
{
"": {
"entityTypes": {
"WorkloadIdentity": {
"shape": {
"type": "Record",
"attributes": {
"spiffe_id": { "type": "String", "required": true }
}
}
},
"ModelEndpoint": {},
"DataStore": {
"shape": {
"type": "Record",
"attributes": {
"classification": { "type": "String", "required": true }
}
}
},
"Environment": {}
},
"actions": {
"invoke_model": {
"appliesTo": {
"principalTypes": ["WorkloadIdentity"],
"resourceTypes": ["ModelEndpoint"]
}
},
"write_data": {
"appliesTo": {
"principalTypes": ["WorkloadIdentity"],
"resourceTypes": ["DataStore"]
}
},
"read_data": {
"appliesTo": {
"principalTypes": ["WorkloadIdentity"],
"resourceTypes": ["DataStore"]
}
}
}
}
}Step 2: Register Workloads in the SPIRE Server
# AI 오케스트레이터 에이전트 등록
spire-server entry create \
-spiffeID spiffe://prod.example.com/ns/ai-agents/sa/orchestrator \
-parentID spiffe://prod.example.com/k8s-workload-registrar/node \
-selector k8s:ns:ai-agents \
-selector k8s:sa:orchestrator-sa \
-ttl 300 # SVID 유효기간 5분 설정
# 모델 서빙 서버 등록
spire-server entry create \
-spiffeID spiffe://prod.example.com/ns/inference/sa/vllm-server \
-parentID spiffe://prod.example.com/k8s-workload-registrar/node \
-selector k8s:ns:inference \
-selector k8s:sa:vllm-sa \
-ttl 300Step 3: Mount SVID to the Filesystem via the spiffe-helper Sidecar
spiffe-helper is a sidecar that automatically writes SVIDs to the filesystem and renews them before expiration. In helper.conf, you specify which path and filename to use for storage.
# /etc/spiffe-helper/helper.conf
agent_address = "/run/spire/sockets/agent.sock"
cmd = "echo"
cmd_args = "svid-rotated"
cert_dir = "/run/secrets/svid"
svid_file_name = "svid.pem"
svid_key_file_name = "key.pem"
svid_bundle_file_name = "bundle.pem"
renew_signal = "SIGUSR1"# k8s deployment 일부 — sidecar 패턴
containers:
- name: ai-orchestrator
image: my-agent:latest
volumeMounts:
- name: spiffe-workload-api
mountPath: /run/spire/sockets
readOnly: true
- name: svid-volume
mountPath: /run/secrets/svid
- name: spiffe-helper
image: ghcr.io/spiffe/spiffe-helper:latest
args: ["-config", "/etc/spiffe-helper/helper.conf"]
volumeMounts:
- name: spiffe-workload-api
mountPath: /run/spire/sockets
- name: svid-volume
mountPath: /run/secrets/svid
- name: helper-config
mountPath: /etc/spiffe-helper
volumes:
- name: spiffe-workload-api
hostPath:
path: /run/spire/sockets
type: Directory
- name: svid-volume
emptyDir:
medium: Memory # 메모리 내 저장으로 디스크 노출 최소화
- name: helper-config
configMap:
name: spiffe-helper-configStep 4: Control Model Invocations with Cedar Policies
// policies/ai-agent-policy.cedar
// 오케스트레이터만 모델 추론 호출 허용
permit (
principal is WorkloadIdentity,
action == Action::"invoke_model",
resource == ModelEndpoint::"gpt-inference-v2"
)
when {
principal.spiffe_id == "spiffe://prod.example.com/ns/ai-agents/sa/orchestrator"
};
// PII 데이터 스토어에 대한 쓰기 작업 전면 금지
forbid (
principal,
action == Action::"write_data",
resource is DataStore
)
when { resource.classification == "PII" };
// 분석 에이전트는 비PII 데이터만 읽기 허용
permit (
principal is WorkloadIdentity,
action == Action::"read_data",
resource is DataStore
)
when {
principal.spiffe_id == "spiffe://prod.example.com/ns/ai-agents/sa/analytics"
&& resource.classification != "PII"
};Step 5: Validate Cedar Policies (Run in CI/CD)
# 스키마 파일을 기준으로 정책 검증
cedar validate \
--schema schema.json \
--policies policies/
# 특정 요청 시뮬레이션 — 정책 평가 결과 확인
cedar authorize \
--policies policies/ \
--schema schema.json \
--principal 'WorkloadIdentity::"spiffe://prod.example.com/ns/ai-agents/sa/orchestrator"' \
--action 'Action::"invoke_model"' \
--resource 'ModelEndpoint::"gpt-inference-v2"' \
--context '{}'
# 출력: ALLOWExample 2: CI/CD Zero Trust Pipeline — Complete Elimination of Hardcoded Secrets
This is a pattern in which a GitHub Actions runner or GitLab CI job receives a JWT-SVID at runtime and uses it to authenticate to HashiCorp Vault. No AWS credentials or API keys exist anywhere in the pipeline.
# JWT-SVID 요청 및 토큰 추출
JWT_TOKEN=$(spire-agent api fetch jwt \
-socketPath /run/spire/sockets/agent.sock \
-audience vault.prod.internal \
| jq -r '.svids[0].token')
# JWT-SVID로 Vault 인증 → 단기 AWS 자격증명 획득
vault write auth/jwt/login \
role="ci-deploy-role" \
jwt="${JWT_TOKEN}"
# Vault가 반환한 단기 자격증명으로 AWS 배포 수행
# (자격증명 TTL: 15분, 파이프라인 완료 후 자동 만료)When SPIFFE ID pattern matching is needed in Cedar, you can use the str:: extension functions.
// CI/CD 배포 권한 정책
// staging 환경: gitlab CI 파이프라인 전체 허용
// str:: 확장 함수로 SPIFFE ID 경로 패턴 매칭
permit (
principal is WorkloadIdentity,
action == Action::"deploy",
resource == Environment::"staging"
)
when {
str::startsWith(principal.spiffe_id, "spiffe://prod.example.com/ci/gitlab/")
&& str::endsWith(principal.spiffe_id, "/deploy")
};
// production 배포: main 브랜치 파이프라인만 허용
permit (
principal is WorkloadIdentity,
action == Action::"deploy",
resource == Environment::"production"
)
when {
principal.spiffe_id == "spiffe://prod.example.com/ci/gitlab/main/deploy"
&& context.approval_count >= 2
};Example 3: Multi-Agent Trust Chain — The WIMSE Delegation Token Pattern
When Agent A calls Agent B, Agent A's full permissions must not propagate unchanged to Agent B. By using the WIMSE (Workload Identity in Multi-System Environments) delegation token pattern, you can use a narrower-scoped token at each hop.
에이전트 A (오케스트레이터)
SVID: spiffe://prod/ns/agents/sa/orchestrator
권한: invoke_model, read_data, delegate
↓ 위임 토큰 요청 (SPIRE에 스코프 명시)
SPIRE Server
→ 에이전트 B용 제한 토큰 발급
→ 스코프: read_data만 허용, TTL: 2분
↓ 제한 토큰 전달
에이전트 B (분석 워커)
위임 토큰으로만 동작
invoke_model 호출 시도 → Cedar가 거부
(에이전트 A가 탈취되어도 에이전트 B 권한은 최소화)Blocking Lateral Movement: Since each agent uses a token with a different scope, even if one agent is compromised, the attacker can only move within the limited scope of that agent. Lateral movement across the entire pipeline is structurally prevented.
Connecting SPIRE + Cedar: Implementing the Policy Decision Point Yourself
The core of actually connecting SPIRE and Cedar is the Policy Decision Point (PDP). The PDP receives a JWT-SVID, verifies the identity, and then evaluates Cedar policies. Below is the core flow of a PDP written in Go.
// pdp/authorize.go
package pdp
import (
"context"
"os"
cedar "github.com/cedar-policy/cedar-go"
"github.com/spiffe/go-spiffe/v2/svid/jwtsvid"
"github.com/spiffe/go-spiffe/v2/workloadapi"
)
type AuthRequest struct {
RawJWT string // Authorization 헤더의 JWT-SVID
Action string // Cedar Action 이름
Resource string // Cedar Resource ID
}
func Authorize(ctx context.Context, req AuthRequest) (bool, error) {
// 1. Workload API에서 트러스트 번들(JWKS) 획득 → JWT-SVID 서명 검증
client, _ := workloadapi.New(ctx)
defer client.Close()
bundles, _ := client.FetchJWTBundles(ctx)
svid, err := jwtsvid.ParseAndValidate(
req.RawJWT, bundles, []string{"pdp.prod.internal"},
)
if err != nil {
return false, err // 검증 실패 → 즉시 거부
}
// 2. Cedar 정책 로드
policyBytes, _ := os.ReadFile("policies/ai-agent-policy.cedar")
ps, _ := cedar.NewPolicySet("policy.cedar", policyBytes)
// 3. 검증된 SPIFFE ID를 Cedar 엔티티 속성으로 주입
principalUID := cedar.NewEntityUID("WorkloadIdentity", svid.ID.String())
entities := cedar.EntityMap{
principalUID: {
UID: principalUID,
Attributes: cedar.NewRecord(cedar.RecordMap{
"spiffe_id": cedar.String(svid.ID.String()),
}),
},
}
// 4. Cedar 정책 평가 → 결정 반환
decision, _ := ps.IsAuthorized(entities, cedar.Request{
Principal: principalUID,
Action: cedar.NewEntityUID("Action", req.Action),
Resource: cedar.NewEntityUID("ModelEndpoint", req.Resource),
})
return decision == cedar.Allow, nil
}This ~30-line block of code connects SPIRE's identity verification and Cedar's policy evaluation into a single pipeline. The JWT-SVID signature is verified using the trust bundle (JWKS) obtained from the SPIRE Workload API, and the verified SPIFFE ID is injected as a Cedar entity attribute for use in policy evaluation.
The Most Common Mistakes in Production
Reviewing problems that repeatedly appear in real-world deployments can help you avoid costly trial and error.
-
Leaving SVID TTL at the default (1 hour) — A stolen SVID remains valid for a full hour. For AI agent workloads, it is recommended to set a short TTL of 5–15 minutes and configure the automatic renewal interval to be no more than half the TTL.
-
Writing Cedar policies with only
permitrules and omittingforbid— While addingpermiton top of the default deny-all may seem sufficient, special cases like PII access or direct production writes should be double-protected with explicitforbidrules for safety. -
Carelessly designing the trust domain path structure at the start — Beginning with a flat structure like
spiffe://prod.example.com/agent1makes it impossible to distinguish by namespace, team, or environment later. It is recommended to design a hierarchical path from the beginning, in the formspiffe://prod.example.com/ns/{namespace}/sa/{service-account}.
Pros and Cons Analysis
Advantages
| Item | Description |
|---|---|
| Solves the Secret Zero problem | Replaces static API keys and passwords with cryptographic identities, fundamentally eliminating the risk of credential leakage. |
| Automatic renewal | SPIRE automatically reissues SVIDs before expiration, eliminating manual secret rotation tasks. |
| Policy analysis capability | cedar validate can detect policy conflicts and unreachable rules at the CI stage before deployment. |
| Multi-platform identity standard | The same identity standard applies regardless of whether you are on Kubernetes, VMs, bare metal, or any cloud. |
| Auditability | All identity issuances and policy decisions are recorded in logs, making compliance with SOC2, GDPR, and other regulations easier. |
| Trust domain federation | Identities can be connected across multi-cloud and multi-organization environments. |
Disadvantages and Caveats
| Item | Description |
|---|---|
| Operational complexity | Configuring SPIRE Server for HA, distributing trust bundles, and managing the upstream CA are challenging. Introducing Tornjak (a management UI) and standardizing Helm chart deployment can reduce the burden. |
| Bootstrap trust problem | At initial node attestation, an entity is needed to verify the SPIRE Agent's own identity. Using cloud platform attestors (AWS IID, GCP GCE) is recommended. |
| Cedar learning curve | It takes time to become familiar with the PARC model and schema definitions, and policies can grow unwieldy in complex scenarios. Incremental adoption is possible by integrating cedar validate into CI. |
| Latency overhead | Inserting Cedar policy evaluation on every request increases latency. Caching decision results (TTL: a few seconds) and using the sidecar pattern are effective mitigations. |
| Dynamic nature of AI agents | LLM-based agents can dynamically call new tools at runtime, making it difficult for static policies to cover every case. Pre-registering tools in a tool catalog and applying a default deny policy for unregistered tool calls is recommended. |
| Ecosystem maturity | SPIFFE/Cedar integration SDKs are not yet fully mature, often requiring custom integration code. Choose between cedar-go and cedar-policy (Rust) based on your language stack. |
Trust Domain: The top-level unit of the SPIFFE identity space. Trust boundaries are separated at the domain level, such as
spiffe://prod.example.com. In multi-cluster environments, trust domain federation enables SVID verification across different clusters.
Closing Thoughts
Through this article, you should now understand the complete picture of a Zero Trust pipeline that issues cryptographic identities to AI agents using SPIFFE/SPIRE and deterministically controls every action with Cedar policies.
There are three steps you can take right now.
-
Try the SPIRE environment locally first. Follow the official Kubernetes Quickstart (
https://spiffe.io/docs/latest/try/getting-started-k8s/) to deploy SPIRE Server + Agent on minikube, and use thespire-agent api fetch x509command to observe the actual SVID issuance process — this will make the architecture much more concrete. -
Write a policy suited to your own workloads in the Cedar playground (
https://www.cedarpolicy.com/en/playground). Define theWorkloadIdentityentity based on theschema.jsonfrom this article and immediately verify allow/deny results withcedar authorize— this will help you get comfortable with how Cedar works quickly. -
Implement the Policy Decision Point that connects the two technologies yourself. Using the
pdp/authorize.goexample above as a starting point, actually run the flow of receiving a JWT-SVID from SPIRE's Workload API and passing it to cedar-go — this will give you a hands-on feel for how the entire pipeline actually works.
Next article: A practical guide to integrating Istio service mesh with SPIRE so that the Envoy sidecar automatically handles SVIDs, and configuring trust domain federation across multi-cluster environments.
References
- SPIFFE Official Docs - SPIRE Concepts
- SPIFFE Official Docs - Workload Registration
- SPIFFE Official Docs - Kubernetes Quickstart
- HashiCorp: SPIFFE - Securing the identity of agentic AI and non-human actors
- HashiCorp: Zero trust for agentic systems — managing non-human identities at scale
- Red Hat: Zero Trust for autonomous agentic AI systems (2026)
- arXiv: Establishing Workload Identity for Zero Trust CI/CD
- arXiv: A Novel Zero-Trust Identity Framework for Agentic AI
- Cedar Policy Language Official Docs
- cedar-policy GitHub
- AWS: Secure AI agents with Policy in Amazon Bedrock AgentCore
- AWS: Policy in Amazon Bedrock AgentCore Official Docs
- StrongDM: Complete Guide to Cedar Policy Language 2026
- OPA vs Cedar vs Zanzibar Comparison Guide 2025
- Microsoft Agent Governance Toolkit (GitHub)
- Microsoft: Agent Governance Toolkit Architecture Deep Dive
- GitGuardian: Getting Started With SPIFFE for Multi-Cloud Secure Workload Authentication
- Cerbos: MCP and Zero Trust — Securing AI Agents With Identity and Policy
- WEF: Non-human identities — Agentic AI's new frontier of cybersecurity risk
- WIMSE IETF Working Group