Skip to content

How do I resolve the AWS STS AssumeRoleWithWebIdentity API call error "InvalidIdentityToken"?

5 minute read
0

The AWS Security Token Service (AWS STS) AssumeRoleWithWebIdentity API call fails with an "InvalidIdentityToken" error. I want to troubleshoot this error.

Resolution

When your AssumeRoleWithWebIdentity API call fails, you might receive an error that's similar to the following message:

"An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation. Couldn't retrieve verification key from your identity provider."

Note: AWS CloudTrail event history doesn't log this error because this issue fails on the client side.

Verify public access for .well-known and jwks_uri

If you can't access the .well-known URL and jwks_uri of the identity provider (IdP), then you might receive an error. Verify that you can publicly access the .well-known URL and jwks_uri of the IdP.

To check the accessibility, navigate to the following links in your browser:

  • https://BASE_SERVER_URL/.well-known/openid-configuration
  • https://BASE_SERVER_URL/.well-known/jwks.json

-or-

To check the accessibility, run one of the following commands.

For Windows:

wget https://BASE_SERVER_URL/.well-known/openid-configurationwget https://BASE_SERVER_URL/.well-known/jwks.json

For Linux:

curl https://BASE_SERVER_URL/.well-known/openid-configurationcurl https://BASE_SERVER_URL/.well-known/jwks.json

Note: Replace BASE_SERVER_URL with the base url of your IdP.

To confirm whether you can access the links, check for the HTTP 200 status code in the request response.

Check firewall settings

If you can't access the .well-known URL and jwks_uri of the IdP, then check the firewall settings. Make sure that the domains aren't on a denylist. Depending on the current configuration of the firewall, the domains might need to be added to an allowlist.

If a custom firewall blocks the requests, then you might receive an error.

If you can't access the firewall settings, then use the browser with a device from a different network, such as a phone.

Navigate to the following links in your browser:

  • https://BASE_SERVER_URL/.well-known/openid-configuration
  • https://BASE_SERVER_URL/.well-known/jwks.json

Note: Replace BASE_SERVER_URL with the base url of your IdP.

If the server that makes the AssumeRoleWithWebIdentity API call is an Amazon Elastic Compute Cloud (Amazon EC2) instance, then check the configuration settings. For more information, see Why can't I connect to a website that is hosted on my EC2 instance?

Check operation latency

When the latency takes more than 5 seconds in API requests from the IdP to reach the AWS STS endpoint, you might receive an error.

Check the latency for the total operation. This includes the request and response time from STS and the request and response time from IdP attributes.

Minimize STS latency

Use AWS Regional endpoints instead of global endpoints for the STS service. This verifies that the requests are routed to the geographically closest server to minimize latency. For more information, see Writing code to use AWS STS Regions.

Note: For AWS SDKs, the Region parameter routes the request's destination endpoint to where the call is made within the sts_regional_endpoint configuration.

Evaluate IdP latency

The IdP makes requests to the STS endpoint. To check whether the request to the STS endpoint takes too long, review the IdP's outgoing packets within the IdP logs.

Note: The request might time out and fail if it takes more than 5 seconds to go from the IdP to the STS endpoint. You can contact your identity provider to request an increase for geographical availability to reduce latency for this API call.

(Optional) Use exponential backoff and increase retries

The IdP supports the AssumeRoleWithWebIdentity by providing information. Most IdPs have API limits to avoid throttling errors, and the IdP might not return the required keys from API calls. If the API has intermittent issues to reach your IdP, then use the following troubleshooting options:

  • Use exponential backoff.
  • Increase your retries, and then set a maximum number of retries. Also, implement a maximum delay interval. For more information, see Retry behavior.

Reduce STS requests to .well-known and jwks_uri

If your JSON Web Key Set (JWKS) sets either Pragma: no-cache or Cache-Control: no-cache response headers, then STS doesn't cache your JWKS. STS performs a callback for keys referenced in an ID_TOKEN but not in the cache. In this case, STS might make too many requests to your .well-known URL and jwks_uri.

To reduce callbacks from STS, verify that your JWKS doesn't set either of these response headers. This allows STS to cache your JWKS.

Reduce the number of keys in your JWKS

STS only supports up to 100 keys in a JWKS. If your JWKS has more than 100 keys, then STS can't verify the tokens signed with your keys. You might receive the "InvalidIdentityToken" error when you call AssumeRoleWithWebIdentity and your JWKS has more than 100 keys.

To resolve the error, remove keys from your JWKS that are longer needed. Or, reduce the number of keys present in your JWKS.

Related information

Welcome to the AWS Security Token Service API Reference

How do I resolve API throttling or "Rate exceeded" errors for IAM and AWS STS?

5 Comments

The documentation above makes it sound like /.well-known/jwks.json is a standard location but it really should specify the ”jwks_uri” value from .well-known/openid-configuration since the OIDC metadata is free to specify another endpoint, such as the oauth/discovery/keys path GitLab uses.

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT
replied 2 years ago

Another cause here is not matching the expected audience in an identity provider policy when attempting to use a role with a trust relationship with that identity provider. Steps to reproduce:

  1. Create a role under IAM > Roles that with a trust relationship with an external identity provider, for example:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "accounts.google.com:sub": "<sub>"
                }
            }
        }
    ]
}
  1. At this point the role should work with AssumeRoleWithWebIdentity if you provide a token with the expected sub.
  2. Add the same principal under IAM > Identity providers, for example:
provider type: OpenID Connect
Provider URL: https://accounts.google.com
Audience: empty
  1. At this point calls to AssumeRoleWithWebIdentity will fail with InvalidIdentityToken and an error message complaining about invalid audience.

The fix is to add the audience you're using to the IdentityProvider. This was pretty surprising to us and took a while to figure out since the trust policy hadn't changed. Also writing code to handle these two cases differently is difficult because the same error is returned for both retriable and permanent errors.

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT
replied 2 years ago
replied a year ago