

# Verified Access policies
<a name="auth-policies"></a>

AWS Verified Access policies allow you to define rules for accessing your applications hosted in AWS. They are written in Cedar, an AWS policy language. Using Cedar, you can create policies that are evaluated against the trust data sent from the identity or device-based trust providers that you configure to use with Verified Access.

For more detailed information about the Cedar policy language, see the [Cedar Reference Guide](https://docs.cedarpolicy.com/).

When you [create a Verified Access group](create-verified-access-group.md) or [create a Verified Access endpoint](verified-access-endpoints.md), you have the option to define the Verified Access policy. You can create a group or endpoint without defining the Verified Access policy, but all access requests will be blocked until you define a policy. Alternatively, you can add or change a policy on an existing Verified Access group or endpoint after it has been created.

**Topics**
+ [Policy statements](auth-policies-policy-statement-struct.md)
+ [Built-in operators](built-in-policy-operators.md)
+ [Policy evaluation](auth-policies-policy-eval.md)
+ [Policy logic short circuit](auth-policies-policy-eval-short-circ.md)
+ [Example policies](trust-data-iam-add-pol.md)
+ [Policy assistant](policy-assistant.md)

# Verified Access policy statement structure
<a name="auth-policies-policy-statement-struct"></a>

The following table shows the structure of a Verified Access policy.


| Component | Syntax | 
| --- | --- | 
| effect | `permit \| forbid` | 
| scope | `(principal, action, resource)` | 
| condition clause | <pre>when {<br />    context.policy-reference-name.attribute-name             <br />};</pre>  | 

## Policy components
<a name="auth-policies-policy-components"></a>

A Verified Access policy contains the following components:
+ **Effect** – Either `permit` (allow) or `forbid` (deny) access.
+ **Scope** – The principals, actions, and resources to which the effect applies. You can leave the scope in Cedar undefined by not identifying specific principals, actions, or resources. In this case, the policy applies to all possible principals, actions, and resources.
+ **Condition clause** – The context in which the effect applies.

**Important**  
For Verified Access, policies are fully expressed by referring to trust data in the condition clause. **The policy scope must always be kept undefined**. You can then specify access using identity and device trust context in the condition clause.

## Comments
<a name="auth-policies-policy-comments"></a>

You can include comments in your AWS Verified Access policies. Comments are defined as a line starting with `//` and ending with a newline character.

The following example shows comments in a policy.

```
// grants access to users in a specific domain using trusted devices
permit(principal, action, resource)
when {
  // the user's email address is in the @example.com domain
  context.idc.user.email.address.contains("@example.com")
  // Jamf thinks the user's computer is low risk or secure.
  && ["LOW", "SECURE"].contains(context.jamf.risk)
};
```

## Multiple clauses
<a name="auth-policies-multiple-clauses"></a>

You can use more than one condition clause in a policy statement using the `&&` operator.

```
permit(principal,action,resource)
when{
 context.policy-reference-name.attribute1 &&
 context.policy-reference-name.attribute2
};
```

For additional examples, see [Verified Access example policies](trust-data-iam-add-pol.md).

## Reserved characters
<a name="auth-policies-semicolon"></a>

The following example shows how to write a policy if a context property uses a `:` (semicolon), which is a reserved character in the policy language.

```
permit(principal, action, resource) 
when {
    context.policy-reference-name["namespace:groups"].contains("finance")
};
```

# Built-in operators for Verified Access policies
<a name="built-in-policy-operators"></a>

When creating the context of an AWS Verified Access policy using various conditions, as discussed in [Verified Access policy statement structure](auth-policies-policy-statement-struct.md), you can use the `&&` operator to add additional conditions. There are also many other built-in operators that you can use to add additional expressive power to your policy conditions. The following table contains all the built-in operators for reference.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/verified-access/latest/ug/built-in-policy-operators.html)

# Verified Access policy evaluation
<a name="auth-policies-policy-eval"></a>

