Using Amazon Verified Permissions with identity providers - Amazon Verified Permissions

Using Amazon Verified Permissions with identity providers

You can use OpenID Connect (OIDC) identity providers (IdPs) with Verified Permissions to pass user attributes to use as principals in Verified Permissions policies.

Working with Amazon Cognito and identity sources

An identity source is a collection of user information referenced by an identity provider for simplifying authorization requests to your policy stores. You can create an identity source to provide information about principals for your Verified Permissions applications. You can specify the AWS Region, Amazon Cognito user pool ID, and principal type of your identity sources. Because Verified Permissions only works with Amazon Cognito user pools in the same AWS account, you can't specify an identity source in another account.

User pool JSON Web Token (JWT) claims contain user attributes. You can add custom claims to inform the authorization decisions that Verified Permissions makes. Identity token claims include cognito:username and cognito:groups. For more information, see Using tokens with user pools in the Amazon Cognito Developer Guide.

Important

Although you can revoke Amazon Cognito tokens before they expire, JWTs are considered to be stateless resources that are self-contained with a signature and validity. Services that conform with the JSON Web Token RFC 7519 are expected to validate tokens remotely and aren't required to validate them with the issuer. This means that it is possible for Verified Permissions to grant access based on a token that was revoked or issued for user that was later deleted. To mitigate this risk, we recommend that you create your tokens with the shortest possible validity duration and revoke refresh tokens when you want to remove authorization to continue a user's session.

You can also add custom attributes to your user pool. Custom attributes require the custom: prefix to distinguish them from standard attributes. For example, you can add a custom:joblevel attribute to a user pool. For more information, see Custom attributes in the Amazon Cognito Developer Guide.

When writing Cedar policies in Verified Permissions using Amazon Cognito user pool claims and attributes that contain a : character, you must reference them in Cedar policies with a period (.) instead of a colon (:) to comply with Cedar policy syntax. For example, you must change cognito:username and cognito:groups to cognito.username and cognito.groups respectively.

Note

If a token contains a claim with a cognito: or custom: prefix and a cognito or custom claim, an authorization request with IsAuthorizedWithToken will fail with a ValidationException.

This example shows how you might create a policy that references Amazon Cognito user pools custom claims corresponding to a principal.

permit( principal == ExampleCo::User::"us-east-1_example|4fe90f4a-ref8d9-4033-a750-4c8622d62fb6", action, resource == ExampleCo::Photo::"VacationPhoto94.jpg" ) when { principal.cognito.username == "alice" };

For more information, see Authorization with Amazon Verified Permissions in the Amazon Cognito Developer Guide.

Working with other identity providers

You can extract your entity attributes from a JSON Web Token (JWT) from any OpenID Connect (OIDC) provider (IdP) and parse it into Verified Permissions.

This example shows how you might call Verified Permissions from an OIDC-compliant IdP.¹

async function authorizeUsingJwtToken(jwtToken) { const payload = await verifier.verify(jwtToken); var principalEntity = { entityType: "PhotoFlash::User", // the application needs to fill in the relevant user type entityId: payload["sub"], // the application need to use the claim that represents the user-id }; var resourceEntity = { entityType: "PhotoFlash::Photo", //the application needs to fill in the relevant resource type entityId: "jane_photo_123.jpg", // the application needs to fill in the relevant resource id }; var action = { actionType: "PhotoFlash::Action", //the application needs to fill in the relevant action id actionId: "GetPhoto", //the application needs to fill in the relevant action type }; var entities = { entityList: [], }; entities.entityList.push(...getUserEntitiesFromToken(payload)); var policyStoreId = "PSEXAMPLEabcdefg111111"; // set your own policy store id const authResult = await client .isAuthorized({ policyStoreId: policyStoreId, principal: principalEntity, resource: resourceEntity, action: action, entities, }) .promise(); return authResult; } function getUserEntitiesFromToken(payload) { let attributes = {}; let claimsNotPassedInEntities = ['aud', 'sub', 'exp', 'jti', 'iss']; Object.entries(payload).forEach(([key, value]) => { if (claimsNotPassedInEntities.includes(key)) { return; } if (Array.isArray(value)) { var attibuteItem = []; value.forEach((item) => { attibuteItem.push({ string: item, }); }); attributes[key] = { set: attibuteItem, }; } else if (typeof value === 'string') { attributes[key] = { string: value, } } else if (typeof value === 'bigint' || typeof value ==='number') { attributes[key] = { long: value, } } else if (typeof value === 'bigint' || typeof value ==='number') { attributes[key] = { long: value, } } else if (typeof value === 'boolean') { attributes[key] = { boolean: value, } } }); let entityItem = { attributes: attributes, identifier: { entityType: "PhotoFlash::User", entityId: payload["sub"], // the application need to use the claim that represents the user-id } }; return [entityItem]; }

¹ This code example uses the aws-jwt-verify library for verifying JWTs signed by OIDC-compatible IdPs.