Skip to content

Cloud credentials

The AWS and GCP connectors need cloud credentials to read. There are two modes, and they are orthogonal to the secret store: that one decides where secrets live, this one decides how cloud credentials are resolved.

Terminal window
RUNNER_AWS_CRED_MODE=static # default
RUNNER_AWS_CRED_MODE=chain
RUNNER_GCP_CRED_MODE=static # default
RUNNER_GCP_CRED_MODE=chain

Reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and optionally AWS_SESSION_TOKEN from the secret store and injects them explicitly into the client.

Serves anyone handed ready-made keys, or keeping them in Vault or Secrets Manager. It’s the default for backward compatibility.

Injects no key at all. The SDK’s default credential chain resolves it: IRSA on EKS, task role on ECS, instance profile on EC2, environment variables, or the SSO cache.

It’s the correct mode when the runner runs inside AWS, and it’s what keeps static keys out of circulation.

Terminal window
RUNNER_AWS_CRED_MODE=chain
AWS_PROFILE=my-profile # in development, with aws sso login

A subtlety that causes an invisible connector

Section titled “A subtlety that causes an invisible connector”

The served set is secret-aware: a connector whose required keys are missing drops out of the announced set. But in chain mode the credential doesn’t come from the secret store, so without special handling, the runner would not announce the aws.* operations even while working perfectly.

That’s why the runtime marks the aws connector as always served in chain mode. Worth knowing this special case exists, so the behavioral difference between the two modes doesn’t surprise you.

chain mode is single-account by construction. For several AWS accounts, run one runner per account, each with its own IRSA identity. The graph is merged on the control-plane side.

With RUNNER_CONNECTORS=real, the runner runs a best-effort STS probe at boot to discover the account and region, and reports that in the handshake. It’s what lets the control-plane resolve the tenant’s AWS context from the live runner, instead of manual configuration.

The probe never throws. If it fails, the information simply doesn’t go, and the control-plane uses its fallback.

The design is the exact sibling of the AWS side.

Reads the service account’s JSON key (GCP_SA_KEY, the JSON on a single line) from the secret store and builds the clients with it.

Injects no key. ADC resolves it: Workload Identity on GKE, metadata on GCE, the file pointed at by GOOGLE_APPLICATION_CREDENTIALS, or gcloud.

With chain, GCP_SA_KEY isn’t needed.

Terminal window
RUNNER_GCP_CRED_MODE=chain
GCP_PROJECT_ID=my-project

Also single-project: for several projects, one runner per project, each with its own Workload Identity GSA.

Variable Notes
AWS_REGION Used by the AWS connectors and required for aws-sts attestation.
EKS_CLUSTER Without it, the EKS health check answers skipped: no cluster configured. The connector shows up as unconfigured in Fleet, which is different from broken and equally blind.
GCP_PROJECT_ID Target project.
GCP_REGION Target region.
GCP_BILLING_EXPORT_TABLE BigQuery billing-export table. Without it, the GCP cost operation fails explicitly.