fizz.today

GovCloud SSO and the STS endpoint trap

I logged in to a GovCloud account via SSO, ran aws sts get-caller-identity, and got InvalidClientTokenId. The same profile, the same SSO config, the same flow that works fine in commercial AWS. Login succeeds. Identity check fails.

The CLI’s SSO credential provider resolves the STS endpoint independently of the profile’s region setting. It sends GetCallerIdentity to sts.amazonaws.com — the commercial global endpoint — regardless of what region the profile says. GovCloud credentials are invalid there. Commercial STS doesn’t recognize them, so InvalidClientTokenId.

GovCloud has no global STS endpoint. It requires regional endpoints like sts.us-gov-east-1.amazonaws.com. My profile says region = us-gov-east-1, but the STS client doesn’t care. It already decided where to send the request.

I tried sts_regional_endpoints = regional in the profile, which is supposed to tell the SDK to use regional STS endpoints instead of the global one. Didn’t help. Without a correct region in the STS client’s own resolution path, it still lands on a commercial endpoint.

Then I tried overriding the endpoint URL in the [services] section of my AWS config, pointing STS at https://sts.us-gov-east-1.amazonaws.com. The URL changed, but the signing region didn’t. The request arrived at the right door signed with the wrong region’s credentials — SignatureDoesNotMatch. Close, but not the same problem.

What actually worked was --region us-gov-east-1 on the CLI call itself. That forces the entire SDK stack — endpoint resolution, signing region, all of it — to use the GovCloud region.

# Fails
aws sts get-caller-identity --profile govcloud-sso

# Works
aws sts get-caller-identity --profile govcloud-sso --region us-gov-east-1

Terraform doesn’t have this problem. The AWS provider reads its own region attribute and constructs all API clients with that region from the start — no ambient default to fight, no separate credential-provider endpoint resolution. If the provider block says region = "us-gov-east-1", STS calls go to the right place. This is purely a CLI issue.

The permanent fix is AWS_REGION in your shell. If you’re using direnv for project-level config, add it to your GovCloud project’s .envrc:

export AWS_REGION=us-gov-east-1
export AWS_DEFAULT_REGION=us-gov-east-1

Set both. Python and Go SDKs read different variables — if you only set one, you’ll fix half your tools and spend an afternoon blaming the other half.

#aws #govcloud #sso #sts