Connect a company cloud account
The cloud onboarding wizard in alphaswarm_admin (route
/admin/accounts/{org_id}/cloud/{cloud_kind}/*) is the canonical
path for wiring an AWS, Azure, GCP, or Cloudflare account into AlphaSwarm.
It is federated-first by design: no access keys, no client secrets,
no service-account JSON, and no global API keys are ever stored.
The same UI serves both flows:
- Per customer organisation —
/accounts/<org_id>/integrations→ "Cloud accounts" section. - Admin tenant (AlphaSwarm's own accounts) —
/settingspage, "Cloud connections" panel, "Guided (federated)" mode. Routes use the syntheticorg_id="__platform__"value.
Step 0 — pre-requisites
Set these env vars on the alphaswarm_admin deployment before the wizard
can emit bootstrap artifacts. None of them are secrets on their own,
but the wizard rejects bootstrap calls when the corresponding
identity is missing.
| Env var | Purpose | Required for |
|---|---|---|
ALPHASWARM_ADMIN_AWS_PARTNER_ACCOUNT_ID | AlphaSwarm's AWS account id (12 digits) embedded as the trust policy's Principal.AWS. | AWS |
ALPHASWARM_ADMIN_CLOUD_AWS_EXTERNAL_ID_SECRET | HMAC key used to derive a stable per-org sts:ExternalId. | AWS (prod) |
ALPHASWARM_ADMIN_AZURE_APP_CLIENT_ID | Client id of the AlphaSwarm Entra app that will carry the federated credential. | Azure |
ALPHASWARM_ADMIN_AZURE_APP_OBJECT_ID | Object id of the same app — parent for az ad app federated-credential create. | Azure |
ALPHASWARM_ADMIN_GCP_WIF_AUDIENCE | Audience template for the customer's WIF provider. | GCP |
ALPHASWARM_ADMIN_GCP_WIF_SERVICE_ACCOUNT_EMAIL | AlphaSwarm-side service account the customer's WIF principal impersonates. | GCP |
The customer-side bootstrap also needs network egress from the admin BFF to each cloud's control plane (AWS STS, Microsoft Graph, GCP IAM, Cloudflare API). The wizard surfaces clear errors when a call fails.
The five-step pattern
| Step | Mutates AlphaSwarm? | Mutates cloud? | Audit row? |
|---|---|---|---|
| 1 Choose cloud + auth method | no | no | no |
| 2 Bootstrap artifacts | no | no | no |
| 3 Validate identity | no | read-only | yes |
| 4 Validate permissions | no | read-only | yes |
| 4* Enumerate resources | no | read-only | yes |
5 Save (connect) | yes | no | yes (pending + succeeded/failed) |
Steps 3, 4, 5 require step-up MFA per hard rule 52.
Per-cloud runbooks
AWS — cross-account IAM role + external id
-
Step 2 — bootstrap. The wizard emits a trust policy that names AlphaSwarm's account as the
Principal.AWSand includes a uniquests:ExternalIdderived fromHMAC-SHA256(ALPHASWARM_ADMIN_CLOUD_AWS_EXTERNAL_ID_SECRET, "<cloud_kind>:<org_id>").Copy the rendered
trust_policy.jsonblock or use the CloudFormation StackSet quick-link the wizard surfaces. The default role name isalphaswarm-broker-<org_id>(configurable viaALPHASWARM_ADMIN_AWS_ROLE_NAME_PATTERN).aws iam create-role \
--role-name alphaswarm-broker-<org_id> \
--assume-role-policy-document file://trust_policy.jsonAttach the policies the wizard hint suggests (
ReadOnlyAccessfor a minimal connection; tighter policies for production). -
Step 3 — validate identity. Paste the resulting Role ARN into the wizard. AlphaSwarm calls
sts:AssumeRolewith the same external id, thensts:GetCallerIdentity. Failure modes:AccessDenied(trust policy not applied or wrong external id),InvalidParameterValue(role doesn't exist), orRegionDisabled. -
Step 4 — validate permissions. AlphaSwarm runs
iam:SimulatePrincipalPolicyagainst the role forsts:GetCallerIdentity,iam:GetRole, andec2:DescribeRegions(the baseline). Missing permissions render as a red "Missing required" badge. -
Step 5 — save. AlphaSwarm persists
{role_arn, external_id, region, account_id}underCredentialKey("cloud_aws", "org:<org_id>")and thealphaswarm_admin.integration_storetable.
Azure — Workload Identity Federation
-
Step 2 — bootstrap. The wizard emits a federated-credential JSON skeleton keyed to the AlphaSwarm Entra app's
object_id. Default audience isapi://AzureADTokenExchange(override viaALPHASWARM_ADMIN_AZURE_AUDIENCE).az ad app federated-credential create \
--id <ALPHASWARM_ADMIN_AZURE_APP_OBJECT_ID> \
--parameters federated_credential.jsonOn the customer's subscription, grant the AlphaSwarm app a role (default:
Reader) at the appropriate scope. -
Step 3 — validate identity. Provide the customer
tenant_idandsubscription_id. AlphaSwarm acquires a token via the federated credential and resolves the token's claims; failures typically point to a subject/issuer mismatch on the federated credential. -
Step 4 — validate permissions. AlphaSwarm lists role assignments at the subscription scope and compares against the
required_rolesbaseline. -
Step 5 — save. Stored under
CredentialKey("cloud_azure", "org:<org_id>"). No client secret is ever provided to or stored by AlphaSwarm — the federated credential is the only artifact.
GCP — Workload Identity Federation + impersonation
-
Step 2 — bootstrap. The wizard emits a Workload Identity Pool + Provider config (issuer URI, allowed audiences,
attribute_mapping) plus threegcloudinvocations:gcloud iam workload-identity-pools create alphaswarm-broker-<org_id> \
--project=<project_id> --location=global \
--display-name="AlphaSwarm broker <org_id>"
gcloud iam workload-identity-pools providers create-oidc alphaswarm-oidc \
--project=<project_id> --location=global \
--workload-identity-pool=alphaswarm-broker-<org_id> \
--issuer-uri=https://alpha-swarm.ai/oidc/ \
--allowed-audiences="<ALPHASWARM_ADMIN_GCP_WIF_AUDIENCE>" \
--attribute-mapping="google.subject=assertion.sub"
gcloud iam service-accounts add-iam-policy-binding \
<ALPHASWARM_ADMIN_GCP_WIF_SERVICE_ACCOUNT_EMAIL> \
--project=<project_id> \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/alphaswarm-broker-<org_id>/*" -
Step 3 — validate identity. AlphaSwarm impersonates the configured service account and confirms the impersonation chain works.
-
Step 4 — validate permissions. AlphaSwarm calls
projects.testIamPermissionsfor the baseline (resourcemanager.projects.get,iam.serviceAccounts.actAs). -
Step 5 — save. Stored under
CredentialKey("cloud_gcp", "org:<org_id>").
Cloudflare — scoped API token
There is no federated identity option for Cloudflare; the federated-first equivalent is the scoped API token (the deprecated Global API key is rejected outright).
-
Step 2 — bootstrap. Pick the narrowest template that covers the use case:
dns_edit,tunnel,access,worker, orr2. The wizard opens https://dash.cloudflare.com/profile/api-tokens and the customer creates the token in the dashboard. -
Step 3 — validate identity. Paste the token into the wizard. AlphaSwarm calls
GET /user/tokens/verifyand confirmsstatus == active. The token is never echoed back to the wizard after submission. -
Step 4 — validate permissions. AlphaSwarm inspects the verified token's permission groups against the template baseline.
-
Step 5 — save. Stored encrypted at rest in the
IntegrationCredentialStore(Fernet-wrapped) underCredentialKey("cloud_cloudflare", "org:<org_id>").
Rotation
| Cloud | Auth method | Rotation duty |
|---|---|---|
| AWS | IAM role + external id | None for the role itself. Rotate the HMAC key (ALPHASWARM_ADMIN_CLOUD_AWS_EXTERNAL_ID_SECRET) when an operator with insider knowledge leaves — re-running the wizard regenerates a new external id and the customer updates the trust policy. |
| Azure | Workload Identity Federation | None — no client secret to rotate. |
| GCP | WIF + impersonation | None — no JSON key to rotate. |
| Cloudflare | Scoped API token | 60–90 days recommended. The wizard re-validates the token through the health route; an expires_on timestamp surfaces in the integration list. |
Disconnect
DELETE /admin/accounts/{org_id}/cloud/{cloud_kind} drops the local
record. Vendor-side cleanup (delete the IAM role, delete the
federated credential, delete the WIF pool, revoke the scoped token)
is the operator's responsibility — the runbook calls this out
because vendor APIs that delete principals require elevated
permissions AlphaSwarm intentionally does not request.
Where to look in code
- ABC + lifecycle helpers:
alphaswarm_admin/src/alphaswarm_admin/providers/base.py - Per-cloud providers:
cloud_aws.py,cloud_azure.py,cloud_gcp.py,cloud_cloudflare.py - Router:
alphaswarm_admin/src/alphaswarm_admin/api/routers/cloud_onboarding.py - Shared frontend wizard:
alphaswarm_admin/frontend/components/cloud/CloudOnboardingWizard.tsx - Settings:
alphaswarm_admin/src/alphaswarm_admin/settings.py(thecloud_*field block).
See also
- Account integrations — sibling per-org integrations (HuggingFace, Docker Hub).
- Cloud-CLI temporary credentials — short-lived credential mint surface, complementary to the long-lived federated identity established here.
- Credentials — the
CredentialResolverchain that backs persistence (hard rule 26).