Saltar al contenido principal

Cloud credentials

How AlphaSwarm routes secret resolution through CredentialResolver once the cloud SecretStore siblings are wired. Phase C of the Phase 7 rollout (Terraform IaC + multi-cloud).

Resolver chain

Lower priority numbers resolve first. The cloud store is added to the default chain only when ALPHASWARM_DEFAULT_CLOUD_PROVIDER matches and the matching SDK is installed (see alphaswarm/credentials/resolver.py::_build_default_resolver).

Naming conventions

StoreKey formatNotes
Env<SERVICE>_<PURPOSE> (uppercase, :_)Always-on safety net.
Filebootstrap_state_dir/<service>-<purpose>.jsonBootstrap workflows write these (Polaris principal, etc).
Azure Key Vaultalphaswarm-<service>-<purpose> (alphanumerics + - only)Vault names disallow : / / / _.
AWS Secrets Mgr{prefix}<service>/<purpose> (default prefix alphaswarm/)Slashes are first-class path separators.
GCP Secret Mgrprojects/{project}/secrets/{prefix}<service>-<purpose>Names allow [A-Za-z0-9_-] only — joins use -.
Vault KV v2<mount>/data/<service>/<purpose>hvac.Client.secrets.kv.v2.read_secret_version adds /data/ automatically.

The cloud secret values are parsed as JSON first; when parsing fails they're exposed via the canonical credential field.

Example secret layouts

Azure Key Vault — alphaswarm-msal-clientsecret

{
"client_secret": "rxq8Q..."
}

AWS Secrets Manager — alphaswarm/broker/api_key

sk_live_abcdef1234567890

Plain string payload — exposed via credential.get("credential").

GCP Secret Manager — alphaswarm-postgres-password

{
"password": "...",
"username": "alphaswarm"
}

HashiCorp Vault KV v2 — secret/data/alphaswarm/redis/password

{
"password": "..."
}

Wiring a SecretStore

Pick a cloud + install the matching extra:

pip install 'alphaswarm[cloud-azure]'   # AzureKeyVaultStore
pip install 'alphaswarm[cloud-aws]' # AwsSecretsManagerStore
pip install 'alphaswarm[cloud-gcp]' # GcpSecretManagerStore
pip install 'alphaswarm[vault]' # HashicorpVaultStore

Configure (matching cloud picked via ALPHASWARM_DEFAULT_CLOUD_PROVIDER):

# Azure
ALPHASWARM_DEFAULT_CLOUD_PROVIDER=azure
ALPHASWARM_AZURE_TENANT_ID=...
ALPHASWARM_AZURE_SUBSCRIPTION_ID=...
ALPHASWARM_AZURE_KEYVAULT_URL=https://alphaswarm-vault.vault.azure.net/

# AWS
ALPHASWARM_DEFAULT_CLOUD_PROVIDER=aws
ALPHASWARM_AWS_REGION=us-east-1
ALPHASWARM_AWS_ACCOUNT_ID=123456789012
ALPHASWARM_AWS_SECRETSMANAGER_PREFIX=alphaswarm/

# GCP
ALPHASWARM_DEFAULT_CLOUD_PROVIDER=gcp
ALPHASWARM_GCP_PROJECT_ID=alphaswarm-prod
ALPHASWARM_GCP_REGION=us-central1
ALPHASWARM_GCP_SECRET_PREFIX=alphaswarm-

# Vault (any cloud)
ALPHASWARM_VAULT_ADDR=https://vault.example.com
ALPHASWARM_VAULT_NAMESPACE=...
ALPHASWARM_VAULT_MOUNT=secret
ALPHASWARM_VAULT_ROLE_ID=...
ALPHASWARM_VAULT_SECRET_ID=...

The resolver auto-adds the matching cloud store + Vault store when the env vars are present. Code that needs a credential does:

from alphaswarm.credentials import get_resolver
from alphaswarm.credentials.protocol import CredentialKey

resolver = get_resolver()
cred = resolver.resolve(CredentialKey(service="msal", purpose="client_secret"))
secret = cred.require("client_secret")

Authentication backends per cloud store

StoreIdentity source
Azure Key VaultDefaultAzureCredential (az login / SP env / Workload Identity)
AWS Secrets Managerboto3 default chain (env / shared credentials / IRSA / EC2 role)
GCP Secret Managergoogle.auth.default() (gcloud ADC / SA file / Workload Identity)
HashiCorp VaultAppRole (preferred) or whatever the operator pre-configured

For cluster-side workloads the Workload Identity variants are the canonical path:

  • AKS — AzureAksAdapter + Azure Workload Identity (Service Account annotation azure.workload.identity/client-id: <managed-identity>).
  • EKS — AwsEksAdapter + IRSA (eks.amazonaws.com/role-arn annotation).
  • GKE — GcpGkeAdapter + GKE Workload Identity (iam.gke.io/gcp-service-account annotation).

External Secrets Operator integration

The Terraform secrets module wires an external-secrets ClusterSecretStore pointing at whichever backend matches vault_backend. The secret_mappings locals block emits one ExternalSecret per (k8s_secret_name, vault_path) pair so AlphaSwarm pods consume secrets via mounted Secrets — never raw env vars.

See alphaswarm_platform/terraform/modules/secrets/main.tf for the full mapping table.

Temporary credentials minted via cloud CLI

Operators with an admin:cluster scope can mint short-lived credentials directly from the admin UI without shipping the cloud CLI binaries into the BFF container. The control plane wraps aws sts assume-role / gcloud auth print-access-token / az account get-access-token in an audit-first subprocess runner; the resulting credential is persisted under a resolver key supplied by the operator and surfaces through the standard CredentialResolver.resolve(...) chain. See the cloud-CLI temporary credentials runbook for the wizard walkthrough, audit shape, and step-up MFA contract.