Saltar al contenido principal

Account integrations

Per-org credential links the admin operator wires through the alphaswarm_admin Next.js surface. Six integration kinds ship today:

KindPersisted underWizardBackend
huggingfaceCredentialKey("huggingface", "org:<org_id>")frontend/components/accounts/HuggingFaceWizard.tsxsrc/alphaswarm_admin/providers/huggingface.py
docker_hubCredentialKey("docker_hub", "org:<org_id>")frontend/components/accounts/DockerHubWizard.tsxsrc/alphaswarm_admin/providers/dockerhub.py
cloud_awsCredentialKey("cloud_aws", "org:<org_id>")frontend/components/cloud/CloudOnboardingWizard.tsxsrc/alphaswarm_admin/providers/cloud_aws.py
cloud_azureCredentialKey("cloud_azure", "org:<org_id>")frontend/components/cloud/CloudOnboardingWizard.tsxsrc/alphaswarm_admin/providers/cloud_azure.py
cloud_gcpCredentialKey("cloud_gcp", "org:<org_id>")frontend/components/cloud/CloudOnboardingWizard.tsxsrc/alphaswarm_admin/providers/cloud_gcp.py
cloud_cloudflareCredentialKey("cloud_cloudflare", "org:<org_id>")frontend/components/cloud/CloudOnboardingWizard.tsxsrc/alphaswarm_admin/providers/cloud_cloudflare.py

The four cloud_* kinds use the same AccountIntegrationProvider ABC but extend it with a 5-step wizard contract (bootstrap_artifactsvalidate_identityvalidate_permissionsenumerate_resourcesconnect) and are exclusively federated-first — no long-lived secrets are stored. See Connect a company cloud account for the full runbook.

Both share the same AccountIntegrationProvider ABC defined in alphaswarm_admin/src/alphaswarm_admin/providers/base.py and the same encrypted file-backed store at alphaswarm_admin/src/alphaswarm_admin/services/integration_store.py.

Lifecycle

The flow is audit-first (see alphaswarm_admin/src/alphaswarm_admin/api/routers/integrations.py) and step-up MFA gated (require_admin_step_up("admin:cluster")). The PAT itself never crosses the BFF response boundary after the initial connect call — the wizard renders the masked metadata (namespace, status, connected_at) only.

HuggingFace Hub

What you need

  • A fine-grained PAT with read access on the org's models / datasets. Generate at https://huggingface.co/settings/tokens.
  • The org's HuggingFace namespace (e.g. acme-quant). Optional — the BFF derives it from HfApi().whoami() when omitted.

Wire-format

POST /admin/accounts/{org_id}/integrations/huggingface
Authorization: Bearer <admin JWT, MFA-fresh>
Content-Type: application/json

{
"token": "hf_*****",
"namespace": "acme-quant"
}
{
"integration": {
"org_id": "org-acme",
"kind": "huggingface",
"namespace": "acme-quant",
"credential_key": "huggingface:org:org-acme",
"status": "healthy",
"connected_at": "2026-05-27T20:00:00Z",
"last_health_at": null,
"error": null,
"metadata": { "type": "org", "auth_email": "ops@example.com", "orgs": ["acme-quant"] }
},
"audit_run_id": "..."
}

Revocation

DELETE /admin/accounts/{org_id}/integrations/huggingface drops the local record. Always revoke the PAT on the HuggingFace side too — settings → Personal access tokens → Revoke. Without that step the PAT remains usable from any source that holds the bytes.

Docker Hub

What you need

  • A Docker Hub PAT (Account → Personal access tokens) with the intended scope. Username + PAT together are required (Docker Hub v2 login does not accept PAT-only).
  • The Docker Hub namespace (defaults to the username on connect).

Wire-format

POST /admin/accounts/{org_id}/integrations/dockerhub
{
"username": "acmeops",
"pat": "dckr_pat_*****",
"namespace": "acmeops"
}

The BFF posts to https://hub.docker.com/v2/users/login to mint a JWT (proving the credential is valid), then /v2/users/{namespace}/ to confirm namespace scope. Both calls happen server-side; only metadata returns to the wizard.

Revocation

DELETE /admin/accounts/{org_id}/integrations/docker_hub drops the local record only. Docker Hub does NOT expose a PAT-revocation API, so you must delete the PAT manually in Account → Security → Personal access tokens to fully terminate access.

Health checks

The wizard's "Re-check" action calls POST /admin/accounts/{org_id}/integrations/{kind}/health which re-runs the whoami (HuggingFace) or login + namespace probe (Docker Hub). The result lands on the row's last_health_at / last_health_status fields and is rendered as a badge.

Operator runbook

ScenarioAction
PAT expired upstreamRe-run the wizard; the new PAT replaces the encrypted blob in-place.
PAT compromisedRevoke upstream first, then disconnect locally.
Switching org ownersDisconnect, delete the PAT upstream, have the new owner connect with their own PAT.
Lost encryption key (ALPHASWARM_ADMIN_INTEGRATIONS_KEY)Drop the local store JSON, rotate the encryption key, re-run all connect wizards. The upstream PATs are unaffected.

Configuration

Env varPurposeDefault
ALPHASWARM_ADMIN_INTEGRATIONS_PATHJSON file the encrypted store writes to.~/.alphaswarm/integrations.json
ALPHASWARM_ADMIN_INTEGRATIONS_KEYFernet key used to encrypt PATs. Required in production.(ephemeral key minted per process — refused in production by IntegrationCredentialStore.assert_production_ready)

Generate a Fernet key with:

from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())

Persist the key in your platform secret manager and inject it as an env var; the store reads it once at boot.