Auth flags
Every --aws-*, --azure-* and --gcp-* flag of cloudg run, the config key it fills, the environment variable cloudg falls back to, and which method wins when several are set.
The credential flags exist on cloudg run only. Each one writes a single field of the loaded config and changes nothing else, so you can mix flags with values from config.yaml. cloudg map takes the same settings from config.yaml (it has --profile and nothing else). cloudg collect uses neither and works from the environment and default chains alone. The Authentication guide covers the identities, roles and permissions each method needs; this page is about the flags.
Secrets on the command line
Values passed as flags can be seen in your shell history and, while cloudg runs, in the process list of the machine. Prefer the environment variables or a config.yaml with tight file permissions for secrets such as --aws-secret and --azure-client-secret.
AWS¶
| Flag | Config key | Environment fallback |
|---|---|---|
--aws-key |
aws.access_key_id |
AWS_ACCESS_KEY_ID, through the boto3 default chain |
--aws-secret |
aws.secret_access_key |
AWS_SECRET_ACCESS_KEY, same |
--aws-session-token |
aws.session_token |
AWS_SESSION_TOKEN, same |
--aws-role-arn |
aws.role_arn |
none |
--aws-external-id |
aws.external_id |
none |
--aws-web-identity-token-file |
aws.web_identity_token_file |
AWS_WEB_IDENTITY_TOKEN_FILE, read by cloudg |
--profile |
aws.profile |
AWS_PROFILE, through the boto3 default chain |
cloudg builds the base session from the first method that is complete, then optionally assumes a role on top:
flowchart TD
A{"Key and secret both set?"} -->|yes| K["Direct keys, plus session token if set"]
A -->|no| B{"Role ARN and token file set?"}
B -->|yes| W["AssumeRoleWithWebIdentity into the role"]
B -->|no| C{"Profile set?"}
C -->|yes| P["Named profile, SSO included"]
C -->|no| D["boto3 default chain"]
K --> R{"Role ARN set?"}
P --> R
D --> R
R -->|yes| S["sts:AssumeRole, with ExternalId if set"]
How cloudg picks AWS credentials
- Direct keys need both
--aws-keyand--aws-secret. One without the other is ignored and the next method is tried.--aws-session-tokenis added when present, for temporary keys. - Web identity federation needs a role ARN and a token file. The token file comes from
--aws-web-identity-token-file, or fromAWS_WEB_IDENTITY_TOKEN_FILEwhen the flag is absent. This is the pattern for GitHub Actions, GitLab CI and EKS, with no stored keys. - A named profile, from
--profile. - The boto3 default chain: environment keys, the shared credentials file, the SSO cache, container credentials and the instance role.
Then the role hop. If --aws-role-arn is set and step 2 did not already use it, cloudg calls sts:AssumeRole into it with the session name aws.role_session_name (default cloudg-scan) for one hour, passing --aws-external-id as ExternalId when given. When cloudg collects the accounts in aws.accounts, it then assumes aws.role_name in each of them, from the --aws-role-arn session when there is one (role chaining). An aws.accounts list without aws.role_name is rejected before anything runs.
One interaction catches people on EKS. With IRSA, AWS_WEB_IDENTITY_TOKEN_FILE is already set in the pod. If you then pass --aws-role-arn, cloudg federates straight into that role with the pod's token, instead of assuming it from the pod's own role. The target role's trust policy must accept the cluster's OIDC provider.
Azure¶
| Flag | Config key | Environment fallback |
|---|---|---|
--azure-tenant-id |
azure.tenant_id |
AZURE_TENANT_ID |
--azure-client-id |
azure.client_id |
AZURE_CLIENT_ID |
--azure-client-secret |
azure.client_secret |
AZURE_CLIENT_SECRET |
--azure-cert-path |
azure.certificate_path |
none read by cloudg |
--azure-federated-token-file |
azure.federated_token_file |
AZURE_FEDERATED_TOKEN_FILE |
--azure-managed-identity |
azure.use_managed_identity |
none |
--subscription-id |
azure.subscription_ids |
none on run; AZURE_SUBSCRIPTION_ID on collect |
cloudg reads each setting from the config first and from the environment variable second, then tries the methods in this order:
- Workload identity federation: tenant ID, client ID and a federated token file.
- Service principal with a client secret: tenant ID, client ID and secret.
- Service principal with a certificate: tenant ID, client ID and
--azure-cert-path(PEM or PKCS12). - Managed identity, when
--azure-managed-identityis set. For a user-assigned identity, put its client ID inazure.managed_identity_client_id; there is no flag for it. DefaultAzureCredential, which covers environment variables,az login, Azure PowerShell and managed identity.
Methods 1 to 3 need the tenant ID and client ID. If either is missing, cloudg skips straight to 4 or 5. The order also means that AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET left in the environment beat --azure-managed-identity. Unset them if you want the managed identity.
GCP¶
| Flag | Config key | Environment fallback |
|---|---|---|
--gcp-credentials-file |
gcp.credentials_file |
GOOGLE_APPLICATION_CREDENTIALS, through application default credentials |
--gcp-impersonate-sa |
gcp.impersonate_service_account |
none |
--project-id |
gcp.project_ids |
the credentials' default project |
--gcp-credentials-file takes a service account key JSON or a workload identity federation config ("type": "external_account"); both load the same way. Without it, cloudg uses application default credentials: the file in GOOGLE_APPLICATION_CREDENTIALS, your gcloud auth application-default login session, or the metadata server on GCE, GKE and Cloud Run.
--gcp-impersonate-sa adds a hop on top of either: cloudg impersonates that service account with the cloud-platform scope. The base identity needs roles/iam.serviceAccountTokenCreator on it.
What the scanners get¶
The flags above configure cloudg's own collection. cloudg run, cloudg scan and CloudGEngine.scan() resolve the same AWS credentials once more, in the same order, and hand them to the scanner subprocesses:
| Scanner | Credentials passed |
|---|---|
| Prowler and ScoutSuite (AWS) | With role_arn (--aws-role-arn, also through --aws-web-identity-token-file): cloudg assumes the role and exports its temporary AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN. With direct keys: the keys and the session token. Otherwise: aws.profile (or --profile) as -p for Prowler and --profile for ScoutSuite. Everything else in cloudg's environment is inherited. |
| Prowler and ScoutSuite (Azure, GCP) | nothing; they use their own defaults and whatever *_extra_args you configure |
| Checkov, Trivy | nothing; they scan files and images |
Explicit regions in aws.regions go to Prowler as -f <regions> and to ScoutSuite as --regions <regions>, unless the *_extra_args already set them. With --regions all nothing is passed and both scan every enabled region. Prowler's AWS_DEFAULT_REGION is the first listed region and is never ALL.
The scanners audit the account those credentials reach: the caller's, or role_arn's. They are not run once per member account of aws.accounts or --org; only collection fans out over those. When the role cannot be assumed, Prowler and ScoutSuite are skipped for AWS and the error is shown (and reported to on_error as scanner_auth).
Examples¶
Keys that your CI secret store already exports as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN. The default chain picks them up, so no flag is needed, and Prowler inherits the same environment:
An auditor assuming a customer's role with an external ID:
cloudg run -p aws --profile auditor \
--aws-role-arn arn:aws:iam::123456789012:role/ThirdPartyAudit \
--aws-external-id 7f3c2a9e-example
OIDC federation in CI, with no stored keys:
cloudg run -p aws --regions all \
--aws-role-arn arn:aws:iam::123456789012:role/cloudg-ci \
--aws-web-identity-token-file "$RUNNER_TEMP/oidc-token"
An Azure service principal, secret from the environment:
export AZURE_CLIENT_SECRET="$(cat ./sp-secret)"
cloudg run -p azure \
--azure-tenant-id 11111111-1111-1111-1111-111111111111 \
--azure-client-id 22222222-2222-2222-2222-222222222222
Azure workload identity on AKS. The webhook sets AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_FEDERATED_TOKEN_FILE in the pod, and cloudg reads all three, so no flag is needed:
The system-assigned managed identity of an Azure VM:
A GCP service account key, impersonating a read-only account:
cloudg run -p gcp --project-id my-project \
--gcp-credentials-file ./sa-key.json \
--gcp-impersonate-sa cloudg-reader@my-project.iam.gserviceaccount.com
The same settings kept in config.yaml, which also works for cloudg map:
aws:
role_arn: arn:aws:iam::123456789012:role/cloudg-ci
web_identity_token_file: /var/run/secrets/oidc/token
azure:
tenant_id: 11111111-1111-1111-1111-111111111111
client_id: 22222222-2222-2222-2222-222222222222
certificate_path: /etc/cloudg/sp-cert.pem
gcp:
credentials_file: /etc/cloudg/wif-config.json
impersonate_service_account: cloudg-reader@my-project.iam.gserviceaccount.com
Related¶
-
Identities, roles and least-privilege permissions per provider.
-
--profile,--subscription-idand--project-id. -
The command these flags belong to.
-
Member-account roles for
cloudg map --org.