alphaswarm_admin — Microsoft Entra Agent Identity
Last refreshed: 2026-05-27. Status: implementation of the alphaswarm_admin Entra refactor (
.cursor/plans/alphaswarm_admin_entra_refactor_039f2aeb.plan.md). See also: entra-internal-tenant.md and identity.md.
The alphaswarm_admin BFF authenticates to alphaswarm_controller,
the AlphaSwarm monolith, and (eventually) any other downstream service via
a per-deployment Microsoft Entra Agent Identity instead of a shared
client_credentials service principal. Each deployment (dev / staging /
prod) gets its own sub claim in minted tokens so audit trails and
RBAC routing remain clean even when the same Blueprint backs every
environment.
This page is the operator + agent reference for the model.
Three-layer object graph
| Layer | Resource | Provider |
|---|---|---|
| 1 | Agent Identity Blueprint | msgraph_resource.blueprint — the microsoft/msgraph provider posting to applications/microsoft.graph.agentIdentityBlueprint (the azuread/azapi providers cannot manage Microsoft.Graph/* typed resources) |
| 2 | BlueprintPrincipal (mandatory second step) | msgraph_resource.blueprint_principal against servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal |
| 3 | Per-environment Agent Identity | msgraph_resource.agent_identity against servicePrincipals/microsoft.graph.agentIdentity |
| 4 | Federated Identity Credential | msgraph_resource.blueprint_fic against applications/{id}/microsoft.graph.agentIdentityBlueprint/federatedIdentityCredentials |
| 5 | App role assignment | azuread_app_role_assignment (the standard azuread provider resource — used because app role assignments have a typed azuread resource, unlike the Agent Identity kinds above) |
Terraform module:
alphaswarm_platform/terraform/modules/alphaswarm_admin_agent_identity/.
Two-step fmi_path exchange
At runtime each pod mints an Agent-Identity-bound access token via the
two-step exchange documented in the entra-agent-id skill:
The exchange lives at
alphaswarm_core.auth.providers.msal_entra.MsalEntraValidator.acquire_agent_token.
CredentialResolver integration
The admin BFF wires the Agent Identity flow through the existing
SecretStore chain so route handlers never see the token directly.
from alphaswarm_core.credentials.stores import (
EntraAgentIdentityCredentialResolver,
EntraAgentIdentitySecretStore,
)
from alphaswarm_core.auth.providers.msal_entra import MsalEntraValidator
store = EntraAgentIdentitySecretStore(
validator=MsalEntraValidator(
tenant="<staff-tenant-uuid>",
audience="api://alphaswarm-controller",
),
resolvers=(
EntraAgentIdentityCredentialResolver(
credential_key=CredentialKey(
service="alphaswarm-admin-to-cp",
purpose="client_credentials",
),
audience="api://alphaswarm-controller",
blueprint_app_id=<blueprint app id>,
agent_identity_id=<per-env agent identity object id>,
fmi_path="alphaswarm-admin-prod",
),
),
)
alphaswarm_admin/integrations/broker.py::build_default_brokers does this
automatically when
ALPHASWARM_AUTH_AGENT_IDENTITY_ENABLED=true AND the three Agent
Identity env vars are populated. When any of the fields are empty the
broker falls back to the legacy env-only client_credentials path so
local-dev sandboxes keep working.
Receiver-side recognition
alphaswarm_controller.auth.deps._identity_to_user maps the
actor_kind / actor_upstream_sub fields resolved by central auth
introspection (which reads the RFC 8693 act claim) onto the
resolved AuthenticatedUser. Recognition
is feature-flagged behind
ALPHASWARM_AUTH_AGENT_TOKEN_RECOGNITION_ENABLED until the end-to-end
path is verified — when off, every token resolves to
actor_kind="user" and the legacy audit shape is preserved.
The monolith side (alphaswarm/api/routes/_internal_audit.py) logs the
actor_kind + actor_upstream_sub on every persisted terraform_runs
ingest call so the audit ledger stays correlatable with the Agent
Identity that minted the token.
Identity on AWS ECS Fargate
When alphaswarm_admin runs on ECS Fargate (the
ecs-fargate-control-plane
module) two identities are in play, and they are orthogonal:
- AWS control — the
/admin/platform/ecs/*surface calls AWS ECS + CloudWatch using the task's AWS IAM role, not Entra (alphaswarm_admin/src/alphaswarm_admin/api/routers/platform.pyandservices/platform_deployment.py). Per-service task-role policy ARNs are supplied to theecs-fargate-control-planemodule via itsservicesvariable (task_role_policy_arns) rather than a dedicated module toggle. No Entra token is involved in the AWS control path. - Control-plane M2M — outbound calls to
alphaswarm-cp/manage/*still need an Entra-minted token. ECS Fargate has no native OIDC issuer for the WIF JWT the two-stepfmi_pathexchange needs, so the ECS-hosted admin routes M2M through the controller's/auth/m2m/tokenshim by settingALPHASWARM_AUTH_THROUGH_CONTROLLER=true. The controller (EKS-hosted, with a projected service-account token) holds the Agent Identity federation and mints on the admin's behalf.
The Agent Identity Blueprint + per-environment identities this module
provisions therefore back the EKS-hosted control plane and any admin
pod that can present a federated SA token. The module's
blueprint_app_id and agent_identity_ids (a map of environment
slug -> Agent Identity object id) outputs plumb directly into the
ALPHASWARM_AUTH_AGENT_BLUEPRINT_APP_ID / ALPHASWARM_AUTH_AGENT_IDENTITY_ID
env vars for a task definition or ConfigMap in those deployments.
Operator workflow
# 1. Pre-check (one-time): grant the Terraform-execution SP the Graph
# permissions the entra-agent-id skill lists.
# 2. Snapshot (from the alphaswarm monolith checkout) + apply
# (step-up MFA gated; AGENTS rule 42 + 52). NOTE: as of this writing
# the installed alphaswarm-cli has no `manage terraform` command; the
# nearest verified equivalent is the `cp terraform` group, which takes
# a plan_run_id rather than a spec-version-id:
python ../alphaswarm/scripts/identity/seed_admin_agent_identity.py --apply
alphaswarm-cli cp terraform plan admin-entra
alphaswarm-cli cp terraform apply admin-entra <plan_run_id from plan>
# 3. Plumb outputs into CredentialResolver. There is no dedicated
# `alphaswarm-cli credentials import` command today — do this via
# whatever CredentialResolver-writing path your deployment uses (e.g.
# the IntegrationCredentialStore / secret-manager injection described
# in account-integrations.md), keyed as:
# service=alphaswarm-admin, purpose=entra_agent_identity
# blueprint_app_id=<output>, agent_identity_id_prod=<output>
# 4. Flip the feature flag on each deployment.
ALPHASWARM_AUTH_AGENT_IDENTITY_ENABLED=true
ALPHASWARM_AUTH_AGENT_BLUEPRINT_APP_ID=<output>
ALPHASWARM_AUTH_AGENT_IDENTITY_ID=<output>
ALPHASWARM_AUTH_AGENT_FMI_PATH=alphaswarm-admin-prod
Rollback
The Terraform module is gated by var.enabled; flipping it to false
removes the per-environment Agent Identities + role assignments while
keeping the Blueprint + BlueprintPrincipal in place for fast re-enable.
The alphaswarm_admin BFF falls back to the legacy client_credentials
path automatically (via EnvSecretStore at priority 100).
For the human-login path, the legacy Vite SPA at alphaswarm_admin_ui/
and its time-boxed Auth0 rollback branch no longer exist: Phase 3.11
retired that SPA (and its ALPHASWARM_ADMIN_LEGACY_AUTH0_FALLBACK
flag) once the Next.js 15 frontend/ reached parity, removing the
last Auth0 rollback path from alphaswarm_admin. frontend/ is now
the canonical and sole admin frontend, and it is Entra-only.