microsoft/identity-spiffe
Python
Captured source
source ↗microsoft/identity-spiffe
Description: Sidecar-enforced agent-to-agent authorization with Microsoft Entra Agent Identity, SPIFFE/SPIRE, and cross-cloud workload federation.
Language: Python
License: MIT
Stars: 1
Forks: 0
Open issues: 0
Created: 2026-05-26T22:21:32Z
Pushed: 2026-05-27T22:34:22Z
Default branch: main
Fork: no
Archived: no
README:
Identity Research for Agent Management Using SPIFFE
> A working prototype for governing agent-to-agent traffic with Microsoft Entra Agent Identity, SPIFFE/SPIRE workload identity, and sidecar-enforced policy. The sample runs on Azure Container Apps and includes optional GCP and GitHub Actions federation paths with no shared secrets.
This repository is the public baseline for Identity Research for Agent Management Using SPIFFE. The README is the landing page; the full architecture, setup guide, and API reference are published through GitHub Pages:
Docs and API reference:
What this demonstrates
- A sidecar that enforces mTLS, route-level RBAC, JWT validation, Conditional Access-style risk signals, and live admin governance before traffic reaches the app.
- Entra Agent Identity provisioning for Azure-native agents and federated external callers.
- SPIFFE/SPIRE SVIDs for workload-to-workload mTLS, including optional cross-cloud bundle federation.
- A portal and admin control plane for policy, health, audit, token, and mTLS allow-list management.
- Deployable examples for Azure agents, a GCP-hosted agent, and a GitHub Actions federated caller.
Enforcement model
Every governed call passes through independent checks. Any failed layer denies the request.
The live Enforcement Layers view in the portal — every governed request walks all four layers before the backend ever sees it.
| Layer | Enforcement point | Denies when | |---:|---|---| | 1 | SPIFFE/SPIRE mTLS in spiffe-proxy | Caller SPIFFE ID is not allowed by the target | | 2 | Sidecar RBAC policy | Method/path is not permitted for that caller | | 3 | Entra OAuth2/JWT validation | Token is missing, expired, wrong audience, or lacks role | | 4a | Conditional Access-style risk evaluation | Caller risk or governance state is unacceptable | | 4b | Admin tag governance | Required live Graph-backed tags are absent |
Architecture graphs
System topology
flowchart LR subgraph Browser U[Admin / Viewer] end subgraph ACA["Azure Container Apps Environment"] Portal[isp-portal] SP[securityportal-mock] ACP[admin-control-plane] subgraph BB["budget-backend pod"] BBAPP[app] BBSC[spiffe-proxy sidecar] BBAG[SPIRE agent] end subgraph CALLER["caller pod, e.g. budget-report"] CAPP[app] CSC[spiffe-proxy egress] CAG[SPIRE agent] end end subgraph VM["Azure VM"] SPIRE[(SPIRE Server)] end subgraph GCP["GCP, optional --google"] GCE[GCE VM: google-budget-reader] end subgraph GH["GitHub, optional --github"] RUNNER[Self-hosted Runner VM] GHA[GitHub Actions OIDC] end U --> Portal Portal --> ACP ACP -->|X-Spiffe-Admin-Key| BBSC CAPP --> CSC CSC -.->|mTLS + JWT| BBSC BBSC --> BBAPP BBAG -.->|SVID| SPIRE CAG -.->|SVID| SPIRE GCE -.->|SPIFFE federation via VPN| SPIRE GCE -->|mTLS + JWT| BBSC GHA -->|OIDC| RUNNER RUNNER -->|mTLS + JWT| BBSC SP --> Portal
Five-layer call flow
sequenceDiagram autonumber participant Caller as Caller Agent participant Egress as Egress Sidecar participant Ingress as Ingress Sidecar participant App as Target App participant Graph as Entra / Graph Caller->>Egress: HTTP request Egress->>Egress: Fetch SVID from SPIRE Egress->>Ingress: mTLS handshake with SPIFFE cert Note over Ingress: Layer 1: verify caller SPIFFE ID Egress->>Ingress: Forward request + Entra JWT Note over Ingress: Layer 2: RBAC method/path check Note over Ingress: Layer 3: JWT signature, audience, roles Ingress->>Graph: Resolve caller governance attributes Note over Ingress: Layer 4a: CA/risk evaluation Note over Ingress: Layer 4b: required tag match Ingress->>App: Forward authorized request App->>Ingress: Response Ingress->>Egress: Response Egress->>Caller: Response
Cross-cloud federation
flowchart LR subgraph GCP["GCP trust_domain: gcp.aim.microsoft.com"] GA[GCP agent app] GSC[spiffe-proxy egress] GSP[GCP SPIRE agent] GSRV[(GCP SPIRE server)] end subgraph AZ["Azure trust_domain: aim.microsoft.com"] ASRV[(Azure SPIRE server)] ABB[budget-backend] AENTRA[Entra Agent Identity + FIC] end GSRV |SPIFFE bundle federation| ASRV GA -->|1. Get SPIFFE SVID| GSP GSP -->|2. Exchange external OIDC via FIC| AENTRA GSC -->|3. mTLS + JWT| ABB
Quick start
Read the GitHub Pages quickstart for prerequisites and the full deployment path.
The common commands are:
az login azd auth login azd env new isp-example # Azure-only environment (seed the portal admin with the identity you'll sign in as) ./deploy.sh --new --with-admin=you@your-tenant.com # Existing environment, code changes only ./deploy.sh --skip-provision # Optional federated callers ./deploy.sh --new --google ./deploy.sh --new --github
> Portal sign-in tip. deploy.sh only adds the signed-in az login user > to the Agent Management Administrators group by default. If you'll sign > into the portal with a different identity, pass --with-admin= > (repeatable) or set ISP_INITIAL_ADMINS=alice@contoso.com,bob@contoso.com. > Use ./scripts/portal-members.sh add-admin to add more admins (or > add-viewer, remove-admin, list) after deploy.
Important deployment rules:
- Do not use
azd deployfor agent services. Use./deploy.sh --skip-provisionor./scripts/reattest.sh. - Do not use
az containerapp update --set-env-varson multi-container apps. Export full YAML, edit it, then reimport. - Do not use
az vm run-command invoke. Use the helper path that callsaz vm run-command create --timeout-in-seconds.
Portal tour
The portal (isp-portal) is the operator surface for everything the sidecars enforce — a live read of policy, identity, transport, and audit, plus the controls to change them. Sign-in is gated by Entra; group membership in Agent Management Administrators unlocks the policy editor and network controls, Agent Management Viewers gets read-only access.
The overview dashboard at a glance — live health, one-click security scan, and the agent connection flow color-coded by enforcement decision.
Test Calls
Fire real requests through the live SPIFFE…
Excerpt shown — open the source for the full document.
Notability
notability 1.0/10Minimal stars, routine repo.