

# Secure your applications with identity sources and tokens
Identity sources

Secure you applications quickly by creating an *identity source* to represent an external identity provider (IdP) in Amazon Verified Permissions. Identity sources provide information from a user who authenticated with an IdP that has a trust relationship with your policy store. When your application makes an authorization request with a token from an identity source, your policy store can make authorization decisions from user properties and access permissions. You can add an Amazon Cognito user pool or a custom OpenID Connect (OIDC) IdP as your identity source.

You can use [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) identity providers (IdPs) with Verified Permissions. Your application can generate authorization requests with JSON web tokens (JWTs) generated by an OIDC-compliant identity provider. The user identity in the token is mapped to the principal ID. With ID tokens, Verified Permissions maps attribute claims to principal attributes. With Access tokens, these claims are mapped to [context](context.md). With both token types, you can map a claim like `groups` to a principal group, and build policies that evaluate role-based access control (RBAC).

**Note**  
Verified Permissions makes authorization decisions based on information from an IdP token but doesn't interact directly with the IdP in any way.

For a step-by-step walkthrough that builds authorization logic for Amazon API Gateway REST APIs using an Amazon Cognito user pool or OIDC identity provider, see [Authorize API Gateway APIs using Amazon Verified Permissions with Amazon Cognito or bring your own identity provider](https://amazonaws-china.com/blogs/security/authorize-api-gateway-apis-using-amazon-verified-permissions-and-amazon-cognito/) on the *Amazon Security Blog*.

**Topics**
+ [

## Choosing the right identity provider
](#choosing-identity-source)
+ [

# Working with Amazon Cognito identity sources
](identity-sources-cognito.md)
+ [

# Working with OIDC identity sources
](identity-sources-oidc.md)

## Choosing the right identity provider


While Verified Permissions works with a variety of IdPs, consider the following when deciding which one to use in your application:

Use Amazon Cognito when:  
+ You're building new applications without existing identity infrastructure
+ You want Amazon-managed user pools with built-in security features
+ You need social identity provider integration
+ You want simplified token management

Use OIDC providers when:  
+ You have existing identity infrastructure (Auth0, Okta, Azure AD)
+ You need to maintain centralized user management
+ You have compliance requirements for specific IdPs

# Working with Amazon Cognito identity sources


Verified Permissions works closely with Amazon Cognito user pools. Amazon Cognito JWTs have a predictable structure. Verified Permissions recognizes this structure and draws maximum benefit from the information that it contains. For example, you can implement a role-based access control (RBAC) authorization model with either ID tokens or access tokens.

A new Amazon Cognito user pools identity source requires the following information:
+ The Amazon Web Services Region.
+ The user pool ID.
+ The principal entity type that you want to associate with your identity source, for example `MyCorp::User`.
+ The principal group entity type that you want to associate with your identity source, for example `MyCorp::UserGroup`.
+ The client IDs from your user pool that you want to authorize to make requests to your policy store.

Because Verified Permissions only works with Amazon Cognito user pools in the same Amazon Web Services account, you can't specify an identity source in another account. Verified Permissions sets the *entity prefix*—the identity-source identifier that you must reference in policies that act on user pool principals—to the ID of your user pool, for example `us-west-2_EXAMPLE`. In this case, you would reference a user in that user pool with ID `a1b2c3d4-5678-90ab-cdef-EXAMPLE22222` as `us-west-2_EXAMPLE|a1b2c3d4-5678-90ab-cdef-EXAMPLE22222`

User pool token *claims* can contain attributes, scopes, groups, client IDs, and custom data. [Amazon Cognito JWTs](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html) have the ability to include a variety of information that can contribute to authorization decisions in Verified Permissions. These include:

1. Username and group claims with a `cognito:` prefix

1. [Custom user attributes](https://docs.amazonaws.cn/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-custom-attributes) with a `custom: prefix`

1. Custom claims added at runtime

1. OIDC standard claims like `sub` and `email`

We cover these claims in detail, and how to manage them in Verified Permissions policies, in [Mapping Amazon Cognito tokens to schema](cognito-map-token-to-schema.md).

**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](https://datatracker.ietf.org/doc/html/rfc7519) 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 a 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. For more information, see [Ending user sessions with token revocation](https://docs.amazonaws.cn/cognito/latest/developerguide/token-revocation.html)

This following example shows how you might create a policy that references some of the Amazon Cognito user pools claims associated with a principal.

```
permit(
     principal, 
     action, 
     resource == ExampleCo::Photo::"VacationPhoto94.jpg" 
)
when { 
     principal["cognito:username"]) == "alice" &&
     principal["custom:department"]) == "Finance"
};
```

This following example shows how you might create a policy that references a principal that's a user in a Cognito user pool. Note that the principal ID takes the form of `"<userpool-id>|<sub>"`.

```
permit(
     principal == ExampleCo::User::"us-east-1_example|a1b2c3d4-5678-90ab-cdef-EXAMPLE11111", 
     action, 
     resource == ExampleCo::Photo::"VacationPhoto94.jpg" 
);
```

Cedar policies for user pool identity sources in Verified Permissions use a special syntax for claim names that contain characters other than alphanumeric and underscore (`_`). This includes user pool prefix claims that contain a `:` character, like `cognito:username` and `custom:department`. To write a policy condition that references the `cognito:username` or `custom:department` claim, write them as `principal["cognito:username"]` and `principal["custom:department"]`, respectively.

**Note**  
If a token contains a claim with a `cognito:` or `custom:` prefix and a claim name with the literal value `cognito` or `custom`, an authorization request with [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) will fail with a `ValidationException`.

For more information about mapping claims, see [Mapping Amazon Cognito tokens to schema](cognito-map-token-to-schema.md). For more information about authorization for Amazon Cognito users, see [Authorization with Amazon Verified Permissions](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-authorization-with-avp.html) in the *Amazon Cognito Developer Guide*.

**Topics**
+ [

# Creating Amazon Verified Permissions Amazon Cognito identity sources
](cognito-create.md)
+ [

# Editing Amazon Verified Permissions Amazon Cognito identity sources
](cognito-edit.md)
+ [

# Mapping Amazon Cognito tokens to schema
](cognito-map-token-to-schema.md)
+ [

# Client and audience validation for Amazon Cognito
](cognito-validation.md)

# Creating Amazon Verified Permissions Amazon Cognito identity sources
Creating identity sources

The following procedure adds an identity source to an existing policy store.

You can also create an identity source when you [create a new policy store](policy-stores-create.md) in the Verified Permissions console. In this process, you can automatically import the claims in your identity source tokens into entity attributes. Choose the **Guided setup** or **Set up with API Gateway and an identity provider** option. These options also create initial policies.

**Note**  
**Identity sources** is not available in the navigation pane on the left until you have created a policy store. Identity sources that you create are associated with the current policy store.

You can leave out the principal entity type when you create an identity source with [create-identity-source](https://docs.amazonaws.cn/cli/latest/reference/verifiedpermissions/create-identity-source.html) in the Amazon CLI or [CreateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_CreateIdentitySource.html) in the Verified Permissions API. However, a blank entity type creates an identity source with an entity type of `Amazon::Cognito`. This entity name isn't compatible with policy store schema. To integrate Amazon Cognito identities with your policy store schema, you must set the principal entity type to a supported policy store entity.

------
#### [ Amazon Web Services Management Console ]

**To create an Amazon Cognito user pools identity source**

1. Open the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions/). Choose your policy store.

1. In the navigation pane on the left, choose **Identity sources**.

1. Choose **Create identity source**.

1. In **Cognito user pool details**, select the Amazon Web Services Region and enter the **User pool ID** for your identity source.

1. In **Principal configuration**, for **Principal type**, choose the entity type for principals from this source. Identities from the connected Amazon Cognito user pools will be mapped to the selected principal type.

1. In **Group configuration**, select **Use Cognito group** if you want to map the user pool `cognito:groups` claim. Choose an entity type that is a parent of the principal type.

1. In **Client application validation**, choose whether to validate client application IDs.
   + To validate client application IDs, choose **Only accept tokens with matching client application IDs**. Choose **Add new client application ID** for each client application ID to validate. To remove a client application ID that has been added, choose **Remove** next to the client application ID.
   + Choose **Do not validate client application IDs** if you do not want to validate client application IDs.

1. Choose **Create identity source**.

1. (Optional) If your policy store has a schema, before you can reference attributes you extract from identity or access tokens in your Cedar policies, you must update your schema to make Cedar aware of the type of principal that your identity source creates. That addition to the schema must include the attributes that you want to reference in your Cedar policies. For more information about mapping Amazon Cognito token attributes to Cedar principal attributes, see [Mapping Amazon Cognito tokens to schema](cognito-map-token-to-schema.md).
**Note**  
When you create an [API-linked policy store](policy-stores-api-userpool.md) or use **Set up with API Gateway and an identity provider** when creating policy stores, Verified Permissions queries your user pool for user attributes and creates a schema where your principal type is populated with user pool attributes.

1. Create policies that use information from the tokens to make authorization decisions. For more information, see [Creating Amazon Verified Permissions static policies](policies-create.md).

Now that you've created an identity source, updated the schema, and created policies, use `IsAuthorizedWithToken` to have Verified Permissions make authorization decisions. For more information, see [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) in the *Amazon Verified Permissions API reference guide*.

------
#### [ Amazon CLI ]

**To create an Amazon Cognito user pools identity source**  
You can an create an identity source by using the [CreateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_CreateIdentitySource.html) operation. The following example creates an identity source that can access authenticated identities from a Amazon Cognito user pool.

1. Create a `config.txt` file that contains the following details of the Amazon Cognito user pool for use by the `--configuration` parameter in the `create-identity-source` command.

   ```
   {
       "cognitoUserPoolConfiguration": {
           "userPoolArn": "arn:aws-cn:cognito-idp:us-west-2:123456789012:userpool/us-west-2_1a2b3c4d5",
           "clientIds":["a1b2c3d4e5f6g7h8i9j0kalbmc"],
           "groupConfiguration": {
                 "groupEntityType": "MyCorp::UserGroup"
           }
       }
   }
   ```

1. Run the following command to create an Amazon Cognito identity source.

   ```
   $ aws verifiedpermissions create-identity-source \
       --configuration file://config.txt \
       --principal-entity-type "User" \
       --policy-store-id 123456789012
   {
       "createdDate": "2023-05-19T20:30:28.214829+00:00",
       "identitySourceId": "ISEXAMPLEabcdefg111111",
       "lastUpdatedDate": "2023-05-19T20:30:28.214829+00:00",
       "policyStoreId": "PSEXAMPLEabcdefg111111"
   }
   ```

1. (Optional) If your policy store has a schema, before you can reference attributes you extract from identity or access tokens in your Cedar policies, you must update your schema to make Cedar aware of the type of principal that your identity source creates. That addition to the schema must include the attributes that you want to reference in your Cedar policies. For more information about mapping Amazon Cognito token attributes to Cedar principal attributes, see [Mapping Amazon Cognito tokens to schema](cognito-map-token-to-schema.md).
**Note**  
When you create an [API-linked policy store](policy-stores-api-userpool.md) or use **Set up with API Gateway and an identity provider** when creating policy stores, Verified Permissions queries your user pool for user attributes and creates a schema where your principal type is populated with user pool attributes.

1. Create policies that use information from the tokens to make authorization decisions. For more information, see [Creating Amazon Verified Permissions static policies](policies-create.md).

Now that you've created an identity source, updated the schema, and created policies, use `IsAuthorizedWithToken` to have Verified Permissions make authorization decisions. For more information, see [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) in the *Amazon Verified Permissions API reference guide*.

------

For more information about using Amazon Cognito access and identity tokens for authenticated users in Verified Permissions, see [Authorization with Amazon Verified Permissions](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-authorization-with-avp.html) in the *Amazon Cognito Developer Guide*. 

# Editing Amazon Verified Permissions Amazon Cognito identity sources
Editing identity sources

You can edit some parameters of your identity source after you create it. You can't change the type of identity source, you have to delete the identity source and create a new one to switch from Amazon Cognito to OIDC or OIDC to Amazon Cognito. If your policy store schema matches your identity source attributes, note that you must update your schema separately to reflect the changes that you make to your identity source.

------
#### [ Amazon Web Services Management Console ]

**To update an Amazon Cognito identity source**

1. Open the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions/). Choose your policy store.

1. In the navigation pane on the left, choose **Identity sources**.

1. Choose the ID of the identity source to edit.

1. Choose **Edit**.

1. In **Cognito user pool details**, select the Amazon Web Services Region and type the **User pool ID** for your identity source.

1. In **Principal details**, you can update the **Principal type** for the identity source. Identities from the connected Amazon Cognito user pools will be mapped to the selected principal type.

1. In **Group configuration**, select **Use Cognito groups** if you want to map the user pool `cognito:groups` claim. Choose an entity type that is a parent of the principal type.

1. In **Client application validation**, choose whether to validate client application IDs.
   + To validate client application IDs, choose **Only accept tokens with matching client application IDs**. Choose **Add new client application ID** for each client application ID to validate. To remove a client application ID that has been added, choose **Remove** next to the client application ID.
   + Choose **Do not validate client application IDs** if you do not want to validate client application IDs.

1. Choose **Save changes**.

1. If you changed the principal type for the identity source, you must update your schema to correctly reflect the updated principal type.

You can delete an identity source by choosing the radio button next to an identity source and then choosing **Delete identity source**. Type `delete` in the text box and then choose **Delete identity source** to confirm deleting the identity source.

------
#### [ Amazon CLI ]

**To update an Amazon Cognito identity source**  
You can update an identity source by using the [UpdateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_UpdateIdentitySource.html) operation. The following example updates the specified identity source to use a different Amazon Cognito user pool.

1. Create a `config.txt` file that contains the following details of the Amazon Cognito user pool for use by the `--configuration` parameter in the `update-identity-source` command.

   ```
   {
       "cognitoUserPoolConfiguration": {
           "userPoolArn": "arn:aws-cn:cognito-idp:us-west-2:123456789012:userpool/us-west-2_1a2b3c4d5",
           "clientIds":["a1b2c3d4e5f6g7h8i9j0kalbmc"],
           "groupConfiguration": {
                 "groupEntityType": "MyCorp::UserGroup"
           }
       }
   }
   ```

1. Run the following command to update an Amazon Cognito identity source.

   ```
   $ aws verifiedpermissions update-identity-source \
       --update-configuration file://config.txt \
       --policy-store-id 123456789012
   {
       "createdDate": "2023-05-19T20:30:28.214829+00:00",
       "identitySourceId": "ISEXAMPLEabcdefg111111",
       "lastUpdatedDate": "2023-05-19T20:30:28.214829+00:00",
       "policyStoreId": "PSEXAMPLEabcdefg111111"
   }
   ```

**Note**  
If you change the principal type for the identity source, you must update your schema to correctly reflect the updated principal type.

------

# Mapping Amazon Cognito tokens to schema
Mapping tokens to schema

You might find that you want to add an identity source to a policy store and map provider claims, or tokens, to your policy store schema. You can automate this process, by using the [Guided setup](policy-stores-create.md) to create your policy store with an identity source, or update your schema manually after the policy store is created. Once you have mapped the tokens to the schema you can create policies that reference them.

This section of the user guide has the following information:
+ When you can automatically populate attributes to a policy store schema
+ How to use Amazon Cognito token claims in your Verified Permissions policies
+ How to manually build a schema for an identity source

[API-linked policy stores](policy-stores-api-userpool.md) and policy stores with an identity source that were created through [Guided setup](policy-stores-create.md) don't require manual mapping of identity (ID) token attributes to schema. You can provide Verified Permissions with the attributes in your user pool and create a schema that is populated with user attributes. In ID token authorization, Verified Permissions maps claims to attributes of a principal entity. You might need to manually map Amazon Cognito tokens to your schema in the following conditions:
+ You created an empty policy store or policy store from a sample.
+ You want to extend your use of access tokens beyond role-based access control (RBAC).
+ You create policy stores with the Verified Permissions REST API, an Amazon SDK, or the Amazon CDK.

To use Amazon Cognito as an identity source in your Verified Permissions policy store, you must have provider attributes in your schema. The schema is fixed and must correspond to the entities that provider tokens create in [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) or [BatchIsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_BatchIsAuthorizedWithToken.html) API requests. If you created your policy store in a way that automatically populates your schema from provider information in an ID token, you're ready to write policies. If you create a policy store without a schema for your identity source, you must add provider attributes to the schema that match the entities created using API requests. Then you can write policies using attributes from the provider token.

For more information about using Amazon Cognito ID and access tokens for authenticated users in Verified Permissions, see [Authorization with Amazon Verified Permissions](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-authorization-with-avp.html) in the *Amazon Cognito Developer Guide*.

**Topics**
+ [

## Mapping ID tokens to schema
](#cognito-map-id-token)
+ [

## Mapping access tokens
](#cognito-map-access-token)
+ [

## Alternative notation for Amazon Cognito colon-delimited claims
](#cognito-colon-claims)
+ [

## Things to know about schema mapping
](#cognito-map-token-to-schema-things-to-know)

## Mapping ID tokens to schema
Mapping ID tokens

Verified Permissions processes ID token claims as the attributes of the user: their names and titles, their group membership, their contact information. ID tokens are most useful in an *attribute-based access control* (ABAC) authorization model. When you want Verified Permissions to analyze access to resources based on who's making the request, choose ID tokens for your identity source.

Amazon Cognito ID tokens work with most [OIDC relying-party libraries](https://openid.net/developers/certified-openid-connect-implementations/). They extend the features of OIDC with additional claims. Your application can authenticate the user with Amazon Cognito user pools authentication API operations, or with the user pool hosted UI. For more information, see [Using the API and endpoints](https://docs.amazonaws.cn/cognito/latest/developerguide/user-pools-API-operations.html) in the *Amazon Cognito Developer Guide*.Useful claims in Amazon Cognito ID tokens

*`cognito:username` and `preferred_username`*  
Variants of the user's username.

*`sub`*  
The user's unique user identifier (UUID)

*Claims with a `custom:` prefix*  
A prefix for custom user pool attributes like `custom:employmentStoreCode`.

*Standard claims*  
Standard OIDC claims like `email` and `phone_number`. For more information, see [Standard claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) in *OpenID Connect Core 1.0 incorporating errata set 2*.

*`cognito:groups`*  
A user's group memberships. In an authorization model based on role-based access control (RBAC), this claim presents the roles that you can evaluate in your policies.

*Transient claims*  
Claims that aren't a property of the user, but are added at runtime by a user pool [Pre token generation Lambda trigger](https://docs.amazonaws.cn/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html). Transient claims resemble standard claims but are outside the standard, for example `tenant` or `department`.

In policies that reference Amazon Cognito attributes that have a `:` separator, reference the attributes in the format `principal["cognito:username"]`. The roles claim `cognito:groups` is an exception to this rule. Verified Permissions maps the contents of this claim to parent entities of the user entity.

For more information about the structure of ID tokens from Amazon Cognito user pools, see [Using the ID token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-id-token.html) in the *Amazon Cognito Developer Guide*.

The following example ID token has each of the four types of attributes. It includes the Amazon Cognito-specific claim `cognito:username`, the custom claim `custom:employmentStoreCode`, the standard claim `email`, and the transient claim `tenant`.

```
{
    "sub": "91eb4550-XXX",
    "cognito:groups": [
        "Store-Owner-Role",
        "Customer"
    ],
    "email_verified": true,
    "clearance": "confidential",
    "iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_EXAMPLE",
    "cognito:username": "alice",
    "custom:employmentStoreCode": "petstore-dallas",
    "origin_jti": "5b9f50a3-05da-454a-8b99-b79c2349de77",
    "aud": "1example23456789",
    "event_id": "0ed5ad5c-7182-4ecf-XXX",
    "token_use": "id",
    "auth_time": 1687885407,
    "department": "engineering",
    "exp": 1687889006,
    "iat": 1687885407,
    "tenant": "x11app-tenant-1",
    "jti": "a1b2c3d4-e5f6-a1b2-c3d4-TOKEN1111111",
    "email": "alice@example.com"
}
```

When you create an identity source with your Amazon Cognito user pool, you specify the type of principal entity that Verified Permissions generates in authorization requests with `IsAuthorizedWithToken`. Your policies can then test attributes of that principal as part of evaluating that request. Your schema defines the principal type and attributes for an identity source, and then you can reference them in your Cedar policies.

You also specify the type of group entity that you want to derive from the ID token groups claim. In authorization requests, Verified Permissions maps each member of the groups claim to that group entity type. In policies, you can reference that group entity as the principal.

The following example shows how to reflect the attributes from the example identity token in your Verified Permissions schema. For more information about editing your schema, see [Editing policy store schemas](schema-edit.md). If your identity source configuration specifies the principal type `User`, then you can include something similar to the following example to make those attributes available to Cedar.

```
"User": {
   "shape": {
      "type": "Record",
      "attributes": {
         "cognito:username": {
            "type": "String",
            "required": false
         },
         "custom:employmentStoreCode": {
            "type": "String",
            "required": false
         },
         "email": {
            "type": "String"
         },
         "tenant": {
            "type": "String",
            "required": true
         }
      }
   }
}
```

For an example policy that will validate against this schema, see [Reflects Amazon Cognito ID token attributes](policies-examples.md#policies-examples-cognito-id).

## Mapping access tokens


Verified Permissions processes access-token claims other than the groups claim as attributes of the action, or *context attributes*. Along with group membership, the access tokens from your IdP might contain information about API access. Access tokens are useful in authorization models that use role-based access control (RBAC). Authorization models that rely on access-token claims other than group membership require additional effort in schema configuration.

Amazon Cognito access tokens have claims that can be used for authorization:Useful claims in Amazon Cognito access tokens

*`client_id`*  
The ID of the client application of an OIDC relying party. With the client ID, Verified Permissions can verify that the authorization request comes from a permitted client for the policy store. In machine-to-machine (M2M) authorization, the requesting system authorizes a request with a client secret and provides the client ID and scopes as evidence of authorization.

*`scope`*  
The [OAuth 2.0 scopes](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) that represent the access permissions of the bearer of the token.

*`cognito:groups`*  
A user's group memberships. In an authorization model based on role-based access control (RBAC), this claim presents the roles that you can evaluate in your policies.

*Transient claims*  
Claims that aren't an access permission, but are added at runtime by a user pool [Pre token generation Lambda trigger](https://docs.amazonaws.cn/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html). Transient claims resemble standard claims but are outside the standard, for example `tenant` or `department`. Customization of access tokens adds cost to your Amazon bill.

For more information about the structure of access tokens from Amazon Cognito user pools, see [Using the access token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html) in the *Amazon Cognito Developer Guide*.

An Amazon Cognito access token is mapped to a context object when passed to Verified Permissions. Attributes of the access token can be referenced using `context.token.attribute_name`. The following example access token includes both the `client_id` and `scope` claims.

```
{
    "sub": "91eb4550-9091-708c-a7a6-9758ef8b6b1e",
    "cognito:groups": [
        "Store-Owner-Role",
        "Customer"
    ],
    "iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_EXAMPLE",
    "client_id": "1example23456789",
    "origin_jti": "a1b2c3d4-e5f6-a1b2-c3d4-TOKEN1111111",
    "event_id": "bda909cb-3e29-4bb8-83e3-ce6808f49011",
    "token_use": "access",
    "scope": "MyAPI/mydata.write",
    "auth_time": 1688092966,
    "exp": 1688096566,
    "iat": 1688092966,
    "jti": "a1b2c3d4-e5f6-a1b2-c3d4-TOKEN2222222",
    "username": "alice"
}
```

The following example shows how to reflect the attributes from the example access token in your Verified Permissions schema. For more information about editing your schema, see [Editing policy store schemas](schema-edit.md).

```
{
   "MyApplication": {
      "actions": {
         "Read": {
            "appliesTo": {
               "context": {
                  "type": "ReusedContext"
               },
               "resourceTypes": [
                  "Application"
               ],
               "principalTypes": [
                  "User"
               ]
            }
         }
      },
      ...
      ...
      "commonTypes": {
         "ReusedContext": {
            "attributes": {
               "token": {
                  "type": "Record",
                  "attributes": {
                     "scope": {
                        "type": "Set",
                        "element": {
                           "type": "String"
                        }
                     },
                     "client_id": {
                        "type": "String"
                     }
                  }
               }
            },
            "type": "Record"
         }
      }
   }
}
```

For an example policy that will validate against this schema, see [Reflects Amazon Cognito access token attributes](policies-examples.md#policies-examples-cognito-access).

## Alternative notation for Amazon Cognito colon-delimited claims


At the time that Verified Permissions launched, the recommended schema for Amazon Cognito token claims like `cognito:groups` and `custom:store` converted these colon-delimited strings to use the `.` character as a hierarchy delimiter. This format is called *dot notation*. For example, a reference to `cognito:groups` became `principal.cognito.groups` in your policies. Although you can continue to use this format, we recommend that you build your schema and policies with [bracket notation](#cognito-map-token-to-schema-things-to-know). In this format, a reference to `cognito:groups` becomes `principal["cognito:groups"]` in your policies. Automatically-generated schemas for user pool ID tokens from the Verified Permissions console use bracket notation.

You can continue to use dot notation in manually-built schema and policies for Amazon Cognito identity sources. You can't use dot notation with `:` or any other non-alphanumeric characters in schema or policies for any other type of OIDC IdP.

A schema for dot notation nests each instance of a `:` character as a child of the `cognito` or `custom` initial phrase, as shown in the following example:

```
"CognitoUser": {
   "shape": {
      "type": "Record",
      "attributes": {
         "cognito": {
            "type": "Record",
            "required": true,
            "attributes": {
               "username": {
                  "type": "String",
                  "required": true
               }
            }
         },
         "custom": {
            "type": "Record",
            "required": true,
            "attributes": {
               "employmentStoreCode": {
                  "type": "String",
                  "required": true
               }
            }
         },
         "email": {
            "type": "String"
         },
         "tenant": {
            "type": "String",
            "required": true
         }
      }
   }
}
```

For an example policy that will validate against this schema and use dot notation, see [Uses dot notation to reference attributes](policies-examples.md#policies-examples-dot).

## Things to know about schema mapping


**Attribute mapping differs between token types**  
In access token authorization, Verified Permissions maps claims to [context](context.md). In ID token authorization, Verified Permissions maps claims to principal attributes. For policy stores that you create in the Verified Permissions console, only **empty** and **sample** policy stores leave you with no identity source and require you to populate your schema with user pool attributes for ID token authorization. Access token authorization is based on role-based access control (RBAC) with group-membership claims and doesn't automatically map other claims to the policy store schema.

**Identity source attributes aren't required**  
When you create an identity source in the Verified Permissions console, no attributes are marked as required. This prevents missing claims from causing validation errors in authorization requests. You can set attributes to required as needed, but they must be present in all authorization requests.

**RBAC doesn't require attributes in schema**  
Schemas for identity sources depend on the entity associations that you make when you add your identity source. An identity source maps one claim to a user entity type, and one claim to a group entity type. These entity mappings are the core of an identity-source configuration. With this minimum information, you can write policies that perform authorization actions for specific users and specific groups that users might be members of, in a role-based access control (RBAC) model. The addition of token claims to the schema extends the authorization scope of your policy store. User attributes from ID tokens have information about users that can contribute to attribute-based access control (ABAC) authorization. Context attributes from access tokens have information like OAuth 2.0 scopes that can contribute additional access-control information from your provider, but require additional schema modifications.

The **Set up with API Gateway and an identity provider** and **Guided setup** options in the Verified Permissions console assign ID token claims to the schema. This isn't the case for access token claims. To add non-group access-token claims to your schema, you must edit your schema in JSON mode and add [commonTypes](https://docs.cedarpolicy.com/schema/json-schema.html#schema-commonTypes) attributes. For more information, see [Mapping access tokens](#cognito-map-access-token).

**Choose a token type**  
The way that your policy store works with your identity source depends on a key decision in identity-source configuration: whether you will process ID or access tokens. With an Amazon Cognito identity provider, you have the choice of token type when you create an API-linked policy store. When you create an [API-linked policy store](policy-stores-api-userpool.md), you must choose whether you want to set up authorization for ID or access tokens. This information affects the schema attributes that Verified Permissions applies to your policy store, and the syntax of the Lambda authorizer for your API Gateway API. Especially if you wish to benefit from the automatic mapping of ID token claims to attributes in the Verified Permissions console, decide early about the token type that you want to process before you create your identity source. Changing the token type requires significant effort to refactor your policies and schema. The following topics describe the use of ID and access tokens with policy stores.

**Cedar parser requires brackets for some characters**  
Policies typically reference schema attributes in a format like `principal.username`. In the case of most non-alphanumeric characters like `:`, `.`, or `/` that might appear in token claim names, Verified Permissions can't parse a condition value like `principal.cognito:username` or `context.ip-address`. You must instead format these conditions with bracket notation in the format `principal["cognito:username"]` or `context["ip-address"]`, respectively. The underscore character `_` is a valid character in claim names, and the only non-alphanumeric exception to this requirement.

A partial example schema for a principal attribute of this type looks like the following:

```
"User": {
   "shape": {
      "type": "Record",
      "attributes": {
         "cognito:username": {
            "type": "String",
            "required": true
         },
         "custom:employmentStoreCode": {
            "type": "String",
            "required": true,
         },
         "email": {
            "type": "String",
            "required": false
         }
      }
   }
}
```

A partial example schema for a context attribute of this type looks like the following:

```
"GetOrder": {
   "memberOf": [],
   "appliesTo": {
      "resourceTypes": [
         "Order"
      ],
      "context": {
         "type": "Record",
         "attributes": {
            "ip-address": {
               "required": false,
               "type": "String"
            }
		 }
	  },
      "principalTypes": [
         "User"
      ]
   }
}
```

For an example policy that will validate against this schema, see [Uses bracket notation to reference token attributes](policies-examples.md#policies-examples-brackets).

# Client and audience validation for Amazon Cognito
Client and audience validation

When you add an identity source to a policy store, Verified Permissions has configuration options that verify that ID and access tokens are being used as intended. This validation happens in the processing of `IsAuthorizedWithToken` and `BatchIsAuthorizedWithToken` API requests. The behavior differs between ID and access tokens, and between Amazon Cognito and OIDC identity sources. With Amazon Cognito user pools providers, Verified Permissions can validate the client ID in both ID and access tokens. With OIDC providers, Verified Permissions can validate the client ID in ID tokens, and the audience in access tokens.

A *client ID* is an identifier associated with the identity provider instance that your application uses, for example `1example23456789`. An *audience* is a URL path associated with the intended *relying party*, or destination, of the access token, for example `https://mytoken.example.com`. When using access tokens, the `aud` claim is always associated with the audience.

Amazon Cognito ID tokens have an `aud` claim that contains the [app client](https://docs.amazonaws.cn/cognito/latest/developerguide/user-pool-settings-client-apps.html) ID. Access tokens have a `client_id` claim that also contains the app client ID.

When you enter one or more values for **Client application validation** in your identity source, Verified Permissions compares this list of app client IDs to the ID token `aud` claim or the access token `client_id` claim. Verified Permissions doesn't validate a relying-party audience URL for Amazon Cognito identity sources.

## Client-side authorization for JWTs


You might want to process JSON web tokens in your application and pass their claims to Verified Permissions without using a policy store identity source. You can extract your entity attributes from a JSON Web Token (JWT) and parse it into Verified Permissions.

This example shows how you might call Verified Permissions from an application using a JWT.¹

```
async function authorizeUsingJwtToken(jwtToken) {
  
    const payload = await verifier.verify(jwtToken);
   
    let 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
    };
    let 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
    };
    let 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
    };
    let entities = {
        entityList: [],
    };
    entities.entityList.push(...getUserEntitiesFromToken(payload));
    let 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 === 'boolean') {
        attributes[key] = {
            boolean: value,
       } 
    }

  });

  let entityItem = {
    attributes: attributes,
    identifier: {
      entityType: "PhotoFlash::User",
      entityId: payload["sub"], // the application needs to use the claim that represents the user-id
    }
  };
  return [entityItem];
}
```

¹ This code example uses the [aws-jwt-verify](https://github.com/awslabs/aws-jwt-verify) library for verifying JWTs signed by OIDC-compatible IdPs.

# Working with OIDC identity sources


You can also configure any compliant OpenID Connect (OIDC) IdP as the identity source of a policy store. OIDC providers are similar to Amazon Cognito user pools: they produce JWTs as the product of authentication. To add an OIDC provider, you must provide an issuer URL

A new OIDC identity source requires the following information:
+ The issuer URL. Verified Permissions must be able to discover a `.well-known/openid-configuration` endpoint at this URL.
+ CNAME records that don't include wild cards. For example, `a.example.com` can't be mapped to `*.example.net`. Conversely, `*.example.com` can't be mapped to `a.example.net`.
+ The token type that you want to use in authorization requests. In this case, you chose **Identity token**.
+ The user entity type that you want to associate with your identity source, for example `MyCorp::User`.
+ The group entity type that you want to associate with your identity source, for example `MyCorp::UserGroup`.
+ An example ID token, or a definition of the claims in the ID token.
+ The prefix that you want to apply to user and group entity IDs. In the CLI and API, you can choose this prefix. In policy stores that you create with the **Set up with API Gateway and an identity provider** or **Guided setup** option, Verified Permissions assigns a prefix of the issuer name minus `https://`, for example `MyCorp::User::"auth.example.com|a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"`.

For more information about using API operations to authorize requests from OIDC sources, see [Available API operations for authorization](authorization.md#authorization-operations).

This following example shows how you might create a policy that permits access to year-end reports for employees in the accounting department, have a confidential classification, and aren't in a satellite office. Verified Permissions derives these attributes from the claims in the principal's ID token.

Note that when referencing a group in the principal, you must use the `in` operator for the policy to be evaluated correctly.

```
permit(
     principal in MyCorp::UserGroup::"MyOIDCProvider|Accounting", 
     action, 
     resource in MyCorp::Folder::"YearEnd2024" 
) when { 
     principal.jobClassification == "Confidential" &&
     !(principal.location like "SatelliteOffice*")
};
```

**Topics**
+ [

# Creating Amazon Verified Permissions OIDC identity sources
](oidc-create.md)
+ [

# Editing Amazon Verified Permissions OIDC identity sources
](oidc-edit.md)
+ [

# Mapping OIDC tokens to schema
](oidc-map-token-to-schema.md)
+ [

# Client and audience validation for OIDC providers
](oidc-validation.md)

# Creating Amazon Verified Permissions OIDC identity sources
Creating identity sources

The following procedure adds an identity source to an existing policy store.

You can also create an identity source when you [create a new policy store](policy-stores-create.md) in the Verified Permissions console. In this process, you can automatically import the claims in your identity source tokens into entity attributes. Choose the **Guided setup** or **Set up with API Gateway and an identity provider** option. These options also create initial policies.

**Note**  
**Identity sources** is not available in the navigation pane on the left until you have created a policy store. Identity sources that you create are associated with the current policy store.

You can leave out the principal entity type when you create an identity source with [create-identity-source](https://docs.amazonaws.cn/cli/latest/reference/verifiedpermissions/create-identity-source.html) in the Amazon CLI or [CreateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_CreateIdentitySource.html) in the Verified Permissions API. However, a blank entity type creates an identity source with an entity type of `Amazon::Cognito`. This entity name isn't compatible with policy store schema. To integrate Amazon Cognito identities with your policy store schema, you must set the principal entity type to a supported policy store entity.

------
#### [ Amazon Web Services Management Console ]

**To create an OpenID Connect (OIDC) identity source**

1. Open the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions/). Choose your policy store.

1. In the navigation pane on the left, choose **Identity sources**.

1. Choose **Create identity source**.

1. Choose **External OIDC provider**.

1. In **Issuer URL**, enter the URL of your OIDC issuer. This is the service endpoint that provides the authorization server, signing keys, and other information about your provider, for example `https://auth.example.com`. Your issuer URL must host an OIDC discovery document at `/.well-known/openid-configuration`.

1. In **Token type**, choose the type of OIDC JWT that you want your application to submit for authorization. For more information, see [Mapping OIDC tokens to schema](oidc-map-token-to-schema.md).

1. In **Map token claims to schema entities**, choose a **User entity** and **User claim** for the identity source. The **User entity** is an entity in your policy store that you want to refer to users from your OIDC provider. The **User claim** is a claim, typically `sub`, from your ID or access token that holds the unique identifier for the entity to be evaluated. Identities from the connected OIDC IdP will be mapped to the selected principal type.

1. (Optional) In **Map token claims to schema entities**, choose a **Group entity** and **Group claim** for the identity source. The **Group entity** is a [parent](https://docs.cedarpolicy.com/overview/terminology.html#term-group) of the **User entity**. Group claims get mapped to this entity. The **Group claim** is a claim, typically `groups`, from your ID or access token that contains a string, JSON, or space-delimited string of user-group names for the entity to be evaluated. Identities from the connected OIDC IdP will be mapped to the selected principal type.

1. In **validation - optional**, enter the client IDs or audience URLs that you want your policy store to accept in authorization requests, if any.

1. Choose **Create identity source**.

1. (Optional) If your policy store has a schema, before you can reference attributes that you extract from identity or access tokens in your Cedar policies, you must update your schema to make Cedar aware of the type of principal that your identity source creates. That addition to the schema must include the attributes that you want to reference in your Cedar policies. For more information about mapping OIDC token attributes to Cedar principal attributes, see [Mapping OIDC tokens to schema](oidc-map-token-to-schema.md).

1. Create policies that use information from the tokens to make authorization decisions. For more information, see [Creating Amazon Verified Permissions static policies](policies-create.md).

Now that you've created an identity source, updated the schema, and created policies, use `IsAuthorizedWithToken` to have Verified Permissions make authorization decisions. For more information, see [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) in the *Amazon Verified Permissions API reference guide*.

------
#### [ Amazon CLI ]

**To create an OIDC identity source**  
You can an create an identity source by using the [CreateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_CreateIdentitySource.html) operation. The following example creates an identity source that can access authenticated identities from a an OIDC identity provider(IdP).

1. Create a `config.txt` file that contains the following details of an OIDC IdP for use by the `--configuration` parameter of the `create-identity-source` command.

   ```
   {
       "openIdConnectConfiguration": {
           "issuer": "https://auth.example.com",
           "tokenSelection": {
                   "identityTokenOnly": {
                           "clientIds":["1example23456789"],
                           "principalIdClaim": "sub"
                   },
           },
           "entityIdPrefix": "MyOIDCProvider",
           "groupConfiguration": {
                 "groupClaim": "groups",
                 "groupEntityType": "MyCorp::UserGroup"
           }
       }
   }
   ```

1. Run the following command to create an OIDC identity source.

   ```
   $ aws verifiedpermissions create-identity-source \
       --configuration file://config.txt \
       --principal-entity-type "User" \
       --policy-store-id 123456789012
   {
       "createdDate": "2023-05-19T20:30:28.214829+00:00",
       "identitySourceId": "ISEXAMPLEabcdefg111111",
       "lastUpdatedDate": "2023-05-19T20:30:28.214829+00:00",
       "policyStoreId": "PSEXAMPLEabcdefg111111"
   }
   ```

1. (Optional) If your policy store has a schema, before you can reference attributes that you extract from identity or access tokens in your Cedar policies, you must update your schema to make Cedar aware of the type of principal that your identity source creates. That addition to the schema must include the attributes that you want to reference in your Cedar policies. For more information about mapping OIDC token attributes to Cedar principal attributes, see [Mapping OIDC tokens to schema](oidc-map-token-to-schema.md).

1. Create policies that use information from the tokens to make authorization decisions. For more information, see [Creating Amazon Verified Permissions static policies](policies-create.md).

Now that you've created an identity source, updated the schema, and created policies, use `IsAuthorizedWithToken` to have Verified Permissions make authorization decisions. For more information, see [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) in the *Amazon Verified Permissions API reference guide*.

------

# Editing Amazon Verified Permissions OIDC identity sources
Editing identity sources

You can edit some parameters of your identity source after you create it. You can't change the type of identity source, you have to delete the identity source and create a new one to switch from Amazon Cognito to OIDC or OIDC to Amazon Cognito. If your policy store schema matches your identity source attributes, note that you must update your schema separately to reflect the changes that you make to your identity source.

------
#### [ Amazon Web Services Management Console ]

**To update an OIDC identity source**

1. Open the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions/). Choose your policy store.

1. In the navigation pane on the left, choose **Identity sources**.

1. Choose the ID of the identity source to edit.

1. Choose **Edit**.

1. In **OIDC provider details**, change the **Issuer URL** as needed.

1. In **Map token claims to schema attributes**, change the associations between user and group claims and policy store entity types, as needed. After you change entity types, you must update your policies and schema attributes to apply to the new entity types.

1. In **Audience validation**, add or remove audience values that you want to enforce.

1. Choose **Save changes**.

You can delete an identity source by choosing the radio button next to an identity source and then choosing **Delete identity source**. Type `delete` in the text box and then choose **Delete identity source** to confirm deleting the identity source.

------
#### [ Amazon CLI ]

**To update an OIDC identity source**  
You can update an identity source by using the [UpdateIdentitySource](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_UpdateIdentitySource.html) operation. The following example updates the specified identity source to use a different OIDC provider.

1. Create a `config.txt` file that contains the following details of an OIDC IdP for use by the `--configuration` parameter of the `update-identity-source` command.

   ```
   {
       "openIdConnectConfiguration": {
           "issuer": "https://auth2.example.com",
           "tokenSelection": {
                   "identityTokenOnly": {
                           "clientIds":["2example10111213"],
                           "principalIdClaim": "sub"
                   },
           },
           "entityIdPrefix": "MyOIDCProvider",
           "groupConfiguration": {
                 "groupClaim": "groups",
                 "groupEntityType": "MyCorp::UserGroup"
           }
       }
   }
   ```

1. Run the following command to update an OIDC identity source.

   ```
   $ aws verifiedpermissions update-identity-source \
       --update-configuration file://config.txt \
       --policy-store-id 123456789012
   {
       "createdDate": "2023-05-19T20:30:28.214829+00:00",
       "identitySourceId": "ISEXAMPLEabcdefg111111",
       "lastUpdatedDate": "2023-05-19T20:30:28.214829+00:00",
       "policyStoreId": "PSEXAMPLEabcdefg111111"
   }
   ```

**Note**  
If you change the principal type for the identity source, you must update your schema to correctly reflect the updated principal type.

------

# Mapping OIDC tokens to schema
Mapping tokens to schema

You might find that you want to add an identity source to a policy store and map provider claims, or tokens, to your policy store schema. You can automate this process, by using the [Guided setup](policy-stores-create.md) to create your policy store with an identity source, or update your schema manually after the policy store is created. Once you have mapped the tokens to the schema you can create policies that reference them.

This section of the user guide has the following information:
+ When you can automatically populate attributes to a policy store schema
+ How to manually build a schema for an identity source

[API-linked policy stores](policy-stores-api-userpool.md) and policy stores with an identity source that were created through [Guided setup](policy-stores-create.md) don't require manual mapping of identity (ID) token attributes to schema. You can provide Verified Permissions with the attributes in your user pool and create a schema that is populated with user attributes. In ID token authorization, Verified Permissions maps claims to attributes of a principal entity.

To use an OIDC identity provider (IdP) as an identity source in your Verified Permissions policy store, you must have provider attributes in your schema. The schema is fixed and must correspond to the entities that provider tokens create in [IsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html) or [BatchIsAuthorizedWithToken](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_BatchIsAuthorizedWithToken.html) API requests. If you created your policy store in a way that automatically populates your schema from provider information in an ID token, you're ready to write policies. If you create a policy store without a schema for your identity source, you must add provider attributes to the schema that match the entities created using API requests. Then you can write policies using attributes from the provider token.

**Topics**
+ [

## Mapping ID tokens to schema
](#oidc-map-id-token)
+ [

## Mapping access tokens
](#oidc-map-access-token)
+ [

## Things to know about schema mapping
](#oidc-map-token-to-schema-things-to-know)

## Mapping ID tokens to schema
Mapping ID tokens

Verified Permissions processes ID token claims as the attributes of the user: their names and titles, their group membership, their contact information. ID tokens are most useful in an *attribute-based access control* (ABAC) authorization model. When you want Verified Permissions to analyze access to resources based on who's making the request, choose ID tokens for your identity source.

Working with ID tokens from an OIDC provider is much the same as working with Amazon Cognito ID tokens. The difference is in the claims. Your IdP might present [standard OIDC attributes](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims), or have a custom schema. When you create a new policy store in the Verified Permissions console, you can add an OIDC identity source with an example ID token, or you can manually map token claims to user attributes. Because Verified Permissions isn't aware of the attribute schema of your IdP, you must provide this information.

For more information, see [Creating Verified Permissions policy stores](policy-stores-create.md).

The following is an example schema for a policy store with an OIDC identity source.

```
"User": {
   "shape": {
      "type": "Record",
      "attributes": {
         "email": {
            "type": "String"
         },
         "email_verified": {
            "type": "Boolean"
         },
         "name": {
            "type": "String",
            "required": true
         },
         "phone_number": {
            "type": "String"
         },
         "phone_number_verified": {
            "type": "Boolean"
         }
      }
   }
}
```

For an example policy that will validate against this schema, see [Reflects OIDC ID token attributes](policies-examples.md#policies-examples-oidc-id).

## Mapping access tokens


Verified Permissions processes access-token claims other than the groups claim as attributes of the action, or *context attributes*. Along with group membership, the access tokens from your IdP might contain information about API access. Access tokens are useful in authorization models that use role-based access control (RBAC). Authorization models that rely on access-token claims other than group membership require additional effort in schema configuration.

Most access tokens from external OIDC providers align closely with Amazon Cognito access tokens. An OIDC access token is mapped to a context object when passed to Verified Permissions. Attributes of the access token can be referenced using `context.token.attribute_name`. The following example OIDC access token includes example base claims.

```
{
    "sub": "91eb4550-9091-708c-a7a6-9758ef8b6b1e",
    "groups": [
        "Store-Owner-Role",
        "Customer"
    ],
    "iss": "https://auth.example.com",
    "client_id": "1example23456789",
    "aud": "https://myapplication.example.com"
    "scope": "MyAPI-Read",
    "exp": 1688096566,
    "iat": 1688092966,
    "jti": "a1b2c3d4-e5f6-a1b2-c3d4-TOKEN2222222",
    "username": "alice"
}
```

The following example shows how to reflect the attributes from the example access token in your Verified Permissions schema. For more information about editing your schema, see [Editing policy store schemas](schema-edit.md).

```
{
   "MyApplication": {
      "actions": {
         "Read": {
            "appliesTo": {
               "context": {
                  "type": "ReusedContext"
               },
               "resourceTypes": [
                  "Application"
               ],
               "principalTypes": [
                  "User"
               ]
            }
         }
      },
      ...
      ...
      "commonTypes": {
         "ReusedContext": {
            "attributes": {
               "token": {
                  "type": "Record",
                  "attributes": {
                     "scope": {
                        "type": "Set",
                        "element": {
                           "type": "String"
                        }
                     },
                     "client_id": {
                        "type": "String"
                     }
                  }
               }
            },
            "type": "Record"
         }
      }
   }
}
```

For an example policy that will validate against this schema, see [Reflects OIDC access token attributes](policies-examples.md#policies-examples-oidc-access).

## Things to know about schema mapping


**Attribute mapping differs between token types**  
In access token authorization, Verified Permissions maps claims to [context](context.md). In ID token authorization, Verified Permissions maps claims to principal attributes. For policy stores that you create in the Verified Permissions console, only **empty** and **sample** policy stores leave you with no identity source and require you to populate your schema with user pool attributes for ID token authorization. Access token authorization is based on role-based access control (RBAC) with group-membership claims and doesn't automatically map other claims to the policy store schema.

**Identity source attributes aren't required**  
When you create an identity source in the Verified Permissions console, no attributes are marked as required. This prevents missing claims from causing validation errors in authorization requests. You can set attributes to required as needed, but they must be present in all authorization requests.

**RBAC doesn't require attributes in schema**  
Schemas for identity sources depend on the entity associations that you make when you add your identity source. An identity source maps one claim to a user entity type, and one claim to a group entity type. These entity mappings are the core of an identity-source configuration. With this minimum information, you can write policies that perform authorization actions for specific users and specific groups that users might be members of, in a role-based access control (RBAC) model. The addition of token claims to the schema extends the authorization scope of your policy store. User attributes from ID tokens have information about users that can contribute to attribute-based access control (ABAC) authorization. Context attributes from access tokens have information like OAuth 2.0 scopes that can contribute additional access-control information from your provider, but require additional schema modifications.

The **Set up with API Gateway and an identity provider** and **Guided setup** options in the Verified Permissions console assign ID token claims to the schema. This isn't the case for access token claims. To add non-group access-token claims to your schema, you must edit your schema in JSON mode and add [commonTypes](https://docs.cedarpolicy.com/schema/json-schema.html#schema-commonTypes) attributes. For more information, see [Mapping access tokens](#oidc-map-access-token).

**OIDC groups claim supports multiple formats**  
When you add an OIDC provider, you can choose the name of the groups claim in ID or access tokens that you want to map to a user’s group membership in your policy store. Verified permissions recognizes groups claims in the following formats:

1. String without spaces: `"groups": "MyGroup"`

1. Space-delimited list: `"groups": "MyGroup1 MyGroup2 MyGroup3"`. Each string is a group.

1. JSON (comma-delimited) list: `"groups": ["MyGroup1", "MyGroup2", "MyGroup3"]`

**Note**  
Verified Permissions interprets each string in a space-separated groups claim as a separate group. To interpret a group name with a space character as a single group, replace or remove the space in the claim. For example, format a group named `My Group` as `MyGroup`.

**Choose a token type**  
The way that your policy store works with your identity source depends on a key decision in identity-source configuration: whether you will process ID or access tokens. With an OIDC provider, you must choose a token type when you add the identity source. You can choose ID or access token, and your choice excludes the unchosen token type from being processed in your policy store. Especially if you wish to benefit from the automatic mapping of ID token claims to attributes in the Verified Permissions console, decide early about the token type that you want to process before you create your identity source. Changing the token type requires significant effort to refactor your policies and schema. The following topics describe the use of ID and access tokens with policy stores.

**Cedar parser requires brackets for some characters**  
Policies typically reference schema attributes in a format like `principal.username`. In the case of most non-alphanumeric characters like `:`, `.`, or `/` that might appear in token claim names, Verified Permissions can't parse a condition value like `principal.cognito:username` or `context.ip-address`. You must instead format these conditions with bracket notation in the format `principal["cognito:username"]` or `context["ip-address"]`, respectively. The underscore character `_` is a valid character in claim names, and the only non-alphanumeric exception to this requirement.

A partial example schema for a principal attribute of this type looks like the following:

```
"User": {
   "shape": {
      "type": "Record",
      "attributes": {
         "cognito:username": {
            "type": "String",
            "required": true
         },
         "custom:employmentStoreCode": {
            "type": "String",
            "required": true,
         },
         "email": {
            "type": "String",
            "required": false
         }
      }
   }
}
```

A partial example schema for a context attribute of this type looks like the following:

```
"GetOrder": {
   "memberOf": [],
   "appliesTo": {
      "resourceTypes": [
         "Order"
      ],
      "context": {
         "type": "Record",
         "attributes": {
            "ip-address": {
               "required": false,
               "type": "String"
            }
		 }
	  },
      "principalTypes": [
         "User"
      ]
   }
}
```

For an example policy that will validate against this schema, see [Uses bracket notation to reference token attributes](policies-examples.md#policies-examples-brackets).

# Client and audience validation for OIDC providers
Client and audience validation

When you add an identity source to a policy store, Verified Permissions has configuration options that verify that ID and access tokens are being used as intended. This validation happens in the processing of `IsAuthorizedWithToken` and `BatchIsAuthorizedWithToken` API requests. The behavior differs between ID and access tokens, and between Amazon Cognito and OIDC identity sources. With Amazon Cognito user pools providers, Verified Permissions can validate the client ID in both ID and access tokens. With OIDC providers, Verified Permissions can validate the client ID in ID tokens, and the audience in access tokens.

A *client ID* is an identifier associated with the identity provider instance that your application uses, for example `1example23456789`. An *audience* is a URL path associated with the intended *relying party*, or destination, of the access token, for example `https://mytoken.example.com`. When using access tokens, the `aud` claim is always associated with the audience.

OIDC ID tokens have an `aud` claim that contains client IDs, such as `1example23456789`.

OIDC Access tokens have an `aud` claim that contains the audience URL for the token, such as `https://myapplication.example.com`, and a `client_id` claim that contains client IDs, such as `1example23456789`.

When setting up your policy store, enter one or more values for **Audience validation** that your policy store with use to validate the audience of a token.
+ **ID tokens** – Verified Permissions validates the client ID by checking that at least one member of the client IDs in the `aud` claim matches an audience validation value.
+ **Access tokens** – Verified Permissions validates the audience by checking that the URL in the `aud` claim matches an audience validation value. If no `aud` claim exists, the audience can be validated using the `cid` or `client_id` claims. Check with your identity provider for the correct audience claim and format.

## Client-side authorization for JWTs


You might want to process JSON web tokens in your application and pass their claims to Verified Permissions without using a policy store identity source. You can extract your entity attributes from a JSON Web Token (JWT) and parse it into Verified Permissions.

This example shows how you might call Verified Permissions from an application using a JWT.¹

```
async function authorizeUsingJwtToken(jwtToken) {
  
    const payload = await verifier.verify(jwtToken);
   
    let 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
    };
    let 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
    };
    let 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
    };
    let entities = {
        entityList: [],
    };
    entities.entityList.push(...getUserEntitiesFromToken(payload));
    let 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 === 'boolean') {
        attributes[key] = {
            boolean: value,
       } 
    }

  });

  let entityItem = {
    attributes: attributes,
    identifier: {
      entityType: "PhotoFlash::User",
      entityId: payload["sub"], // the application needs to use the claim that represents the user-id
    }
  };
  return [entityItem];
}
```

¹ This code example uses the [aws-jwt-verify](https://github.com/awslabs/aws-jwt-verify) library for verifying JWTs signed by OIDC-compatible IdPs.