SAML failures between Google Workspace and AWS produce vague errors on purpose - a specific message would leak information to an attacker. The cause is nearly always one of six things, and they are worth checking in a fixed order.
The frustrating part of debugging SAML is that both sides believe they are correct. Google thinks it issued a valid assertion and AWS thinks it rejected an invalid one, and neither will tell you which field disagreed. Reading the assertion yourself resolves most cases in a few minutes.
Table of contents
- Check one: the attribute mapping
- Check two: read the actual assertion
- Check three: URLs, entity IDs, and metadata
- Check four: the certificate
- Checks five and six: trust policy and provisioning
- How this fits the rest of the stack
- FAQ
Check one: the attribute mapping
The most common cause by a wide margin. AWS expects specific attribute names in the assertion, and the exact set depends on which integration you are using.
For IAM Identity Center, the critical attribute is the subject, which must carry the user identifier that matches the provisioned user - typically the email address. If Google is sending a different value, or sending it in a different format, the assertion is rejected as being for an unknown user.
For direct IAM federation, three attributes matter: the role attribute carrying the role ARN and the provider ARN as a comma-separated pair, the role session name, and optionally a session duration.
Two mistakes recur. First, the order inside the role attribute value - it is the role ARN first, then the provider ARN. Reversing them fails. Second, the account ID inside those ARNs must match the account you are federating into, which is easy to get wrong when the SAML app was copied from another account’s setup.
In Google’s admin console, these are configured as attribute mappings on the SAML app. Check every one against what AWS expects rather than assuming the template filled them in.
Check two: read the actual assertion
Stop guessing. Capture the assertion and read it - this converts the problem from speculation into a comparison of two values.
- Open the browser developer tools and enable request log preservation, so the redirect does not clear the network panel.
- Start the sign-in flow.
- Find the POST to the AWS SAML endpoint.
- Copy the SAMLResponse form field value.
- Decode it - it is base64-encoded XML.
# Decode a captured assertion
echo "$SAML_RESPONSE" | base64 -d | xmllint --format -
# The fields that matter
echo "$SAML_RESPONSE" | base64 -d | grep -oE 'Destination="[^"]*"'
echo "$SAML_RESPONSE" | base64 -d | grep -oE '<saml2:Audience>[^<]*'
echo "$SAML_RESPONSE" | base64 -d | grep -oE 'NotOnOrAfter="[^"]*"'
Compare four things against what AWS expects: the destination URL, the audience value, the attribute names and values, and the validity window. One of them will be wrong, and it is usually obvious once you are looking at both sides.
There are also browser extensions that decode SAML assertions inline, which is faster than the manual route if you do this more than occasionally.
Check three: URLs, entity IDs, and metadata
The ACS URL and the entity ID must match exactly on both sides. Exactly, including protocol, trailing slashes, and case.
For IAM Identity Center these values are region-specific and shown in the Identity Center console. Copying them from documentation rather than from your own console is a reliable way to get a region wrong, and the resulting failure looks like a credentials problem.
The audience value in the assertion must match the entity ID AWS is configured with. A mismatch here produces a rejection with no useful detail, because from AWS’s perspective it received an assertion intended for someone else.
The cleanest way to avoid all of this is metadata exchange. Download the metadata XML from each side and upload it to the other, rather than typing values into forms.
# Sanity-check downloaded IdP metadata
xmllint --format google-idp-metadata.xml | head -30
# Confirm the certificate inside it
xmllint --xpath '//*[local-name()="X509Certificate"]/text()' \
google-idp-metadata.xml | base64 -d | openssl x509 -noout -dates -subject
Check four: the certificate
An expired or rotated signing certificate produces a total failure - every user, all at once, with no warning. It is the cause behind most SSO outages that appear to come out of nowhere.
The certificate is issued by Google and uploaded to AWS. If Google rotates it and AWS still holds the old one, signature validation fails on every assertion.
# When does the certificate AWS holds expire?
openssl x509 -in google-cert.pem -noout -dates -subject -issuer
Put the expiry date in a shared calendar with a month of notice. This is unglamorous and it prevents an outage that otherwise arrives on a morning when nobody knows why nobody can log in.
Related: clock skew. SAML assertions carry a validity window measured in minutes, and a host with a badly wrong clock will reject assertions that are perfectly valid. Rare on cloud infrastructure with proper time synchronisation, but worth ruling out if the failures are intermittent rather than total.
Checks five and six: trust policy and provisioning
The role trust policy. For direct IAM federation, the role must trust your SAML provider specifically. A trust policy that names a different provider, or is missing the SAML condition entirely, means the assertion is valid and the role assumption still fails.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:saml-provider/GoogleWorkspace"
},
"Action": "sts:AssumeRoleWithSAML",
"Condition": {
"StringEquals": {
"SAML:aud": "https://signin.aws.amazon.com/saml"
}
}
}]
}
# Which SAML providers exist, and what does the role trust?
aws iam list-saml-providers
aws iam get-role --role-name YourSamlRole \
--query 'Role.AssumeRolePolicyDocument'
User provisioning. For IAM Identity Center, the user must exist on the AWS side before SAML will work. Authentication and provisioning are separate mechanisms - SAML proves who someone is, provisioning creates the account they are proving themselves into.
Provisioning is normally handled by SCIM from Google. When only some users fail while others succeed, this is almost always the cause: those users were not synchronised, or were assigned to the SAML app but not included in the provisioning scope. Check that the user exists in Identity Center and is assigned to a permission set, not just that they can reach the app.
A quick way to distinguish the two: if everyone fails, look at certificates, URLs, and mappings. If some fail and some succeed, look at provisioning and group assignment.
How this fits the rest of the stack
Identity federation is the kind of infrastructure that is invisible until a certificate expires, which is a good argument for keeping the surface small. Where an application can take environment variables from the platform, read its own logs, and roll back to the previous deploy without a separate access path, there is simply less identity plumbing to break. The RunxBuild hosting calculator shows what that shape costs - service, managed database, storage, and bandwidth as separate line items.
Useful related references:
- Google Cloud vs AWS: Pricing, Networking, and When to Pick Each
- AWS vs Google Cloud for Startups: A Friction-First Comparison
- AWS vs Google Cloud for Startups: The Bill and the Boring Stuff
- Services on RunxBuild
FAQ
Why does my Google Workspace SAML login to AWS fail with a generic error?
SAML errors are deliberately vague to avoid leaking information to attackers. Decode the assertion yourself: capture the SAMLResponse form field from the browser network panel, base64-decode it, and compare the destination, audience, attribute names, and validity window against what AWS expects.
What attributes does AWS need in a SAML assertion?
For IAM Identity Center, the subject must carry the user identifier that matches the provisioned user, usually the email address. For direct IAM federation, you need the role attribute carrying the role ARN and provider ARN as a comma-separated pair in that order, plus a role session name.
Why do only some users fail SAML login?
That pattern points at provisioning rather than SAML configuration. Those users likely were not synchronised into IAM Identity Center, or are assigned to the SAML app but outside the provisioning scope. If every user fails, look at certificates, URLs, and attribute mappings instead.
How do I check if the SAML certificate has expired?
Inspect the certificate AWS holds with an OpenSSL command showing its validity dates. An expired or rotated signing certificate fails every assertion at once with no warning, which is the cause behind most SSO outages that seem to appear from nowhere.
What is the difference between SAML authentication and SCIM provisioning?
SAML proves who someone is at sign-in. SCIM creates and maintains the user account they are signing in to. Both are needed - a user who authenticates successfully but was never provisioned will still be rejected, because AWS has no account to log them into.