

# Creating Verified Permissions policy stores
Creating policy stores

You can create a policy store using the following methods:
+ **Follow a guided setup** – You will define a resource type with valid actions and a principal type before creating your first policy.
+ **Set up with API Gateway and an identity source**– Define your principal entities with users who sign in with an identity provider (IdP), and your actions and resource entities from an Amazon API Gateway API. We recommend this option if you want your application to authorize API requests with users’ group membership or other attributes.
+ **Start from a sample policy store** – Choose a pre-defined sample project policy store. We recommend this option if you are learning about Verified Permissions and want to view and test example policies.
+ **Create an empty policy store** – You will define the schema and all access policies yourself. We recommend this option if you are already familiar with configuring a policy store.

------
#### [ Guided setup ]

**To create a policy store using the **Guided setup** configuration method**

The guided setup wizard leads you through the process of creating the first iteration of your policy store. You will create a schema for your first resource type, describe the actions that are applicable for that resource type, and the principal type for which you are granting permissions. You will then create your first policy. Once you've completed this wizard, you will be able to add to your policy store, extend the schema to describe other resource and principal types, and create additional policies and templates.

1. In the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions), select **Create new policy store**.

1. In the **Starting options** section, choose **Guided setup**.

1. Enter a **Policy store description**. This text can be whatever suits your organization as a friendly reference to the function of the current policy store, for example *Weather updates web application*.

1. In the **Details** section, type a **Namespace for your schema**. For more information about namespaces, see [Namespace definition](terminology-differences-avp-cedar.md#differences-namespaces).

1. Choose **Next**.

1. On the **Resource type** window, type a name for your resource type. For example, `currentTemperature` could be a resource for the *Weather updates web application*.

1. (Optional) Choose **Add an attribute** to add resource attributes. Type the **Attribute name** and choose an **Attribute type** for each attribute of the resource. Choose whether each attribute is **Required**. For example, `temperatureFormat` could be an attribute for the `currentTemperature` resource and be either Fahrenheit or Celsius. To remove an attribute that has been added for the resource type, choose **Remove** next to the attribute.

1. In the **Actions** field, type the actions to be authorized for the specified resource type. To add additional actions for the resource type, choose **Add an action**. For example, `viewTemperature` could be an action in the *Weather updates web application*. To remove an action that has been added for the resource type, choose **Remove** next to the action.

1. In the **Name of the principal type** field, type the name for a type of principal that will be using the specified actions for your resource type. By default, **User** is added to this field but can be replaced.

1. Choose **Next**.

1. On the **Principal type** window, choose the identity source for your principal type.
   + Choose **Custom** if the principal's ID and attributes will be provided directly by your Verified Permissions application. Choose **Add an attribute** to add principal attributes. Verified Permissions uses the specified attribute values when verifying policies against the schema. To remove an attribute that has been added for the principal type, choose **Remove** next to the attribute.
   + Choose **Cognito User Pool** if the principal's ID and attributes will be provided from an ID or access token generated by Amazon Cognito. Choose **Connect user pool**. Select the **Amazon Web Services Region** and type **User pool ID** of the Amazon Cognito user pool to connect to. Choose **Connect**. For more information, 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*.
   + Choose **External OIDC provider** if the principal's ID and attributes will be extracted from an ID and/or Access token, generated by an external OIDC provider and add the provider and token details.

1. Choose **Next**.

1. In the **Policy details** section, type an optional **Policy description** for your first Cedar policy.

1. In the **Principals scope** field, choose the principals that will be granted permissions from the policy.
   + Choose **Specific principal** to apply the policy to a specific principal. Choose the principal in the **Principal that will be permitted to take actions** field and type an entity identifier for the principal. For example, `user-id` could be an entity identifier in the *Weather updates web application*.
**Note**  
If you are using Amazon Cognito, the entity identifier must be formatted as `<userpool-id>|<sub>`.
   + Choose **All principals** to apply the policy to all principals in your policy store.

1. In the **Resources scope** field, choose which resources that the specified principals will be authorized to act on.
   + Choose **Specific resource** to apply the policy to a specific resource. Choose the resource in the **Resource this policy should apply to** field and type an entity identifier for the resource. For example, `temperature-id` could be an entity identifier in the *Weather updates web application*.
   + Choose **All resources** to apply the policy to all resources in your policy store.

1. In the **Actions scope** field, choose which actions that the specified principals will be authorized to perform.
   + Choose **Specific set of actions** to apply the policy to specific actions. Select the check boxes next to the actions in the **Action(s) this policy should apply to** field.
   + Choose **All actions** to apply the policy to all actions in your policy store.

1. Review the policy in the **Policy preview** section. Choose **Create policy store**.

------
#### [ Set up with API Gateway and an identity source ]

**To create a policy store using the **Set up with API Gateway and an identity source** configuration method**

The API Gateway option secures APIs with Verified Permissions policies that are designed to make authorization decisions from users’ groups, or *roles*. This option builds a policy store for testing authorization with identity-source groups and an API with a Lambda authorizer.

The users and their groups in an IdP become either your principals (ID tokens) or your context (access tokens). The methods and paths in an API Gateway API become the actions that your policies authorize. Your application becomes the resource. As a result of this workflow, Verified Permissions creates a policy store, a Lambda function, and an API Lambda authorizer. You must assign the Lambda [authorizer](https://docs.amazonaws.cn/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) to your API after you finish this workflow.

1. In the [Verified Permissions console](https://console.amazonaws.cn/verifiedpermissions), select **Create new policy store**.

1. In the **Starting options** section, choose **Set up with API Gateway and an identity source** and select **Next**.

1. In the **Import resources and actions** step, under **API**, choose an API that will function as the model to your policy store resources and actions.

   1. Choose a **Deployment stage** from the stages configured in your API and select **Import API**. For more information about API stages, see [Setting up a stage for a REST API in the Amazon API Gateway Developer Guide](https://docs.amazonaws.cn/apigateway/latest/developerguide/set-up-stages.html).

   1. Preview your **Map of imported resources and actions**.

   1. To update resources or actions, modify your API paths or methods in the API Gateway console and select **Import API** to see the updates.

   1. When you are satisfied with your choices, choose **Next**.

1. In **Identity source**, choose an **Identity provider type**. You can choose an Amazon Cognito user pool or an OpenID Connect (OIDC) IdP type.

1. If you chose **Amazon Cognito**:

   1. Choose a user pool in the same Amazon Web Services Region and Amazon Web Services account as your policy store.

   1. Choose the **Token type to pass to API** that you want to submit for authorization. Either token types contains user groups, the foundation of this API-linked authorization model.

   1. Under **App client validation**, you can limit the scope of a policy store to a subset of the Amazon Cognito app clients in a multi-tenant user pool. To require that user authenticate with one or more specified app clients in your user pool, select **Only accept tokens with expected app client IDs**. To accept any user who authenticates with the user pool, select **Don't validate app client IDs**.

   1. Choose **Next**.

1. If you chose **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 Amazon Cognito tokens to schema](cognito-map-token-to-schema.md) and [Mapping OIDC tokens to schema](oidc-map-token-to-schema.md).

   1. (optional) In **Token claims - optional**, choose **Add a token claim**, enter a name for the token, and select a value type.

   1. In **User and group token claims**, do the following:

      1. Enter a **User claim name in token** for the identity source. This 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 user type in your policy store.

      1. Enter a **Group claim name in token** for the identity source. This is a claim, typically `groups`, from your ID or access token that contains a list of the user's groups. Your policy store will authorize requests based on the group membership.

   1. In **Audience validation**, choose `Add value` and add a value that you want your policy store to accept in authorization requests.

   1. Choose **Next**.

1. If you chose **Amazon Cognito**, Verified Permissions queries your user pool for groups. For OIDC providers, enter group names manually. The **Assign actions to groups** step creates policies for your policy store that permit group members to perform actions.

   1. Choose or add the groups that you want to include in your policies.

   1. Assign actions to each of the groups that you selected.

   1. Choose **Next**.

1. In **Deploy app integration**, choose whether you want to manually attach the Lambda authorizer manually later or if you want Verified Permissions to do it for you now and review the steps that Verified Permissions will take to create your policy store and Lambda authorizer.

1. When you're ready to create the new resources, choose **Create policy store**.

1. Keep the **Policy store status** step open in your browser to monitor the progress of resource creation by Verified Permissions.

1. After some time, typically about an hour, or when the **Deploy Lambda authorizer** step shows **Success**, if you chose to attach the authorizer manually, configure your authorizer.

   Verified Permissions will have created a Lambda function and a Lambda authorizer in your API. Choose **Open API** to navigate to your API.

   To learn how to assign a Lambda authorizer, see [Use API Gateway Lambda authorizers](https://docs.amazonaws.cn/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) in the *Amazon API Gateway Developer Guide*.

   1. Navigate to **Authorizers** for your API and note the name of the authorizer that Verified Permissions created.

   1. Navigate to **Resources** and select a top-level method in your API.

   1. Select **Edit** under **Method request settings**.

   1. Set the **Authorizer** to be the authorizer name you noted earlier.

   1. Expand **HTTP request headers**, enter a **Name** or `AUTHORIZATION`, and select **Required**.

   1. Deploy the API stage.

   1. **Save** your changes.

1. Test your authorizer with a user pool token of the **Token type** that you selected in the **Choose identity source** step. For more information about user pool sign-in and retrieving tokens, see [User pool authentication flow](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html) in the *Amazon Cognito Developer Guide*.

1. Test authentication again with a user pool token in the `AUTHORIZATION` header of a request to your API.

1. Examine your new policy store. Add and refine policies.

------
#### [ Sample policy store ]

**To create a policy store using the **Sample policy store** configuration method**

1. In the **Starting options** section, choose **Sample policy store**.

1. In the **Sample project** section, choose the type of sample Verified Permissions application to use.
   + **PhotoFlash** is a sample customer-facing web application that enables users to share individual photos and albums with friends. Users can set fine-grained permissions on who is allowed to view, comment on, and re-share their photos. Account owners can also create groups of friends and organize photos into albums.
   + **DigitalPetStore** is a sample application where anyone can register and become a customer. Customers can add pets for sale, search pets, and place orders. Customers who have added a pet are recorded as the pet owner. Pet owners can update the pet's details, upload a pet image, or delete the pet listing. Customers who have placed an order are recorded as the order owner. Order owners can get details on the order or cancel it. Pet store managers have administrative access.
**Note**  
The **DigitalPetStore** sample policy store does not include policy templates. The **PhotoFlash** and **TinyTodo** sample policy stores include policy templates.
   + **TinyTodo** is a sample application that enables users to create taks and task lists. List owners can manage and share their lists and specify who can view or edit their lists.

1. A namespace for the schema of your sample policy store is automatically generated based on the sample project you chose.

1. Choose **Create policy store**.

   Your policy store is created with policies and a schema for the sample policy store you chose. For more information on template-linked policies you can create for the sample policy stores, see [Amazon Verified Permissions example template-linked policies](policy-templates-example-policies.md).

------
#### [ Empty policy store ]

**To create a policy store using the **Empty policy store** configuration method**

1. In the **Starting options** section, choose **Empty policy store**.

1. Choose **Create policy store**.

An empty policy store is created without a schema, which means policies are not validated. For more information about updating the schema for your policy store, see [Amazon Verified Permissions policy store schema](schema.md).

For more information about creating policies for your policy store, see [Creating Amazon Verified Permissions static policies](policies-create.md) and [Creating Amazon Verified Permissions template-linked policies](policy-templates-create-policy.md).

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

**To create an empty policy store by using the Amazon CLI.**  
You can create a policy store by using the `create-policy-store` operation.

**Note**  
A policy store that you create by using the Amazon CLI is empty.  
To add schema, see [Amazon Verified Permissions policy store schema](schema.md).
 To add policies, see [Creating Amazon Verified Permissions static policies](policies-create.md).
To add policy templates, see [Creating Amazon Verified Permissions policy templates](policy-templates-create.md).

```
$ aws verifiedpermissions create-policy-store \
    --validation-settings "mode=STRICT"
{
    "arn": "arn:aws-cn:verifiedpermissions::123456789012:policy-store/PSEXAMPLEabcdefg111111",
    "createdDate": "2023-05-16T17:41:29.103459+00:00",
    "lastUpdatedDate": "2023-05-16T17:41:29.103459+00:00",
    "policyStoreId": "PSEXAMPLEabcdefg111111"
}
```

------
#### [ Amazon SDKs ]

You can create a policy store using the `CreatePolicyStore` API. For more information, see [CreatePolicyStore](https://docs.amazonaws.cn/verifiedpermissions/latest/apireference/API_CreatePolicyStore.html) in the Amazon Verified Permissions API Reference Guide.

------

# Implementing Amazon Verified Permissions in Rust with the Amazon SDK
Creating a policy store using Rust

This topic provides a practical example of implementing Amazon Verified Permissions in Rust with the Amazon SDK. This example shows how to develop an authorization model that can test whether a user is able to view a photo. The sample code uses the [aws-sdk-verifiedpermissions](https://docs.rs/aws-sdk-verifiedpermissions/latest/aws_sdk_verifiedpermissions/) crate from the [Amazon SDK for Rust](https://github.com/awslabs/aws-sdk-rust), which offers a robust set of tools for interacting with Amazon Web Services services.

## Prerequisites


 Before starting, ensure that you have the [Amazon CLI](https://www.amazonaws.cn/cli/) configured on your system and that you're familiar with Rust.
+ For instructions on installing the Amazon CLI, see [Amazon CLI installation guide](https://docs.amazonaws.cn//cli/latest/userguide/getting-started-install.html).
+ For instructions on configuring the Amazon CLI, see [Configuring settings for the Amazon CLI](https://docs.amazonaws.cn//cli/latest/userguide/cli-configure-quickstart.html) and [Configuration and credential file settings in the Amazon CLI](https://docs.amazonaws.cn//cli/latest/userguide/cli-configure-profiles.html).
+ For more information on Rust, see [rust-lang.org](https://www.rust-lang.org/) and the [Amazon SDK for Rust Developer Guide](https://docs.amazonaws.cn//sdk-for-rust/latest/dg/welcome.html).

With your environment prepared, let's explore how to implement Verified Permissions in Rust.

## Test the sample code


The sample code does the following:
+ Sets up the SDK client to communicate with Amazon
+ Creates a [policy store](policy-stores.md)
+ Defines the structure of the policy store by adding a [schema](schema.md)
+ Adds a [policy](policies.md) to check authorization requests
+ Sends a test [authorization request](authorization.md) to verify everything is set up correctly

**To test the sample code**

1. Create a Rust project.

1. Replace any existing code in `main.rs` with the following code:

   ```
   use std::time::Duration;
   use std::thread::sleep;
   use aws_config::BehaviorVersion;
   use aws_sdk_verifiedpermissions::Client;
   use aws_sdk_verifiedpermissions::{
       operation::{
           create_policy::CreatePolicyOutput,
           create_policy_store::CreatePolicyStoreOutput,
           is_authorized::IsAuthorizedOutput,
           put_schema::PutSchemaOutput,
       },
       types::{
           ActionIdentifier, EntityIdentifier, PolicyDefinition, SchemaDefinition, StaticPolicyDefinition, ValidationSettings
       },
   };
   
   //Function that creates a policy store in the client that's passed
   async fn create_policy_store(client: &Client, valid_settings: &ValidationSettings)-> CreatePolicyStoreOutput {
       let policy_store = client.create_policy_store().validation_settings(valid_settings.clone()).send().await;
       return policy_store.unwrap();
   }
   
   //Function that adds a schema to the policy store in the client
   async fn put_schema(client: &Client, ps_id: &str, schema: &str) -> PutSchemaOutput {
       let schema = client.put_schema().definition(SchemaDefinition::CedarJson(schema.to_string())).policy_store_id(ps_id.to_string()).send().await;
       return schema.unwrap();
   }
   
   //Function that creates a policy in the policy store in the client
   async fn create_policy(client: &Client, ps_id: &str, policy_definition:&PolicyDefinition) -> CreatePolicyOutput {
       let create_policy = client.create_policy().definition(policy_definition.clone()).policy_store_id(ps_id).send().await;
       return create_policy.unwrap();
   }
   
   //Function that tests the authorization request to the policy store in the client
   async fn authorize(client: &Client, ps_id: &str, principal: &EntityIdentifier, action: &ActionIdentifier, resource: &EntityIdentifier) -> IsAuthorizedOutput {
       let is_auth = client.is_authorized().principal(principal.to_owned()).action(action.to_owned()).resource(resource.to_owned()).policy_store_id(ps_id).send().await;
       return is_auth.unwrap();
   }
   
   #[::tokio::main]
   async fn main() -> Result<(), aws_sdk_verifiedpermissions::Error> {
   
   //Set up SDK client
       let config = aws_config::load_defaults(BehaviorVersion::latest()).await;
       let client = aws_sdk_verifiedpermissions::Client::new(&config);
   
   //Create a policy store
       let valid_settings = ValidationSettings::builder()
       .mode({aws_sdk_verifiedpermissions::types::ValidationMode::Strict
       })
       .build()
       .unwrap();
       let policy_store = create_policy_store(&client, &valid_settings).await;
       println!(
       "Created Policy store with ID: {:?}",
       policy_store.policy_store_id
       );
   
   //Add schema to policy store
       let schema= r#"{
           "PhotoFlash": {
               "actions": {
                   "ViewPhoto": {
                       "appliesTo": {
                           "context": {
                               "type": "Record",
                               "attributes": {}
                           },
                           "principalTypes": [
                               "User"
                           ],
                           "resourceTypes": [
                               "Photo"
                           ]
                       },
                       "memberOf": []
                   }
               },
               "entityTypes": {
                   "Photo": {
                       "memberOfTypes": [],
                       "shape": {
                           "type": "Record",
                           "attributes": {
                               "IsPrivate": {
                                   "type": "Boolean"
                               }
                           }
                       }
                   },
                   "User": {
                       "memberOfTypes": [],
                       "shape": {
                           "attributes": {},
                           "type": "Record"
                       }
                   }
               }
           }
       }"#;
       let put_schema = put_schema(&client, &policy_store.policy_store_id, schema).await;
       println!(
           "Created Schema with Namespace: {:?}",
           put_schema.namespaces
       ); 
   
   //Create policy
       let policy_text = r#"
           permit (
               principal in PhotoFlash::User::"alice",
               action == PhotoFlash::Action::"ViewPhoto",
               resource == PhotoFlash::Photo::"VacationPhoto94.jpg"
           );
           "#;
       let policy_definition = PolicyDefinition::Static(StaticPolicyDefinition::builder().statement(policy_text).build().unwrap()); 
       let policy = create_policy(&client, &policy_store.policy_store_id, &policy_definition).await;
       println!(
           "Created Policy with ID: {:?}",
           policy.policy_id
       ); 
   
   //Break to make sure the resources are created before testing authorization
       sleep(Duration::new(2, 0));
   
   //Test authorization
       let principal= EntityIdentifier::builder().entity_id("alice").entity_type("PhotoFlash::User").build().unwrap();
       let action = ActionIdentifier::builder().action_type("PhotoFlash::Action").action_id("ViewPhoto").build().unwrap();
       let resource = EntityIdentifier::builder().entity_id("VacationPhoto94.jpg").entity_type("PhotoFlash::Photo").build().unwrap();
       let auth = authorize(&client, &policy_store.policy_store_id, &principal, &action, &resource).await;
       println!(
           "Decision: {:?}",
           auth.decision
           );
           println!(
           "Policy ID: {:?}",
           auth.determining_policies
           );
        Ok(())   
   }
   ```

1. Run the code by entering `cargo run` in the terminal.

If the code runs correctly, the terminal will show `Decision: Allow` followed by the policy ID of the determining policy. This means you've successfully created a policy store and tested it using the Amazon SDK for Rust.

## Clean up resources


After you have finished exploring your policy store, delete it.

**To delete a policy store**  
You can delete a policy store by using the `delete-policy-store` operation, replacing `PSEXAMPLEabcdefg111111` with the policy store ID you want to delete.

```
$ aws verifiedpermissions delete-policy-store \
    --policy-store-id PSEXAMPLEabcdefg111111
```

If successful, this command produces no output.