- Newest
- Most votes
- Most comments
Thank you for bringing this important issue to our attention. You're correct that silently re-authenticating a user without requiring validation from the identity provider could lead to security vulnerabilities.
A few things to note here:
- Google Workspace does not support SAML SLO, so Cognito's
/logoutendpoint alone cannot fully sign the user out across both systems. [1] - When a user logs out of Cognito, it only clears the session cookie, but ID tokens remain valid until expiration.
- Your solution of calling
/oauth2/revokebefore logout is a good workaround, as it invalidates refresh tokens stored in Cognito.
A few other things:
- Consider calling
/oauth2/revokeon frontend logout in addition to backend calls. - Set short ID token expiration times (e.g. 5 minutes) to reduce risk window if tokens are stolen.
- Add MFA for high-security applications to prevent token reuse even if stolen.
- Redirect to identity provider logout page in addition to Cognito logout.
Docs
[1]: SAML sign-out flow
May be this is already resolved but writing what I followed if anyone else finds it helpful. The important point here is that we have to call the /oauth2/revoke google endpoint with the access_token sent by Google. In the default scenario, Google will send this to Cognito when logging a user in but unless you map this token to any Cognito attribute, Cognito won't send it back to your frontend app.
So, we have 2 things to do here:
- Create a custom attribute in Cognito and map it to the access_token Google attribute. You can see this doc to understand how to map custom attributes.
- Grab the custom attribute in the frontend and explicitly call the
/oauth2/revokeendpoint with the access_token. Once step 1 is complete, I noticed that I am getting the custom attribute in the Cognito sent id token. Wrote the below code to call Google/oauth2/revokein addition to Cognito logout.
import { signOut } from 'aws-amplify/auth'
const userSignOut = useCallback(async () => {
const userSessionData = getStorage(USER_SESSION_KEY) as UserDetails
removeStorage(USER_SESSION_KEY)
if (userDetails.isBusinessUser || userSessionData.isBusinessUser || user) {
const gaccessToken = userSessionData['custom:gaccess_token']
if (gaccessToken) {
try {
const formData = new URLSearchParams()
formData.append('token', gaccessToken)
await fetch('https://oauth2.googleapis.com/revoke', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData.toString()
})
} catch (error) {
console.error(error)
}
}
// signOut from Amplify which is used to communicate with Cognito
signOut({ global: true }).then(() => setUserDetails(DEFAULT_USER_DETAILS))
} else {
setUserDetails({
...DEFAULT_USER_DETAILS
})
}
}, [user, userDetails.isBusinessUser])
answered a year ago
Relevant content
asked a year ago

Thanks Ibrahim. So it sounds like this id token that persists in Cognito is probably the issue; it's avoiding re-authenticating with the Idp on
/loginbecause that token persists. Is that a good, secure design decision? Can we perhaps add a configuration option to AWS Cognito to revoke this id token on logout? While my work-around is sufficient for the moment, I'd feel better if there wasn't the possibility for someone to pick-up a user's session after/logoutwithout them having to authenticate.