A policy document is a set of one or more policy statements (`permit` or `forbid` statements). The policy applies if the conditional clause (the `when` statement) is true. In order for a policy document to allow access, at least one permit policy in the document must apply and no forbid policies can apply. If no permit policies apply and/or one or more forbid policies apply, then the policy document denies access. If you have defined policy documents for both the Verified Access group and the Verified Access endpoint, both documents must allow access. If you have not defined a policy document for the Verified Access endpoint, only the Verified Access group policy needs access.

AWS Verified Access validates the syntax when you create the policy, but it does not validate the data you put in the conditional clause.

# Verified Access policy logic short-circuiting
<a name="auth-policies-policy-eval-short-circ"></a>

You might want to write an AWS Verified Access policy that evaluates data that may or may not be present in a given context. If you reference data in a context that does not exist, Cedar will produce an error and evaluate the policy to deny access, regardless of your intent. For example, this would result in a deny, as `fake_provider` and `bogus_key` do not exist in this context.

```
permit(principal, action, resource) when {
  context.fake_provider.bogus_key > 42
};
```

To avoid this situation, you can check to see if a key is present by using the `has` operator. If the `has` operator returns false, further evaluation of the chained statement halts, and Cedar does not produce an error attempting to reference an item that does not exist.

```
permit(principal, action, resource) when {
  context.identity.user has "some_key" && context.identity.user.some_key > 42
};
```

This is most useful when specifying a policy that references two different trust providers.

```
permit(principal, action, resource) when {
  // user is in an allowed group
  context.aws_idc.groups has "c242c5b0-6081-1845-6fa8-6e0d9513c107"
  &&( 
    ( 
      // if CrowdStrike data is present, 
      // permit if CrowdStrike's overall assessment is over 50
      context has "crowdstrike" && context.crowdstrike.assessment.overall > 50
    )
    || 
    (
      // if Jamf data is present,
      // permit if Jamf's risk score is acceptable
      context has "jamf" && ["LOW", "NOT_APPLICABLE", "MEDIUM", "SECURE"].contains(context.jamf.risk) 
    )
  )
};
```

# Verified Access example policies
<a name="trust-data-iam-add-pol"></a>

You can use Verified Access policies to grant access to your applications to specific users and devices.

**Topics**
+ [

## Example 1: Grant access to a group in IAM Identity Center
](#example-policy-iam-identity-center)
+ [

## Example 2: Grant access to a group in a third-party provider
](#example-policy-oidc-provider)
+ [

## Example 3: Grant access using CrowdStrike
](#example-policy-crowdstrike)
+ [

## Example 4: Allow or deny a specific IP address
](#example-policy-ip-address)

## Example 1: Grant access to a group in IAM Identity Center
<a name="example-policy-iam-identity-center"></a>

When using AWS IAM Identity Center, it is better to refer to groups by using their IDs. This helps to avoid breaking a policy statement if you change the name of the group.

The following example policy allows access only to users in the specified group with a verified email address. The group ID is c242c5b0-6081-1845-6fa8-6e0d9513c107.

```
permit(principal,action,resource)
when {
    context.policy-reference-name.groups has "c242c5b0-6081-1845-6fa8-6e0d9513c107"
    && context.policy-reference-name.user.email.verified == true
};
```

The following example policy allows access only when the user is in the specified group, the user has a verified email address, and the Jamf device risk score is `LOW`.

```
permit(principal,action,resource)
when {
    context.policy-reference-name.groups has "c242c5b0-6081-1845-6fa8-6e0d9513c107"
    && context.policy-reference-name.user.email.verified == true
    && context.jamf.risk == "LOW"
};
```

For more information about the trust data, see [AWS IAM Identity Center context for Verified Access trust data](trust-data-iam.md).

## Example 2: Grant access to a group in a third-party provider
<a name="example-policy-oidc-provider"></a>

The following example policy allows access only when the user is in the specified group, the user has a verified email address, and the Jamf device risk score is LOW. The name of the group is "finance".

```
permit(principal,action,resource)
when {
     context.policy-reference-name.groups.contains("finance") 
     && context.policy-reference-name.email_verified == true
     && context.jamf.risk == "LOW"
};
```

For more information about the trust data, see [Third-party trust provider context for Verified Access trust data](trust-data-third-party-trust.md).

## Example 3: Grant access using CrowdStrike
<a name="example-policy-crowdstrike"></a>

The following example policy allows access when the overall assessment score is greater than 50.

```
permit(principal,action,resource)
when {
    context.crwd.assessment.overall > 50 
};
```

## Example 4: Allow or deny a specific IP address
<a name="example-policy-ip-address"></a>

The following example policy allows HTTP requests from the specified IP address.

```
permit(principal, action, resource) 
when {
    context.http_request.client_ip == "192.0.2.1"
};
```

The following example policy denies HTTP requests from the specified IP address.

```
forbid(principal,action,resource) 
when { 
    ip(context.http_request.client_ip).isInRange(ip("192.0.2.1/32")) 
};
```

The following example policy allows TCP requests from the specified IP address.

```
permit(principal, action, resource) 
when {
    context.tcp_flow.client_ip == "192.0.2.1"
};
```

# Verified Access policy assistant
<a name="policy-assistant"></a>

The Verified Access policy assistant is a tool in the Verified Access console that you can use to test and develop your polices. It presents the endpoint policy, the group policy, and the trust context on one screen, where you can test and make edits to the policies.

Trust context formats vary across different trust providers, and sometimes the Verified Access administrator might not know the exact format a certain trust provider uses. That is why it can be very helpful to see the trust context, and both the group and endpoint policies in one place for testing and developing purposes.

The following sections describe the basics of using the policy editor.

**Topics**
+ [

## Step 1: Specify your resources
](#specify-resources)
+ [

## Step 2: Test and edit policies
](#test-and-edit)
+ [

## Step 3: Review and apply changes
](#review-and-commit)

## Step 1: Specify your resources
<a name="specify-resources"></a>

On the first page of the policy assistant, you specify the Verified Access endpoint that you want to work with. You will also specify a user (identified by email address), and optionally, the user’s name and/or a device identifier. By default, the most recent authorization decision is extracted from the Verified Access logs for the specified user. You can optionally choose the most recent allow *or* deny decision specifically.

Finally, the trust context, authorization decision, endpoint policy, and group policy are all displayed on the next screen. 

**To open the policy assistant and specify your resources**

1. Open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, choose **Verified Access instances**, then click the **Verified Access instance ID** for the instance you want to work with.

1. Choose **Launch policy assistant**.

1. For **User email address**, enter the email address of the user.

1. For **Verified Access endpoint**, select the endpoint that you want to edit and test policies for.

1. (Optional) For **Name**, provide the name of the user.

1. (Optional) Under **Device identifier**, provide the unique device identifier.

1. (Optional) For **Authorization result**, choose the type of recent authorization result you want to use. By default, the latest authorization result will be used.

1. Choose **Next**.

## Step 2: Test and edit policies
<a name="test-and-edit"></a>

On this page you will be presented with the following information to work with:
+ The trust context sent by your trust provider for the user and (optionally) the device that you specified in the previous step.
+ The Cedar policy for the Verified Access endpoint specified in the previous step.
+ The Cedar policy for the Verified Access group that the endpoint belongs to.

The Cedar policies for the Verified Access endpoint and group can be edited on this page, but the trust context is static. You can now use this page to view the trust context along side the Cedar policies.

Test the polices against the trust context by choosing the **Test policies** button, and the authorization result will be displayed on the screen. You can make edits to the policies and retest your changes, repeating the process as needed.

After you are satisfied with the changes made to the policies, choose **Next** to continue to the next screen of the policy assistant.

## Step 3: Review and apply changes
<a name="review-and-commit"></a>

On the final page of the policy assistant, you will see the changes you made to the policies highlighted for easy review. You can now review them a final time and choose **Apply changes** to commit the changes.

You also have the option of going back to the previous page by choosing **Previous**, or cancelling out of the policy assistant completely by choosing **Cancel**.