identity-spiffe / portal
AGENTS.md11 starsChanged 6 months agoMITView on GitHub
Web-based management UI for live RBAC, admin governance, and A2A demonstrations. A FastAPI-backed single-page app that lets you: 1. Execute test requests between agents and see real-time results - normal SPIFFE path to BudgetBackend - direct A2A HTTPS path between selected agents 2. View and edit RBAC policies on any agent's sidecar 3. View and edit mTLS allow lists — add/remove SPIFFE IDs with immediate effect 4. Run security scans — automated detection of misconfigurations with one-click fixes 5. Demonstrate…
- Reads credentials
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- infra/AGENTS.mdAGENTS.md
- scripts/AGENTS.mdAGENTS.md
- tests/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- infra/CLAUDE.mdCLAUDE.md
- portal/CLAUDE.mdCLAUDE.md
- scripts/CLAUDE.mdCLAUDE.md
The file
Files
AGENTS.md — Identity Research for Agent Management Using SPIFFE Control Panel (Portal)
Web-based management UI for live RBAC, admin governance, and A2A demonstrations.
What This Is
A FastAPI-backed single-page app that lets you:
- Execute test requests between agents and see real-time results
- normal SPIFFE path to BudgetBackend
- direct A2A HTTPS path between selected agents
- View and edit RBAC policies on any agent's sidecar
- View and edit mTLS allow lists — add/remove SPIFFE IDs with immediate effect
- Run security scans — automated detection of misconfigurations with one-click fixes
- Demonstrate live policy changes — edit a rule, re-run a request, show the enforcement change
- Operate the live environment safely — dependency-aware health, durable policy config storage, and explicit admin-only mutation paths
How It Works
The portal talks to the dedicated admin-control-plane endpoint, which proxies management API calls to BudgetBackend via mTLS. This works because:
- BudgetBackend has
internal-onlyingress — not reachable from outside admin-control-planehasexternalingress and exists only for management/recovery trafficadmin-control-planeforwards/admin/*to BudgetBackend's sidecar/mgmt/*API on port 9443- BudgetApproval is now just a governed business agent; it is not the recovery path anymore
- Live A2A execution no longer hardwires to BudgetApproval. The portal sends the selected target to the caller app, which then calls the selected target's
/a2a/statusendpoint. - Production runtime is live-only. Simulated/demo responses are no longer part of the portal backend contract.
Key Files
portal/
├── app/ ← Modular FastAPI backend package
│ ├── main.py ← App factory + middleware + lifespan
│ ├── settings.py ← Local/cloud config loading and validation
│ ├── auth.py ← Entra auth + admin/viewer role checks
│ ├── clients/ ← Admin control-plane, agent, and Graph clients
│ ├── services/ ← Policy, scan, CA, and health services
│ └── storage/ ← File + Blob-backed policy config stores
├── index.html ← Main UI (vanilla JS, no framework)
├── server.py ← Thin compatibility wrapper / CLI entrypoint
├── portal-config.json ← Agent endpoints (git-ignored, generated by deploy.sh)
└── deploy-portal.sh ← Launch portal locally from generated live configRunning
# After deploy.sh completes (generates portal-config.json):
python3 portal/server.py --port 8550 --config portal/portal-config.json
# Open http://localhost:8550deploy.sh launches the portal only when --portal is supplied.
For cloud-only portal changes, prefer:
./deploy.sh --portal-onlyThat rebuilds and updates isp-portal and securityportal-mock without restarting agent sidecars or forcing SPIRE re-attestation.
Operational Notes
- Cloud startup now fails fast on missing
ADMIN_CP_URL,MGMT_API_KEY, Entra auth config, or Blob storage settings. - Saved policy configs use Azure Blob Storage in cloud and
policy-configs.jsononly for local development. /healthz/livereports process health,/healthz/readyreports dependency readiness, and/api/system-statusexposes dependency-level status to authenticated users.reload-configis local-only and should not be used as a cloud runtime mechanism.- For new deployments, portal app registrations are env-scoped:
Identity Research for Agent Management Using SPIFFE Portal - Management [<env>]andIdentity Research for Agent Management Using SPIFFE Portal - Security Portal Mock [<env>]. - The portal auth groups stay shared tenant-wide:
Agent Management AdministratorsandAgent Management Viewers. - Existing deployments stay on legacy Agent Blueprint naming until explicitly migrated.
./deploy.sh --portal-onlyis the preferred cloud deploy path for portal-only UI/backend changes; do not use it for agent-side or SPIRE-side changes.
This is the Identity Research for Agent Management Using SPIFFE control panel for live demonstrations and operational validation.
Read With This
docs/developer/portal-runtime.mddocs/reference/management-apis.mddocs/reference/authentication-flows.mddocs/architecture/portal-cloud-deployment.md
portal-config.json Format
{
"mode": "live",
"trust_domain": "aim.microsoft.com",
"resource_group": "rg-<env>",
"location": "eastus2",
"portal_port": 8550,
"agents": {
"budget-report": {
"name": "BudgetReport",
"app_name": "budget-report",
"url": "https://budget-report.<env>.eastus2.azurecontainerapps.io",
"spiffe_id": "spiffe://aim.microsoft.com/ests/bp/<bp-oid>/aid/<agent-oid>",
"entra_agent_id": "<agent-oid>",
"role": "Read-only Caller",
"entra_role": "BudgetFrontEnds"
},
"budget-backend": { "..." },
"employee-menus": { "..." },
"budget-approval": { "..." }
},
"control_plane": {
"name": "Admin Control Plane",
"app_name": "admin-control-plane",
"url": "https://admin-control-plane.<env>.eastus2.azurecontainerapps.io",
"spiffe_id": "spiffe://aim.microsoft.com/ests/bp/<bp-oid>/aid/<agent-oid>",
"entra_agent_id": "<agent-oid>",
"role": "Management Control Plane"
},
"spire_server_ip": "<vm-ip>",
"management_api_port": 9443,
"mgmt_api_key": "<key>"
}This file is git-ignored because endpoints change per deployment. Generated automatically by deploy.sh.
Agent Discovery (Cloud Mode)
In cloud mode (PORTAL_MODE=cloud), the portal discovers agents from admin-control-plane's /admin/agents endpoint at startup. Agent URLs are derived from CONTAINER_APP_ENV_DNS_SUFFIX at runtime — no static env vars needed. Dynamic agents appear automatically if they're in the RBAC policy.
Auth Token Handling
The api() JS helper retries on 401 by calling acquireTokenSilent. If silent refresh fails (e.g. MSAL cache expired overnight), it falls back to acquireTokenRedirect for an interactive login. Same pattern in security portal mock via the monkey-patched fetch wrapper.
Current Gotchas
- Policy push via the portal uses
Content-Type: application/x-yaml(raw YAML), not JSON-wrapped. - Cloud storage access depends on the portal Container App managed identity having
Storage Blob Data Contributoron the portal policy store. - The UI still accepts legacy
#/demo/...deep links for backward compatibility, but production behavior is live-only. - The portal app registrations are env-scoped for new deployments, while
Agent Management AdministratorsandAgent Management Viewersstay shared tenant-wide by design.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

