Skip to content

Workload Identity with SPIFFE/SPIRE

Supported Versions: SPIRE 1.12+, Kubernetes 1.31, 1.32, 1.33 最終更新: February 25, 2026

SPIFFE (Secure Production Identity Framework For Everyone) と SPIRE (the SPIFFE Runtime Environment) は、cloud-native 環境における workload identity への標準ベースのアプローチを提供します。CNCF Graduated プロジェクトとして、SPIFFE/SPIRE は、アプリケーションコードの変更を必要とせずに、暗号学的に検証可能な identity を workload に提供することで、Zero Trust security を実現します。

Table of Contents

  1. The Zero Trust Identity Problem
  2. SPIFFE Specification Overview
  3. Core Concepts
  4. SPIRE Architecture
  5. Installation
  6. Node Attestation
  7. Workload Attestation
  8. Kubernetes Integration
  9. Service Mesh Integration
  10. Federation
  11. EKS Integration
  12. Best Practices
  13. Troubleshooting
  14. Summary and References

The Zero Trust Identity Problem

従来の perimeter-based security model では、ネットワーク境界内の workload は信頼できるものと仮定します。このアプローチは、次のような現代の分散システムではうまく機能しません。

  • Microservices communicate across network boundaries — Service は複数の cluster、cloud、data center にまたがります
  • Dynamic infrastructure — Container と pod は一時的で、IP address が絶えず変化します
  • Lateral movement attacks — 攻撃者が perimeter を突破すると、ネットワーク内を自由に移動できます
  • Shared tenancy — 複数のチームとアプリケーションが同じ infrastructure を共有します

Zero Trust security では、ネットワーク上の場所に関係なく、すべての workload が通信前に identity を証明する必要があります。SPIFFE は次の機能を提供することでこれに対応します。

  1. Universal identity standard — 異種環境全体で workload を識別するための一貫した方法
  2. Cryptographic verification — ネットワークを信頼せずに検証できる identity
  3. Automatic rotation — 侵害された場合の blast radius を最小化する短命の credential
  4. No application changes — アプリケーションに透過的な identity 注入

SPIFFE Specification Overview

SPIFFE は、3 つの中核コンポーネントを定義するオープン仕様です。

ComponentDescription
SPIFFE IDA URI that uniquely identifies a workload
SVIDSPIFFE Verifiable Identity Document — a cryptographic document that proves a workload's identity
Trust BundleA set of CA certificates used to verify SVIDs
Workload APIA local API that workloads use to obtain their SVIDs

CNCF Graduation Status

SPIFFE/SPIRE は 2022 年に CNCF を卒業し、production-readiness と業界での広範な採用を示しています。主な採用組織は次のとおりです。

  • Bloomberg
  • ByteDance
  • GitHub
  • Pinterest
  • Square
  • Uber

Core Concepts

SPIFFE ID

SPIFFE ID は、trust domain 内で workload を一意に識別する URI です。

spiffe://trust-domain/workload-identifier

構成要素:

PartDescriptionExample
spiffe://URI scheme (always "spiffe")spiffe://
trust-domainAdministrative domain of trustprod.example.com
workload-identifierPath identifying the workload/ns/payments/sa/api-server

SPIFFE ID の例:

# Kubernetes workload by namespace and service account
spiffe://prod.example.com/ns/payments/sa/api-server

# Workload by cluster and deployment
spiffe://example.com/cluster/us-east-1/deployment/frontend

# Legacy application by hostname
spiffe://example.com/host/db-server-01/app/mysql

SVID (SPIFFE Verifiable Identity Document)

SVID は、workload の SPIFFE ID を保持する暗号学的 document です。SPIFFE は 2 つの SVID 形式を定義しています。

X.509-SVID vs JWT-SVID Comparison

FeatureX.509-SVIDJWT-SVID
FormatX.509 certificateJSON Web Token
TransportTLS client certificatesHTTP headers, gRPC metadata
VerificationCertificate chain validationSignature verification
Use CasemTLS connectionsAPI authentication, proxies
AudienceNot applicableRequired (prevents replay)
Typical TTL1 hour (configurable)5 minutes (short-lived)
Key StoragePrivate key filePrivate key for signing
RevocationShort TTL (no CRL/OCSP)Short TTL

X.509-SVID の構造:

┌─────────────────────────────────────────────────────────────┐
│                      X.509-SVID                             │
├─────────────────────────────────────────────────────────────┤
│  Subject: CN=<workload-identifier>                          │
│  URI SAN: spiffe://trust-domain/workload-identifier         │
│  Issuer: SPIRE Server CA                                    │
│  Not Before: 2026-02-25T10:00:00Z                          │
│  Not After: 2026-02-25T11:00:00Z (1 hour TTL)              │
│  Public Key: [workload's public key]                        │
│  Signature: [signed by SPIRE Server CA]                     │
└─────────────────────────────────────────────────────────────┘

JWT-SVID の構造:

json
{
  "alg": "RS256",
  "kid": "abcd1234",
  "typ": "JWT"
}
.
{
  "sub": "spiffe://prod.example.com/ns/payments/sa/api",
  "aud": ["spiffe://prod.example.com/ns/orders/sa/processor"],
  "exp": 1708858200,
  "iat": 1708857900
}
.
[signature]

Trust Bundle

Trust bundle には、trust domain の root CA certificate が含まれます。workload は trust bundle を使用して、同じ trust domain 内の他の workload からの SVID を検証します。

yaml
# Trust bundle structure
trust_domain: "prod.example.com"
root_certificates:
  - |
    -----BEGIN CERTIFICATE-----
    MIIBzDCCAVKgAwIBAgIJAJR2...
    -----END CERTIFICATE-----
jwt_signing_keys:
  - kid: "key-1"
    public_key: |
      -----BEGIN PUBLIC KEY-----
      MIIBIjANBgkqhkiG9w0BAQEF...
      -----END PUBLIC KEY-----

Trust Domain

Trust domain は、信頼の管理境界です。trust domain 内のすべての workload は、同じ root of trust (SPIRE Server CA) を共有します。

Trust Domain の設計上の考慮事項:

PatternExampleUse Case
Single domainexample.comSimple deployments
Environment-basedprod.example.com, staging.example.comEnvironment isolation
Region-basedus-east.example.com, eu-west.example.comRegional isolation
Cluster-basedcluster-a.example.comMulti-cluster with separate CAs

SPIRE Architecture

SPIRE は server-agent architecture で SPIFFE 仕様を実装します。

SPIRE Server

SPIRE Server は次の役割を持つ中央 authority です。

FunctionDescription
CA OperationsSigns X.509-SVIDs and JWT-SVIDs
Registration APIManages workload registration entries
Node AttestationVerifies agent identity during bootstrap
Data StorePersists registration entries and CA state
Key ManagementManages signing keys (supports HSM/KMS)

Server Configuration Example:

yaml
# server.conf
server {
    bind_address = "0.0.0.0"
    bind_port = "8081"
    trust_domain = "prod.example.com"
    data_dir = "/run/spire/data"
    log_level = "INFO"

    ca_ttl = "24h"
    default_x509_svid_ttl = "1h"
    default_jwt_svid_ttl = "5m"

    ca_subject {
        country = ["US"]
        organization = ["Example Corp"]
        common_name = "SPIRE Server CA"
    }
}

plugins {
    DataStore "sql" {
        plugin_data {
            database_type = "postgres"
            connection_string = "dbname=spire host=postgres user=spire"
        }
    }

    NodeAttestor "k8s_psat" {
        plugin_data {
            clusters = {
                "production" = {
                    service_account_allow_list = ["spire:spire-agent"]
                }
            }
        }
    }

    KeyManager "disk" {
        plugin_data {
            keys_path = "/run/spire/data/keys.json"
        }
    }

    UpstreamAuthority "disk" {
        plugin_data {
            key_file_path = "/run/spire/conf/ca.key"
            cert_file_path = "/run/spire/conf/ca.crt"
        }
    }
}

SPIRE Agent

SPIRE Agent は各 node 上で実行され、次を行います。

FunctionDescription
Node AttestationProves node identity to the server
Workload AttestationIdentifies workloads requesting SVIDs
Workload APIServes SVIDs to workloads via Unix socket
SVID CachingCaches and rotates SVIDs automatically
SDS ServerProvides Envoy SDS API for service meshes

Agent Configuration Example:

yaml
# agent.conf
agent {
    data_dir = "/run/spire/data"
    log_level = "INFO"
    server_address = "spire-server"
    server_port = "8081"
    socket_path = "/run/spire/sockets/agent.sock"
    trust_domain = "prod.example.com"
}

plugins {
    NodeAttestor "k8s_psat" {
        plugin_data {
            cluster = "production"
        }
    }

    KeyManager "memory" {
        plugin_data {}
    }

    WorkloadAttestor "k8s" {
        plugin_data {
            skip_kubelet_verification = true
        }
    }
}

SVID Issuance Flow

次の図は、workload が SVID を取得する方法を示しています。


Installation

Prerequisites

  • Kubernetes cluster 1.31+
  • Helm 3.10+
  • cluster access が設定された kubectl
  • Cluster admin permission

SPIRE は、workload registration を自動化する SPIRE Controller Manager を含む Helm chart を提供しています。

bash
# Add the SPIFFE Helm repository
helm repo add spiffe https://spiffe.github.io/helm-charts-hardened/
helm repo update

# Create namespace
kubectl create namespace spire-system

# Install SPIRE with Controller Manager
helm install spire spiffe/spire \
  --namespace spire-system \
  --set global.spire.trustDomain="prod.example.com" \
  --set global.spire.clusterName="production" \
  --set spire-server.replicaCount=3 \
  --set spire-server.persistence.enabled=true \
  --set spire-server.persistence.size=1Gi

Namespace Layout

一般的な SPIRE deployment では、次の namespace 構造を使用します。

┌─────────────────────────────────────────────────────────────┐
│                    Namespace Layout                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  spire-system/                                              │
│  ├── spire-server (StatefulSet, 3 replicas for HA)         │
│  ├── spire-server-0, spire-server-1, spire-server-2        │
│  ├── spire-controller-manager (Deployment)                  │
│  └── spire-bundle-configmap                                 │
│                                                             │
│  spire-agents/                                              │
│  └── spire-agent (DaemonSet, one per node)                 │
│                                                             │
│  spiffe-csi-driver/                                        │
│  └── spiffe-csi-driver (DaemonSet)                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

High Availability Configuration

production deployment では、高可用性のために SPIRE Server を構成します。

yaml
# values-ha.yaml
spire-server:
  replicaCount: 3

  persistence:
    enabled: true
    size: 5Gi
    storageClass: gp3

  dataStore:
    sql:
      databaseType: postgres
      connectionString: "host=spire-postgres dbname=spire sslmode=verify-full"

  resources:
    requests:
      cpu: 200m
      memory: 512Mi
    limits:
      cpu: 1000m
      memory: 1Gi

  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: spire-server
          topologyKey: kubernetes.io/hostname

spire-agent:
  resources:
    requests:
      cpu: 50m
      memory: 128Mi
    limits:
      cpu: 200m
      memory: 256Mi
bash
# Install with HA values
helm install spire spiffe/spire \
  --namespace spire-system \
  -f values-ha.yaml

Verify Installation

bash
# Check SPIRE Server status
kubectl -n spire-system get pods -l app.kubernetes.io/name=spire-server

# Check SPIRE Agent status
kubectl -n spire-system get pods -l app.kubernetes.io/name=spire-agent

# Verify server health
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server healthcheck

# List registered entries
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry show

Node Attestation

Node attestation は、SPIRE Agent と SPIRE Server の間に信頼を確立します。agent は workload の代理で SVID を要求する前に、自身の identity を証明する必要があります。

Attestation Flow

Kubernetes PSAT (Projected Service Account Token)

Kubernetes で推奨される attestation method です。自動的に rotation される projected service account token を使用します。

Server Configuration:

yaml
# In server.conf plugins section
NodeAttestor "k8s_psat" {
    plugin_data {
        clusters = {
            "production" = {
                service_account_allow_list = ["spire-system:spire-agent"]
                audience = ["spire-server"]
            }
        }
    }
}

Agent Configuration:

yaml
# In agent.conf plugins section
NodeAttestor "k8s_psat" {
    plugin_data {
        cluster = "production"
        token_path = "/var/run/secrets/tokens/spire-agent"
    }
}

Agent DaemonSet with PSAT:

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: spire-agent
  namespace: spire-system
spec:
  selector:
    matchLabels:
      app: spire-agent
  template:
    metadata:
      labels:
        app: spire-agent
    spec:
      serviceAccountName: spire-agent
      containers:
        - name: spire-agent
          image: ghcr.io/spiffe/spire-agent:1.12.0
          volumeMounts:
            - name: spire-token
              mountPath: /var/run/secrets/tokens
      volumes:
        - name: spire-token
          projected:
            sources:
              - serviceAccountToken:
                  path: spire-agent
                  expirationSeconds: 7200
                  audience: spire-server

AWS Instance Identity Document (IID)

EKS または EC2-based Kubernetes cluster では、AWS IID により、AWS の暗号学的に署名された instance metadata を使った強力な node attestation が提供されます。

Server Configuration:

yaml
NodeAttestor "aws_iid" {
    plugin_data {
        access_key_id = "AKIAIOSFODNN7EXAMPLE"      # Or use IRSA
        secret_access_key = "wJalrXUtnFEMI/K7MDENG" # Or use IRSA
        skip_block_device = true
        account_ids_for_local_validation = ["123456789012"]
    }
}

Agent Configuration:

yaml
NodeAttestor "aws_iid" {
    plugin_data {}
}

Join Token (Bootstrap)

初期セットアップまたは non-cloud 環境向けです。使用後に期限切れになる one-time token です。

bash
# Generate a join token on the server
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server token generate \
  -spiffeID spiffe://prod.example.com/agent/node-01 \
  -ttl 3600

# Output: Token: abc123-def456-ghi789

# Use the token when starting the agent
spire-agent run -joinToken abc123-def456-ghi789

Node Attestor Comparison

AttestorSecurityAutomationUse Case
k8s_psatHighFully automaticKubernetes clusters
aws_iidHighFully automaticAWS EC2/EKS
gcp_iitHighFully automaticGCP GKE
azure_msiHighFully automaticAzure AKS
join_tokenMediumManualBootstrap, air-gapped
x509popHighSemi-automaticExisting PKI integration

Workload Attestation

Workload attestation は、SPIRE Agent に SVID を要求している特定の workload を識別します。agent は attestor を使用して、呼び出し元 process に関する情報を収集します。

Kubernetes Workload Attestor

Kubernetes attestor は kubelet に問い合わせて pod を識別します。

yaml
# In agent.conf
WorkloadAttestor "k8s" {
    plugin_data {
        kubelet_read_only_port = 10255  # Or use secure port
        skip_kubelet_verification = false
        node_name_env = "MY_NODE_NAME"
    }
}

Selectors Available:

SelectorDescriptionExample
k8s:nsNamespacek8s:ns:payments
k8s:saService Accountk8s:sa:api-server
k8s:pod-labelPod labelk8s:pod-label:app:frontend
k8s:pod-ownerOwner referencek8s:pod-owner:Deployment:web
k8s:pod-owner-uidOwner UIDk8s:pod-owner-uid:abc123
k8s:pod-namePod namek8s:pod-name:web-abc123
k8s:pod-uidPod UIDk8s:pod-uid:def456
k8s:container-nameContainer namek8s:container-name:app
k8s:container-imageContainer imagek8s:container-image:nginx:1.25
k8s:node-nameNode namek8s:node-name:node-01

Registration Entry Examples

Registration entry は workload selector を SPIFFE ID に対応付けます。

bash
# Register a workload by namespace and service account
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry create \
  -spiffeID spiffe://prod.example.com/ns/payments/sa/api-server \
  -parentID spiffe://prod.example.com/agent/k8s-node \
  -selector k8s:ns:payments \
  -selector k8s:sa:api-server

# Register with pod labels
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry create \
  -spiffeID spiffe://prod.example.com/app/frontend \
  -parentID spiffe://prod.example.com/agent/k8s-node \
  -selector k8s:ns:web \
  -selector k8s:pod-label:app:frontend

# Register with container image (for supply chain security)
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry create \
  -spiffeID spiffe://prod.example.com/verified/nginx \
  -parentID spiffe://prod.example.com/agent/k8s-node \
  -selector k8s:container-image:nginx:1.25-alpine

Unix Workload Attestor

non-Kubernetes workload または追加の process-level attestation 向けです。

yaml
WorkloadAttestor "unix" {
    plugin_data {
        discover_workload_path = true
    }
}

Unix Selectors:

SelectorDescription
unix:uidProcess user ID
unix:gidProcess group ID
unix:userUsername
unix:groupGroup name
unix:pathExecutable path
unix:sha256Binary SHA256 hash

Kubernetes Integration

SPIFFE CSI Driver

SPIFFE CSI Driver は、アプリケーション変更を必要とせずに SVID を pod filesystem に直接 mount します。

bash
# Install SPIFFE CSI Driver
helm install spiffe-csi-driver spiffe/spiffe-csi-driver \
  --namespace spiffe-csi-driver \
  --create-namespace \
  --set spire.agentSocketPath=/run/spire/sockets/agent.sock

Using CSI Driver in Pods:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-workload
  namespace: payments
spec:
  serviceAccountName: api-server
  containers:
    - name: app
      image: myapp:latest
      volumeMounts:
        - name: spiffe
          mountPath: /run/spiffe
          readOnly: true
      env:
        - name: SVID_PATH
          value: /run/spiffe/svid.pem
        - name: KEY_PATH
          value: /run/spiffe/key.pem
        - name: BUNDLE_PATH
          value: /run/spiffe/bundle.pem
  volumes:
    - name: spiffe
      csi:
        driver: csi.spiffe.io
        readOnly: true

Files Mounted by CSI Driver:

/run/spiffe/
├── svid.pem         # X.509-SVID certificate
├── key.pem          # Private key
├── bundle.pem       # Trust bundle (CA certificates)
└── svid.jwt         # JWT-SVID (if configured)

SPIRE Controller Manager

SPIRE Controller Manager は Kubernetes CRD を使用して workload registration を自動化します。

bash
# Controller Manager is included in the main SPIRE Helm chart
# Verify it's running
kubectl -n spire-system get pods -l app.kubernetes.io/name=spire-controller-manager

ClusterSPIFFEID Custom Resource:

yaml
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: payments-api
spec:
  spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
  podSelector:
    matchLabels:
      app: payments-api
  namespaceSelector:
    matchLabels:
      spiffe-enabled: "true"
  ttl: 1h
  dnsNameTemplates:
    - "{{ .PodMeta.Name }}.{{ .PodMeta.Namespace }}.svc.cluster.local"
  workloadSelectorTemplates:
    - "k8s:ns:{{ .PodMeta.Namespace }}"
    - "k8s:sa:{{ .PodSpec.ServiceAccountName }}"

Label Namespaces for Auto-Registration:

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: payments
  labels:
    spiffe-enabled: "true"

Advanced ClusterSPIFFEID Examples:

yaml
# Identity based on deployment and container
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: deployment-identity
spec:
  spiffeIDTemplate: >-
    spiffe://{{ .TrustDomain }}/cluster/{{ .ClusterName }}/ns/{{ .PodMeta.Namespace }}/deploy/{{ index .PodMeta.Labels "app" }}
  podSelector:
    matchExpressions:
      - key: app
        operator: Exists
  ttl: 30m
  federatesWith:
    - "partner.example.com"
---
# Identity for jobs with short TTL
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: batch-jobs
spec:
  spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/job/{{ .PodMeta.Namespace }}/{{ index .PodMeta.Labels \"job-name\" }}"
  podSelector:
    matchLabels:
      workload-type: batch
  ttl: 5m

Envoy SDS Integration

SPIRE Agent は Envoy-based proxy 向けに SDS (Secret Discovery Service) API を公開します。

yaml
# Agent configuration for SDS
agent {
    # ... other config ...

    # Enable SDS for Envoy
    sds {
        default_svid_name = "default"
        default_bundle_name = "ROOTCA"
    }
}

Envoy Configuration Using SPIRE SDS:

yaml
static_resources:
  listeners:
    - name: mtls_listener
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8443
      filter_chains:
        - transport_socket:
            name: envoy.transport_sockets.tls
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
              common_tls_context:
                tls_certificate_sds_secret_configs:
                  - name: "spiffe://prod.example.com/ns/web/sa/frontend"
                    sds_config:
                      api_config_source:
                        api_type: GRPC
                        grpc_services:
                          - envoy_grpc:
                              cluster_name: spire_agent
                validation_context_sds_secret_config:
                  name: "ROOTCA"
                  sds_config:
                    api_config_source:
                      api_type: GRPC
                      grpc_services:
                        - envoy_grpc:
                            cluster_name: spire_agent

  clusters:
    - name: spire_agent
      connect_timeout: 1s
      type: STATIC
      lb_policy: ROUND_ROBIN
      typed_extension_protocol_options:
        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
          "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
          explicit_http_config:
            http2_protocol_options: {}
      load_assignment:
        cluster_name: spire_agent
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    pipe:
                      path: /run/spire/sockets/agent.sock

Service Mesh Integration

Istio + SPIRE Integration

SPIRE は Istio の組み込み CA (Citadel) を置き換え、より強力な workload identity の保証を提供できます。

Architecture:

┌─────────────────────────────────────────────────────────────┐
│                  Istio + SPIRE Integration                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐     ┌─────────────┐     ┌─────────────┐  │
│   │   istiod    │     │ SPIRE Server│     │  SPIRE      │  │
│   │ (disabled   │     │    (CA)     │     │  Agent      │  │
│   │    CA)      │     │             │     │             │  │
│   └─────────────┘     └──────┬──────┘     └──────┬──────┘  │
│                              │                    │         │
│                              │ SVID               │ SDS     │
│                              ▼                    ▼         │
│   ┌─────────────────────────────────────────────────────┐  │
│   │              Envoy Sidecar (istio-proxy)            │  │
│   │         Receives SVID via SPIRE Agent SDS           │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Configure Istio to Use SPIRE:

yaml
# IstioOperator configuration
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-spire
spec:
  profile: default
  meshConfig:
    trustDomain: prod.example.com
  values:
    global:
      caAddress: ""  # Disable Citadel
    pilot:
      env:
        PILOT_CERT_PROVIDER: spiffe
        SPIFFE_BUNDLE_ENDPOINTS: "prod.example.com|https://spire-server.spire-system:8443"
  components:
    pilot:
      k8s:
        env:
          - name: PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION
            value: "true"

Sidecar Injection with SPIRE:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-sidecar-injector
  namespace: istio-system
data:
  values: |
    {
      "global": {
        "caAddress": "spire-agent.spire-system:8081",
        "pilotCertProvider": "spiffe"
      }
    }

Cilium + SPIRE Mutual Authentication

Cilium は Service 間の mutual authentication に SPIRE を使用できます。

yaml
# CiliumNetworkPolicy with SPIFFE identity
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: payments-api-policy
  namespace: payments
spec:
  endpointSelector:
    matchLabels:
      app: payments-api
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      authentication:
        mode: required
  egress:
    - toEndpoints:
        - matchLabels:
            app: database
      authentication:
        mode: required

Cilium SPIRE Configuration:

yaml
# Cilium Helm values
authentication:
  enabled: true
  mutual:
    spire:
      enabled: true
      serverAddress: spire-server.spire-system:8081
      trustDomain: prod.example.com

Linkerd Identity Trust Anchors

Linkerd は SPIRE が発行した certificate を信頼するよう構成できます。

bash
# Export SPIRE trust bundle
kubectl -n spire-system exec spire-server-0 -- \
  /opt/spire/bin/spire-server bundle show -format spiffe > spire-bundle.json

# Install Linkerd with SPIRE trust anchor
linkerd install \
  --identity-trust-anchors-file spire-bundle.json \
  --identity-issuer-certificate-file spire-ca.crt \
  --identity-issuer-key-file spire-ca.key \
  | kubectl apply -f -

Federation

Federation により、異なる trust domain の workload が相互信頼を確立できます。これは multi-cluster、multi-cloud、cross-organization communication に不可欠です。

Federation Trust Establishment

Configuring Federation

Server A Configuration (us-east.example.com):

yaml
server {
    trust_domain = "us-east.example.com"

    federation {
        bundle_endpoint {
            address = "0.0.0.0"
            port = 8443
        }

        federates_with "eu-west.example.com" {
            bundle_endpoint_url = "https://spire-server-eu.example.com:8443"
            bundle_endpoint_profile "https_spiffe" {
                endpoint_spiffe_id = "spiffe://eu-west.example.com/spire/server"
            }
        }
    }
}

Server B Configuration (eu-west.example.com):

yaml
server {
    trust_domain = "eu-west.example.com"

    federation {
        bundle_endpoint {
            address = "0.0.0.0"
            port = 8443
        }

        federates_with "us-east.example.com" {
            bundle_endpoint_url = "https://spire-server-us.example.com:8443"
            bundle_endpoint_profile "https_spiffe" {
                endpoint_spiffe_id = "spiffe://us-east.example.com/spire/server"
            }
        }
    }
}

Federated Registration Entries

bash
# Register a workload that can communicate with federated domain
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry create \
  -spiffeID spiffe://us-east.example.com/ns/payments/sa/api \
  -parentID spiffe://us-east.example.com/agent/node \
  -selector k8s:ns:payments \
  -selector k8s:sa:api \
  -federatesWith "spiffe://eu-west.example.com"

ClusterSPIFFEID with Federation:

yaml
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: cross-region-api
spec:
  spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
  podSelector:
    matchLabels:
      federation-enabled: "true"
  federatesWith:
    - "eu-west.example.com"
    - "ap-south.example.com"

Multi-Cloud Federation Example

┌─────────────────────────────────────────────────────────────┐
│                 Multi-Cloud Federation                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   AWS (us-east-1)              GCP (us-central1)            │
│   ┌─────────────────┐          ┌─────────────────┐          │
│   │ Trust Domain:   │          │ Trust Domain:   │          │
│   │ aws.corp.com    │◄────────►│ gcp.corp.com    │          │
│   │                 │ HTTPS    │                 │          │
│   │ EKS Cluster     │ Bundle   │ GKE Cluster     │          │
│   └─────────────────┘ Exchange └─────────────────┘          │
│           ▲                            ▲                     │
│           │                            │                     │
│           ▼                            ▼                     │
│   ┌─────────────────┐          ┌─────────────────┐          │
│   │ On-Prem DC      │          │ Azure (eastus)  │          │
│   │ Trust Domain:   │          │ Trust Domain:   │          │
│   │ dc.corp.com     │◄────────►│ azure.corp.com  │          │
│   └─────────────────┘          └─────────────────┘          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

EKS Integration

IRSA vs SPIFFE Comparison

FeatureIRSASPIFFE/SPIRE
ScopeAWS services onlyUniversal (any service)
Identity FormatIAM Role ARNSPIFFE ID (URI)
Token TypeOIDC JWT (AWS STS)X.509-SVID, JWT-SVID
Trust BoundarySingle AWS account (or cross-account)Any trust domain (multi-cloud)
RotationPod restart requiredAutomatic (no restart)
mTLSNot supportedNative support
Service MeshNot integratedNative integration
Use CaseAWS API accessService-to-service auth

Pod Identity vs SPIRE

FeatureEKS Pod IdentitySPIRE
Setup ComplexityLow (AWS managed)Medium (self-managed)
Cloud Lock-inAWS onlyCloud agnostic
Custom IdentityNo (IAM only)Yes (any identity)
FederationCross-account IAMAny trust domain
On-premisesNot supportedFully supported
Hybrid CloudLimitedFull support

Hybrid Use Cases

Scenario 1: AWS API + Service-to-Service

AWS API access には IRSA を使用し、service-to-service authentication には SPIRE を使用します。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: hybrid-workload
  annotations:
    # IRSA for AWS API access
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-role
spec:
  serviceAccountName: my-service-account
  containers:
    - name: app
      image: myapp:latest
      volumeMounts:
        # SPIRE for service-to-service mTLS
        - name: spiffe
          mountPath: /run/spiffe
          readOnly: true
      env:
        # AWS credentials from IRSA
        - name: AWS_ROLE_ARN
          value: arn:aws:iam::123456789012:role/my-role
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        # SPIRE certificates for mTLS
        - name: SVID_PATH
          value: /run/spiffe/svid.pem
  volumes:
    - name: spiffe
      csi:
        driver: csi.spiffe.io
        readOnly: true

Scenario 2: Cross-Cloud with EKS

yaml
# EKS cluster federates with GKE and on-premises
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: eks-cross-cloud
spec:
  spiffeIDTemplate: "spiffe://eks.example.com/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
  podSelector:
    matchLabels:
      cross-cloud: "true"
  federatesWith:
    - "gke.example.com"
    - "onprem.example.com"

EKS-Specific Node Attestation

EKS では、より強力な node identity のために AWS IID attestation を使用します。

yaml
# Server plugin configuration for EKS
NodeAttestor "aws_iid" {
    plugin_data {
        skip_block_device = true
        disable_instance_profile_selectors = false

        # Allow specific EKS node groups
        agent_path_template = "/eks/{{ .ClusterName }}/{{ .NodeGroupName }}/{{ .InstanceID }}"
    }
}

NodeResolver "aws_iid" {
    plugin_data {
        # Resolve AWS-specific selectors
        # tag:kubernetes.io/cluster/my-cluster = owned
        # tag:eks:nodegroup-name = my-nodegroup
    }
}

Best Practices

Trust Domain Naming

GuidelineExampleRationale
Use DNS-like namesprod.example.comGlobally unique, familiar
Environment separationprod.corp.com, staging.corp.comPrevent cross-env access
Avoid IP addressesNever use IPsIPs change, names don't
Plan for federationaws.corp.com, gcp.corp.comEasier multi-cloud setup

SVID TTL Tuning

yaml
# Recommended TTL values
server {
    # Root CA certificate - long lived
    ca_ttl = "168h"  # 7 days

    # X.509-SVID for workloads
    default_x509_svid_ttl = "1h"  # Balance security vs performance

    # JWT-SVID for API calls
    default_jwt_svid_ttl = "5m"  # Short for stateless auth
}

TTL Guidelines:

Workload TypeRecommended TTLRationale
Long-running services1hBalance rotation overhead
Batch jobs5-15mMatch job duration
API gateways30mFrequent rotation acceptable
CI/CD jobs5mShort-lived, high security

High Availability Deployment

yaml
# Production HA configuration
spire-server:
  replicaCount: 3

  # Use external PostgreSQL for HA
  dataStore:
    sql:
      databaseType: postgres
      connectionString: "host=spire-postgres-cluster..."

  # Pod anti-affinity for spread
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: spire-server
          topologyKey: topology.kubernetes.io/zone

  # Resource limits
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2000m
      memory: 4Gi

  # Persistent storage for CA keys
  persistence:
    enabled: true
    storageClass: gp3
    size: 10Gi

Key Rotation

SPIRE は expiration 前に SVID を自動的に rotation します。CA key rotation については次のとおりです。

bash
# Prepare new upstream CA (if using disk-based upstream authority)
# 1. Generate new CA key pair
# 2. Update server configuration
# 3. Restart servers one at a time

# For AWS KMS-based key management
UpstreamAuthority "aws_kms" {
    plugin_data {
        region = "us-east-1"
        key_arn = "arn:aws:kms:us-east-1:123456789012:key/abc123"
    }
}

Security Hardening

yaml
# Agent security configuration
agent {
    # Restrict socket access
    socket_path = "/run/spire/sockets/agent.sock"

    # Require attestation for all workloads
    authorized_delegates = []

    # Log all workload API requests
    log_level = "INFO"
}

# Network policies for SPIRE
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: spire-server-policy
  namespace: spire-system
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: spire-server
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app.kubernetes.io/name: spire-agent
      ports:
        - port: 8081
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - port: 5432

Troubleshooting

Common Issues

Issue: Agent Cannot Connect to Server

bash
# Check agent logs
kubectl -n spire-system logs -l app.kubernetes.io/name=spire-agent

# Verify server is reachable
kubectl -n spire-system exec -it spire-agent-xxxxx -- \
  nc -zv spire-server 8081

# Check node attestation
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server agent list

Issue: Workload Cannot Get SVID

bash
# Verify registration entry exists
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server entry show

# Check workload attestation from agent
kubectl -n spire-system exec -it spire-agent-xxxxx -- \
  /opt/spire/bin/spire-agent api fetch x509 -socketPath /run/spire/sockets/agent.sock

# Debug workload selectors
kubectl -n spire-system exec -it spire-agent-xxxxx -- \
  /opt/spire/bin/spire-agent api fetch x509 -socketPath /run/spire/sockets/agent.sock -debug

Issue: CSI Driver Not Mounting SVIDs

bash
# Check CSI driver pods
kubectl -n spiffe-csi-driver get pods

# Verify CSI driver registration
kubectl get csidrivers csi.spiffe.io

# Check events on failing pod
kubectl describe pod <pod-name> -n <namespace>

Health Checks

bash
# Server health
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server healthcheck

# Agent health
kubectl -n spire-system exec -it spire-agent-xxxxx -- \
  /opt/spire/bin/spire-agent healthcheck

# Bundle status
kubectl -n spire-system exec -it spire-server-0 -- \
  /opt/spire/bin/spire-server bundle show

Summary and References

Key Takeaways

  1. SPIFFE provides universal workload identity — cloud、cluster、platform を横断して機能する標準ベースのアプローチ

  2. SPIRE implements SPIFFE at scale — 自動化された attestation と SVID management を備えた production-ready な実装

  3. Zero-code integration — CSI driver と service mesh integration により、アプリケーション変更は不要

  4. Federation enables multi-cluster/multi-cloud — Trust domain は cross-boundary authentication のために federation できます

  5. Complements cloud-native identity — SPIFFE は包括的な identity management のために IRSA/Pod Identity と併用できます

Architecture Decision Guide

RequirementRecommendation
AWS-only, AWS APIsUse IRSA or Pod Identity
Multi-cloud servicesUse SPIFFE/SPIRE
Service mesh mTLSUse SPIFFE/SPIRE
Hybrid cloudUse SPIFFE/SPIRE
Cross-organization trustUse SPIFFE Federation
Simple setup, single clusterStart with cloud-native (IRSA), add SPIRE later

References

Official Documentation:

Integration Guides:

CNCF Resources: