Saltar al contenido principal

Cloud-CLI temporary credentials

How to use the CloudCliCredentialWizard in the admin Settings page to mint a short-lived AWS / GCP / Azure credential without shipping the parent credential or the cloud CLI binary into the admin BFF container.

Topology

The CLI subprocess only runs inside alphaswarm_controller. The admin BFF (alphaswarm_admin) is HTTP-only per its boundary contract; it never spawns processes or holds the parent credential.

Prerequisites

The control plane host needs the CLI binary on $PATH:

ProviderBinaryRequired pre-auth
AWSawsparent IAM identity (instance profile / IRSA / access key) with sts:AssumeRole on the target role
GCPgcloudADC (Application Default Credentials) for an identity with iam.serviceAccounts.getAccessToken on the target SA
Azureazlogged-in az session (az login --identity for managed identity, or interactive) on a principal that can issue tokens for the requested resource

The wizard's preview step renders a binary present on CP host flag so the operator can spot a missing CLI before they hit Execute mint.

Walkthrough

1. Pick a provider + fill the form

Open Settings → Cloud-CLI temporary credential mint. The wizard loads handler metadata from /admin/settings/credentials/cloud-cli/handlers (proxied to the CP) and renders the appropriate fields:

ProviderRequired
AWStarget_credential_key, role_arn
GCPtarget_credential_key, service_account_email
Azuretarget_credential_key (resource / tenant / subscription optional)

target_credential_key is the resolver key the minted credential persists under (e.g. idp:aws:prod). Downstream code reads it via CredentialResolver.resolve(CredentialKey(<service>, <purpose>)) once minted; nothing in the platform passes the bytes directly.

2. Preview

Clicking Preview command posts to /admin/settings/credentials/cloud-cli/preview which returns the exact argv the CP would spawn, with token-bearing args masked. This is a dry run — no subprocess executes.

3. Mint

Execute mint posts to /admin/settings/credentials/cloud-cli/sts. Server-side the CP:

  1. writes a WorkloadRun audit row with action=mint_cloud_credential in PENDING state before spawning the subprocess;
  2. invokes aws sts assume-role / gcloud auth print-access-token / az account get-access-token with a 60s wall-clock timeout;
  3. parses the result, persists the credential under target_credential_key via the resolver chain;
  4. updates the audit row to SUCCEEDED|FAILED.

The wizard renders the response envelope:

FieldMeaning
credential_keyresolver key the temp creds live under
expires_atTTL boundary (provider-derived)
source_identityrole ARN / SA email / subscription id
audit_run_idlinks to the WorkloadRun ledger row

The raw token is never in the response body or audit ledger.

Step-up MFA

/admin/settings/credentials/cloud-cli/{preview,sts} carry Depends(require_admin_step_up("admin:cluster")). If the operator's JWT is older than the configured auth_step_up_default_max_age (default 180s), the BFF returns 401 insufficient_user_authentication with an RFC 9470 WWW-Authenticate challenge; the wizard's apiFetch middleware silently re-issues an MFA prompt and retries the original call.

Troubleshooting

SymptomCauseFix
binary_missing in the previewCLI not on the CP host's $PATHInstall the CLI in the CP container image, or shell into the host and run which aws/gcloud/az
nonzero_exit with masked stderrParent credential lacks the requested permissionRead the redacted stderr in the audit row's error field; provision the missing role / IAM permission
parse_errorUpstream returned an unexpected JSON shapeCompare against the canonical aws sts assume-role / az account get-access-token shape in the AWS / Azure docs; file a bug if AWS/Azure changed the format
timeoutNetwork / IAM trust-policy resolution stuckThe 60s budget is intentional — re-run; if it persists, run the masked argv from the preview locally to inspect
persist_failedResolver write surface not configuredThe default CP resolver doesn't ship a write hook in OSS; provide one via the persist= kwarg of alphaswarm_controller.services.cloud_cli.mint, or wire a Vault / SSM secret manager that supports writes