This page describes generally how to create basic access levels. To create
custom access levels and use **Advanced Mode** in the Google Cloud console, see
[Creating a custom access level](https://docs.cloud.google.com/access-context-manager/docs/create-custom-access-level.md.txt).

This page includes more focused implementations of access levels. See the
following examples:

- [Limit access on a corporate network](https://docs.cloud.google.com/access-context-manager/docs/create-basic-access-level.md.txt#corporate-network-example)
- [Limit access by device attributes](https://docs.cloud.google.com/access-context-manager/docs/create-basic-access-level.md.txt#device-example)
- [Grant access by user or service account](https://docs.cloud.google.com/access-context-manager/docs/create-basic-access-level.md.txt#members-example)

## Before you begin

- Learn about [access levels](https://docs.cloud.google.com/access-context-manager/docs/overview.md.txt).

> [!NOTE]
> **Note:** In Access Context Manager, you cannot use the Google Cloud console to select a scoped policy under which you want to create an access level. To specify the scoped policy under which to create the access level, you can use the Google Cloud CLI or the API.

## Create a basic access level

### Console

To create a basic access level:

1. Open the **Access Context Manager** page in the Google Cloud console.

   [Open the Access Context Manager page](https://console.cloud.google.com/security/access-level)
2. If you are prompted, select your organization.

3. At the top of the **Access Context Manager** page, click **New**.

4. In the **New Access Level** pane:

   1. In the **Access level title** field, enter a title for the access level.
      The title must be at most 50 characters, start with a letter, and can
      contain only numbers, letters, underscores, and spaces.

   2. In the **Conditions** section, click the
      add button for the type
      of attribute you want to add, and then provide
      the values you want applied to that attribute.

      For a complete list of the attributes you can add,
      read about [access level attributes](https://docs.cloud.google.com/access-context-manager/docs/access-level-attributes.md.txt).

      For example, if you want the access level to consider where a
      request is coming from within your network, you would select the
      **IP Subnetworks** attribute.

      Repeat this step to add multiple attributes to the same condition.
      When a condition has multiple attributes, all of the attributes must
      be met by the access request.

      An access level condition can include one of each type of
      attribute. Some attributes include additional
      options, such as the **Device Policy** attribute.

      Access levels support conditions based on
      user identity. However, to add identities to a condition, you
      must create or update the access level using the gcloud CLI or the API.
   3. Use the **When condition is met, return** option to specify whether
      the condition is evaluated as an **AND** operation that requires a
      request to meet all specified attributes (**TRUE** ), or as a
      negated (**NAND** ) operation that is met when a request doesn't
      meet at least one specified attribute (**FALSE**).

      For example, if you want to deny requests from a certain IP address
      range of your network, specify the IP address range using the
      **IP Subnetworks** attribute and then set the condition to
      **FALSE**.
   4. Optionally, click **Add another condition** to add an
      additional condition to your access level and then repeat
      the previous two steps.

      For example, if you want to deny access to a subset of IP
      addresses within a broader IP address range, create a new
      condition, specify the subset IP address range for the
      **IP Subnetworks** attribute, and set the condition to return
      **FALSE**.

      Repeat this step to add multiple conditions to the same access
      level.
   5. If you created more than one condition, use
      **Combine condition with** to specify whether you want the
      access level to require a request to meet at least one of the
      conditions (**OR** ), or all of the conditions (**AND**).

   6. Click **Save**.

### gcloud

### Before you begin

- If it doesn't exist yet, [create an access policy](https://docs.cloud.google.com/access-context-manager/docs/create-access-policy.md.txt) for your organization.

To create an access level using the `gcloud` command-line tool, use the
[`gcloud access-context-manager levels create`](https://docs.cloud.google.com/sdk/gcloud/reference/access-context-manager/levels/create.md.txt) command.

```bash
gcloud access-context-manager levels create LEVEL_NAME OPTIONS \
    --policy=POLICY
```

Where:

- <var translate="no">LEVEL_NAME</var> is the unique name for the access level. It must
  begin with a letter and include only letters, numbers, and
  underscores. The name can be a maximum of 50 characters.

- <var translate="no">OPTIONS</var> are the required options from the following table.

  | Options ||
  |---|---|
  | `basic-level-spec` | [A YAML file](https://docs.cloud.google.com/access-context-manager/docs/create-basic-access-level.md.txt#yaml-file) that specifies one or more conditions for the access level. |
  | `title` | A short title for the access level. The access level's title is displayed in the Google Cloud console. |
  | `combine-function` | (Optional) Determines how conditions are combined. Valid values: `AND`, `OR` |
  | `description` | (Optional) A long-form description of the access level. |

- <var translate="no">POLICY</var> is the ID of your organization's access policy.
  If you have a default policy set, this parameter is optional.

Optionally, you can include any of the
[gcloud-wide flags](https://docs.cloud.google.com/sdk/gcloud/reference.md.txt).

### basic-level-spec YAML file

When you use the `gcloud` command-line tool to create an access level, you must provide a YAML
file for the `basic-level-spec` option. The YAML file defines one or more
conditions for the access level. Conditions must contain at least one
attribute. When a condition contains more than one attribute, they are
combined as either an **AND** operation (all must be true) or as a **NAND**
operation (at least one must be false), depending on whether the `negate`
attribute is set to true in the condition.

For a complete list of the attributes you can include in your YAML file,
read about [access level attributes](https://docs.cloud.google.com/access-context-manager/docs/access-level-attributes.md.txt).

For more information about access levels and YAML,
refer to the [example YAML for an access level](https://docs.cloud.google.com/access-context-manager/docs/example-yaml-file.md.txt).

### Example command

```bash
gcloud access-context-manager levels create Device_Trust \
    --basic-level-spec=corpdevspec.yaml \
    --combine-function=AND \
    --description='Access level that conforms to corporate spec.' \
    --title='Device_Trust Extended' \
    --policy=1521580097614100
```

### API

### Before you begin

- If it doesn't exist yet, [create an access policy](https://docs.cloud.google.com/access-context-manager/docs/create-access-policy.md.txt) for your organization.

To create an access level, call [`accessLevels.create`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels/create.md.txt).

```
POST https://accesscontextmanager.googleapis.com/v1/accessPolicies/POLICY/accessLevels
```

Where:

- <var translate="no">POLICY</var> is the ID of your organization's access policy.

### Request body

The request body must include an [`AccessLevel`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels.md.txt#AccessLevel)
resource that specifies the conditions you want for the new access level.
Each [`Condition`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels.md.txt#condition) has one or more attributes that are
evaluated as an **AND** operation (all must be true) or as a
**NAND** operation (at least one must be false) depending on whether the
`negate` field is set to true. The resulting evaluation determines
whether the condition is met or not.

### Response body

If successful, the response body for the call contains an
[`Operation`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/Shared.Types/Operation.md.txt) resource that provides details about the
`POST` operation.

## Example implementations

The following examples cover a few of the practical ways your organization might
want to implement access levels. These examples assume your organization already
has an [access policy](https://docs.cloud.google.com/access-context-manager/docs/create-access-policy.md.txt).

### Limit access on a corporate network

This example describes how to create an access level condition that allows
access only from a specified range of IP addresses (for example, those within a
corporate network).

By restricting the range of IP addresses that are granted access, you can
make exfiltrating data more difficult for an attacker that is inside or outside
your organization.

For this example, assume you want to create an access level that will allow a
group of internal auditors to access the Cloud Logging service for a
project named *sensitive-data*. All of the devices for the auditors are
assigned IPs on a subnet ranging between 203.0.113.0 and 203.0.113.127. You
know there won't be any devices assigned to that subnet other than those
used by the auditors.

If you want to use a private IP address range (for example, `192.168.0.0/16`
or `172.16.0.0/12`), see [Allow access to protected resources from an internal
IP address](https://docs.cloud.google.com/vpc-service-controls/docs/enable-internal-ip-access) for additional
information and an example implementation using VPC Service Controls.

### Console

1. Open the **Access Context Manager** page in the Google Cloud console.

   [Open the Access Context Manager page](https://console.cloud.google.com/security/access-level)
2. If you are prompted, select your organization.

3. At the top of the **Access Context Manager** page, click **New**.

4. In the **New Access Level** pane, in the **Conditions** section, click
   **Add attribute** and then click **IP Subnetworks**.

5. In the **IP Subnetworks** box, select either **Public IP** or **Private
   IP**.

   - If you select **Public IP** , enter one or more IPv4 or IPv6 ranges
     formatted as [CIDR](https://wikipedia.org/wiki/Classless_Inter-Domain_Routing) blocks.

     In this example, to limit access to only the auditors, enter
     `203.0.113.0/25` in the **IP Subnetworks** box.
   - If you select **Private IP** , click **Select VPC networks** . You can
     specify VPC networks using one of the three options
     available in the **Import options** list.

     - *Option 1:*

       1. Select **Browse for VPC networks in your organization** and select the
          VPC networks.

       2. Click **Add selected VPC networks**.

       3. Click **Select IP subnets** and select the subnets.

       4. Click **Add IP subnets**.

     - *Option 2:*

       1. Select **Manually enter VPC network address** and enter one or more
          VPC networks.

       2. Click **Add VPC network**.

       3. Click **Select IP subnets** and select the subnets.

       4. Click **Add IP subnets**.

     - *Option 3:*

       1. Select **Upload CSV file (overwrites existing networks)**.

          If you use a CSV file to add VPC networks and subnets
          to an access level, Access Context Manager overwrites the previously selected VPC
          networks and subnets.
       2. Click **Browse** and upload the CSV file. In the CSV file, you must specify
          the VPC networks and subnets in the following format:

          ```
          VPC_NETWORK_NAME_1       | IP_RANGE_1       | IP_RANGE_2       | ...
          VPC_NETWORK_NAME_2       | .                | .                | ...
          .                        | .                | .                | ...
          .                        | .                | .                | ...
          ```
       3. Click **Import networks**.

          Using the CSV file, Access Context Manager populates the VPC network
          names and subnet information in the **VPC network address** and **IP
          subnetworks** boxes respectively.

     For information about the VPC network name and private
     IP address format, see [Use internal IP address in access
     levels](https://docs.cloud.google.com/vpc-service-controls/docs/enable-internal-ip-access#enable).
6. Click **Save**.

### gcloud

1. Create a YAML file for an access level that includes one or more
   IPv4 or IPv6 ranges formatted as [CIDR](https://wikipedia.org/wiki/Classless_Inter-Domain_Routing) blocks.

   In this example, to limit access to only the auditors, you would enter
   the following into the YAML file:

   ```yaml
   - ipSubnetworks:
     - 203.0.113.0/25
   ```

   If you want to use a private IP address, you need to enter the following
   information in the YAML file:

   ```yaml
   - vpcNetworkSources:
     - vpcSubnetwork:
         network: VPC_NETWORK_NAME
         vpcIpSubnetworks:
         - IP_RANGE
   ```

   Replace <var translate="no">VPC_NETWORK_NAME</var> and <var translate="no">IP_RANGE</var> with the values
   described in the [Use internal IP address in access
   levels](https://docs.cloud.google.com/vpc-service-controls/docs/enable-internal-ip-access#enable) section.
2. Save the file. In this example, the file is named *CONDITIONS.yaml*.

3. Create the access level.

   ```bash
   gcloud access-context-manager levels create NAME \
      --title TITLE \
      --basic-level-spec CONDITIONS.yaml \
      --policy=POLICY
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

   - <var translate="no">POLICY</var> is the ID of your organization's
     access policy. If you have a default policy set, this parameter is
     optional.

   You should see output similar to:

   ```
   Create request issued for: NAME
   Waiting for operation [accessPolicies/POLICY/accessLevels/NAME/create/1521594488380943] to complete...done.
   Created level NAME.
   ```

### API

1. Craft a request body to create an [`AccessLevel`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels.md.txt#AccessLevel)
   resource that includes one or more IPv4 or IPv6 ranges formatted
   as [CIDR](https://wikipedia.org/wiki/Classless_Inter-Domain_Routing) blocks.

   In this example, to limit access to only the auditors, you would enter
   the following into the request body:

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "ipSubnetworks": [
            "203.0.113.0/25"
          ]
        }
      ]
    }
   }
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

   If you want to use a private IP address, you need to enter the following
   information in the request body:

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "vpcNetworkSources": [
           {
             "vpcSubnetwork": {
               "network": VPC_NETWORK_NAME,
               "vpcIpSubnetworks": [
                 IP_RANGE
               ]
             }
           }
          ]
        }
      ]
    }
   }
   ```

   Replace <var translate="no">VPC_NETWORK_NAME</var> and <var translate="no">IP_RANGE</var> with the values
   described in the [Use internal IP address in access
   levels](https://docs.cloud.google.com/vpc-service-controls/docs/enable-internal-ip-access#enable) section.
2. Create the access level by calling [`accessLevels.create`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels/create.md.txt).

   ```
   POST https://accesscontextmanager.googleapis.com/v1/accessPolicies/POLICY/accessLevels
   ```

   Where:
   - <var translate="no">POLICY</var> is the ID of your organization's access policy.

### Limit access by device attributes

This example describes how to create an access level that grants access only to
devices, which meet a specified set of requirements, like a certain operating
system (OS) version.

Information about devices is provided to Access Context Manager using
[Endpoint Verification](https://support.google.com/cloudidentity/answer/9007320).
The following criteria can be checked when determining whether to grant access:

- Screen lock is enabled
- Storage encryption is enabled
- Device is running a specified operating system kind and version

> [!IMPORTANT]
> **Important:** You must have a paid subscription to use [device attributes](https://docs.cloud.google.com/access-context-manager/docs/custom-access-level-spec.md.txt#device) in custom access level expressions. You can [sign up](https://docs.cloud.google.com/chrome-enterprise-premium/docs/overview.md.txt) if interested.

For this example, assume your organization uses only machines that have either
Chrome OS or Windows installed. To add a layer of security, you want to create
an access level that will prevent access by anyone using other operating
systems. Additionally, to manage risk, you want to make sure that only certain
versions of the OSes can gain access.

### Console

1. Open the **Access Context Manager** page in the Google Cloud console.

   [Open the Access Context Manager page](https://console.cloud.google.com/security/access-level)
2. If you are prompted, select your organization.

3. At the top of the **Access Context Manager** page, click **New**.

4. In the **New Access Level** pane, in the **Conditions** section,
   click **Add attribute** and then click **Device Policy**.

5. Add the device policy attributes:

   1. Click **Add OS Policy** and then click **Chrome OS Policy**.

   2. In the **Minimum version** box, enter the minimum version of Chrome
      OS you want to allow.

   3. Repeat steps 1 and 2 for **Windows OS Policy**.

6. Click **Save**.

### gcloud

1. Create a YAML file for an access level that includes a device policy with
   OS constraints.

   In this example, to allow only devices with a minimum acceptable version
   of Chrome OS and Windows, you would enter the following into the YAML
   file:

   ```yaml
   - devicePolicy:
       osConstraints:
         - osType: DESKTOP_CHROME_OS
           minimumVersion: 11316.165.0
         - osType: DESKTOP_WINDOWS
           minimumVersion: 10.0.1809
   ```
2. Save the file. In this example, the file is named *CONDITIONS.yaml*.

3. Create the access level.

   ```bash
   gcloud access-context-manager levels create NAME \
      --title TITLE \
      --basic-level-spec CONDITIONS.yaml \
      --policy=POLICY
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

   - <var translate="no">POLICY</var> is the ID of your organization's
     access policy. If you have a default policy set, this parameter is
     optional.

   You should see output similar to:

   ```
   Create request issued for: NAME
   Waiting for operation [accessPolicies/POLICY/accessLevels/NAME/create/1521594488380943] to complete...done.
   Created level NAME.
   ```

### API

1. Craft a request body to create an [`AccessLevel`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels.md.txt#AccessLevel)
   resource that includes a device policy with OS constraints.

   In this example, to allow only devices with a minimum acceptable version
   of Chrome OS and Windows, you would enter the following into the request
   body:

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "devicePolicy": {
            "osConstraints": [
              {
                "osType": "DESKTOP_CHROME_OS",
                "minimumVersion": "11316.165.0"
              },
              {
                "osType": "DESKTOP_WINDOWS",
                "minimumVersion": "10.0.1809"
              }
            ]
         }
        }
      ]
     }
   }
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

2. Create the access level by calling [`accessLevels.create`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels/create.md.txt).

   ```
   POST https://accesscontextmanager.googleapis.com/v1/accessPolicies/POLICY/accessLevels
   ```

   Where:
   - <var translate="no">POLICY</var> is the ID of your organization's access policy.

### Grant access by user or service account

Access levels for human users often combine identity with other context
like IP addresses. In contrast, access levels for service accounts are defined
based on the specific service account identity. For example, Cloud Functions
requires an identity to interact with other Google Cloud services.

The following information describes how to grant access to specific users and service
accounts, while including existing access levels to show an example of
nested access levels. In this case, the specified users are included in this
access level regardless of whether they meet the conditions specified in the
existing access levels. This new access level could be considered as a
less-restrictive tier than the existing access levels.

### Console

The Google Cloud console does not currently support adding principals to
access levels. If you want to add principals to access levels, you must
use the `gcloud` command-line tool or the API.

### gcloud

1. Create a YAML file that contains a condition that lists the principals
   that you want to provide access to.

   Add a system administrator
   (`sysadmin@example.com`) and a service account
   (`service@project.iam.gserviceaccount.com`).

   ```yaml
   - members:
       - user:sysadmin@example.com
       - serviceAccount:service@project.iam.gserviceaccount.com
   ```
2. Add a condition that lists the existing access levels that you want to
   include in this access level.

   In this example, assume the access levels are named `Device_Trust` and
   `IP_Trust`, and that `247332951433` is the name of your access policy.

   ```yaml
   - members:
       - user:sysadmin@example.com
       - serviceAccount:service@project.iam.gserviceaccount.com

   - requiredAccessLevels:
       - accessPolicies/247332951433/accessLevels/Device_Trust
       - accessPolicies/247332951433/accessLevels/IP_Trust
   ```
3. Save the file. In this example, the file is named *CONDITIONS.yaml*.

4. Create the access level, using the [`create`](https://docs.cloud.google.com/sdk/gcloud/reference/access-context-manager/levels/create.md.txt) command.

   ```bash
   gcloud access-context-manager levels create NAME \
      --title TITLE \
      --basic-level-spec CONDITIONS.yaml \
      --combine-function=OR \
      --policy=POLICY
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

   - <var translate="no">POLICY</var> is the ID of your organization's
     access policy. If you have a default policy set, this parameter
     is optional.

   - `combine-function` is set to `OR`. The default value, `AND`, requires
     *all* conditions be met before an access level is granted. The `OR`
     value will give the principals access even if other conditions are
     not met.

   You should see output similar to:

   ```
   Create request issued for: NAME
   Waiting for operation [accessPolicies/POLICY/accessLevels/NAME/create/1521594488380943] to complete...done.
   Created level NAME.
   ```

### API

1. Craft a request body to create an [`AccessLevel`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels.md.txt#AccessLevel)
   resource that includes a condition that lists the principals
   that you want to provide access to.

   In this example, you want to add your system administrator
   (`sysadmin@example.com`) and a service account
   (`service@project.iam.gserviceaccount.com`).

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "members": [
            "user:sysadmin@example.com",
            "serviceAccount:service@project.iam.gserviceaccount.com"
          ]
        }
      ]
    }
   }
   ```

   Where:
   - <var translate="no">NAME</var> is the unique name for the access level. It must
     begin with a letter and include only letters, numbers, and
     underscores.

   - <var translate="no">TITLE</var> is a human-readable title. It must be unique to the
     policy.

2. Add a condition that lists the existing access levels that you want to
   include in this access level.

   In this example, assume the access levels are named `Device_Trust` and
   `IP_Trust`, and that `247332951433` is the name of your access policy.

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "members": [
            "user:sysadmin@example.com",
            "serviceAccount:service@project.iam.gserviceaccount.com"
          ]
        },
        {
          "requiredAccessLevels": [
            "accessPolicies/247332951433/accessLevels/Device_Trust",
            "accessPolicies/247332951433/accessLevels/IP_Trust"
          ]
        }
      ]
    }
   }
   ```
3. Set `combiningFunction` to `OR`.

   The default value for `combiningFunction`, `AND`, requires
   *all* conditions be met before an access level is granted. The `OR`
   value will give the principals access even if other conditions, such as
   IP address or those inherited from other required access levels, are
   not met.

   ```json
   {
    "name": "NAME",
    "title": "TITLE",
    "basic": {
      "conditions": [
        {
          "members": [
            "user:sysadmin@example.com",
            "serviceAccount:service@project.iam.gserviceaccount.com"
          ]
        },
        {
          "requiredAccessLevels": [
            "accessPolicies/247332951433/accessLevels/Device_Trust",
            "accessPolicies/247332951433/accessLevels/IP_Trust"
          ]
        }
      ],
      "combiningFunction": "OR"
    }
   }
   ```
4. Create the access level by calling [`accessLevels.create`](https://docs.cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.accessLevels/create.md.txt).

   ```
   POST https://accesscontextmanager.googleapis.com/v1/accessPolicies/POLICY/accessLevels
   ```

   Where:
   - <var translate="no">POLICY</var> is the ID of your organization's access policy.