Skip to content

fix: strip -fips suffix from AWS service name in SigV4 signer - #3280

Open
macastelaz wants to merge 2 commits into
googleapis:mainfrom
macastelaz:fix/aws-sts-fips-service-name
Open

macastelaz wants to merge 2 commits into
googleapis:mainfrom
macastelaz:fix/aws-sts-fips-service-name

Conversation

@macastelaz

@macastelaz macastelaz commented Oct 30, 2026 •

Copy link
Copy Markdown

Description

AwsExternalAccountCredential already supports regional AWS STS endpoints out of the box by substituting the {region} placeholder in RegionalCredentialVerificationUrl (for example, https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15, which is the default verification URL generated for AWS Workload Identity Federation configurations).

However, when a customer in a FIPS-compliant AWS environment configures the corresponding AWS STS FIPS endpoint (https://sts-fips.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15), AwsSignedSubjectToken.Create previously derived the SigV4 serviceName directly from the first hostname label (host.Split('.')[0]) as sts-fips.

Per AWS SigV4 specification, the signing key derivation (keyService) and X-Amz-Credential credential scope (<date>/<region>/sts/aws4_request) must always use the canonical AWS service name sts, even when the request Host header and target URL use the sts-fips.<region>.amazonaws.com hostname. Scoping the signature to sts-fips causes AWS STS to reject the signed GetCallerIdentity token exchange with:

SignatureDoesNotMatch: Credential should be scoped to correct service: 'sts'.

This PR is part of a coordinated cross-language bugfix across all Google Auth libraries (Python #18920, Node.js #9779, Java #14867, Go cloud.google.com/go/auth #20805, Go golang/oauth2 #815, gRPC C++ #43804, and Ruby #608) to ensure AwsExternalAccountCredential strips the trailing -fips suffix when computing the SigV4 service name.

Fix

  • Strip any trailing -fips suffix from the first hostname segment in AwsExternalAccountCredential.AwsSignedSubjectToken.cs when computing serviceName (while preserving the full sts-fips.<region>.amazonaws.com hostname in the host header and request URL).
  • Add AwsSignedSubjectTokenTests.Create_Fips in AwsSignedSubjectTokenTests.cs verifying that a FIPS STS endpoint produces an Authorization header and signature scoped to sts.

Manual Testing

Verified end-to-end against live GCP STS (https://sts.googleapis.com/v1/token) forwarding to live AWS STS (https://sts-fips.us-east-2.amazonaws.com):

  • Before fix (sts-fips): Rejected by AWS STS with SignatureDoesNotMatch: Credential should be scoped to correct service: 'sts'.
  • After fix (sts): Passed AWS STS service-scope validation and proceeded to token validation (InvalidClientTokenId).
  • Verification App & Full HTTP Wire Logs (GPaste): https://paste.googleplex.com/6755399436519354

@macastelaz
macastelaz requested a review from a team as a code owner October 30, 2026 18:23

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for AWS FIPS endpoints by stripping the "-fips" suffix from the host's first segment when determining the service name, and includes corresponding unit tests. The review feedback suggests replacing the magic number 5 with a local constant for the "-fips" suffix to improve code maintainability and readability.

@amanda-tarafa

Copy link
Copy Markdown
Contributor

We now have ProgrammaticExternalAccountCredential that you can use for any sts exchange that deviates from what we currently support. I know that's not ideal but that's what we can offer at the moment. I'll raise the issue of regional AWS endpoints internally in case we want to support that out of the box. But for now I'll be closing this PR.

@amanda-tarafa amanda-tarafa self-assigned this Oct 30, 2026
@amanda-tarafa

Copy link
Copy Markdown
Contributor

Reopening in draft while we discuss internally.

@amanda-tarafa amanda-tarafa reopened this Oct 30, 2026
@amanda-tarafa
amanda-tarafa marked this pull request as draft October 30, 2026 18:45
@amanda-tarafa
amanda-tarafa self-requested a review October 30, 2026 18:45
@macastelaz
macastelaz marked this pull request as ready for review October 30, 2026 19:31
@macastelaz

Copy link
Copy Markdown
Author

Thanks @amanda-tarafa! Just adding a note here to clarify the framing for future readers on the thread:

  1. Regional AWS STS endpoints are already supported: AwsExternalAccountCredential already supports regional AWS STS endpoints out of the box via {region} substitution in RegionalCredentialVerificationUrl (e.g., https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15, which is the default verification URL template generated for AWS Workload Identity Federation configs).
  2. Why -fips endpoints fail without this fix: When a workload in a FIPS-compliant AWS environment uses the corresponding FIPS regional STS endpoint (https://sts-fips.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15), AwsSignedSubjectToken.Create extracts the first label of the hostname (sts-fips) and uses it as the SigV4 serviceName. However, AWS SigV4 requires the credential scope (<date>/<region>/sts/aws4_request) and HMAC signing key (keyService) to always use the canonical service name sts, even when the HTTP request is sent to sts-fips.<region>.amazonaws.com. Without stripping the -fips suffix from serviceName, AWS STS rejects the signed GetCallerIdentity token with SignatureDoesNotMatch: Credential should be scoped to correct service: 'sts'.
  3. Cross-SDK consistency: This PR is part of a coordinated bugfix across all Google Auth libraries (Python #18920, Node.js #9779, Java #14867, Go cloud.google.com/go/auth #20805, Go golang/oauth2 #815, gRPC C++ #43804, and Ruby #608) so that sts-fips.{region}.amazonaws.com verification URLs sign with the sts service scope consistently everywhere.

I also pushed a quick commit addressing the gemini-code-assist suggestion to extract const string fipsSuffix = "-fips";.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants