This article describes use cases for Context-Aware Access that include policies using custom access levels. In these examples, you create custom access levels in Advanced mode, using Common Expressions Language (CEL).
Note that if you prefer, you can also use functions and macros when building custom access levels using CEL expressions.
For examples of access levels developed in Basic mode (using the Context-Aware access interface), go to Context-Aware Access examples for Basic mode.
Authentication examples
To improve the security of access to applications which contain sensitive data you can determine how the user authenticated to the system to decide whether they get access to the application.
For example, users logged in with just a password can only be allowed to access applications that do not contain any sensitive information, whereas a user logged in with a hardware security key as a second factor can be allowed to access the most sensitive enterprise applications.
This access level uses request.auth attributes to verify that the users log in using both a password and a hardware key for 2-step verification, and can access sensitive applications.
request.auth.claims.crd_str.pwd == true && request.auth.claims.crd_str.hwk == true
Often administrators want to enforce access to corporate resources only after the user has authenticated with strong credentials. The following example uses levels and request.auth attributes as follows:
- If a user is coming from a corporate device, any MFA, except SMS, method will suffice (Methods can be push notification, hardware or software security key, or one time password)
- If a user is coming from a NON-corporate device, then either a hardware or software security key must be used
// Require basic MFA (not SMS) on corporate devices and security key (hardware or software) if not
levels.Require_Secure_Device &&
(
(
levels.Require_Corporate_Device &&
request.auth.claims.crd_str.mfa &&
!request.auth.claims.crd_str.sms
) ||
(
!levels.Require_Corporate_Device &&
(
request.auth.claims.crd_str.hwk || request.auth.claims.crd_str.swk
)
)
)
Device examples
Expand section | Collapse all & go to top
You can use device signals reported by a BeyondCorp Alliance partner. In this example, Lookout Software is used as the application.
This access level uses the device attribute to verify that the device used to access Google Workspace is reported by Lookout as compliant with policies, and the health score is Very Good.
device.vendors["Lookout"].is_compliant_device == true && device.vendors["Lookout"].device_health_score == DeviceHealthScore.VERY_GOOD
This access level uses the device attribute to verify that users are using the latest version of a managed Chrome browser, and allows access only through such a browser.
device.chrome.management_state == ChromeManagementState.CHROME_MANAGEMENT_STATE_BROWSER_MANAGED && device.chrome.versionAtLeast("94.0.4606.81")
You can use enterprise certificates for devices in custom access levels to determine if a device is a corporate-owned asset. This access level uses the device attribute for the asset verification. Read Configuring enterprise certificate conditions for more information and examples.
A device can have more than one certificate. Enterprise certificates are used in a custom access level using the exists() macro. For example:
device.certificates.exists(cert, predicate)
In this example, cert is a simple identifier to use in the variable predicate to bind to the device enterprise certificate. The exists() macro combines per-element predicate results with the or (||) operator. Macros return true if at least one certificate satisfies the predicate expression.
The table below lists attributes you can use to form CEL expressions to use with custom access levels. Note that string comparisons are case sensitive.
Attribute | Description | Example of predicate expression (where cert is an identifier of macros) |
---|---|---|
is_valid |
True if the certificate is valid and not expired. |
cert.is_valid |
cert_fingerprint | Fingerprint of the certificate (base64 unpadded SHA256) |
cert.cert_fingerprint == origin. |
root_ca_fingerprint | Fingerprint of root CA certificate used to sign this certificate (base64 unpadded SHA256) |
cert.root_ca_fingerprint == "the_fingerprint" |
issuer |
Issuer name To find the issuer name, run the following command on the cert:
The issuer string used in the access level is the reverse of the output and the “/” replaced by a comma, for example:
|
cert.issuer == "EMAILADDRESS=test_inter1 |
subject | Subject name of the certificate (fully expanded names) |
cert.subject == "CA_SUB" |
serial_number |
Serial number of the certificate |
cert.serial_number == “123456789” |
template_id | Template Id of X.509 extension Certificate Template for the certificate (string) |
cert.template_id == "1.3.6.1.4.1.311.21. |
Examples of commonly-used policies:
Validate that the device has a valid enterprise certificate signed by the company root certificate
device.certificates.exists(cert, cert.is_valid && cert.root_ca_fingerprint == "ROOT_CA_FINGERPRINT")
Validate the issuer of the enterprise certificate on the device
device.certificates.exists(cert, cert.is_valid && cert.issuer == "[email protected], CN=inter_1, OU=BCEDemo_1, O=BCEDemo, L=NCR, ST=UP, C=IN”)
This example uses the device attribute to require both disk encryption and screen lock to be enabled. In addition, the device has to be approved by administrators.
By default, all devices created by Endpoint Verification are approved. However, there are cases where you may want to block a device such as when a device is lost. In these cases you would not want these devices to be able to access the corporate resources.
For other access level examples in this document, we will assume this access level has the name Require_Secure_Device
.
// Require disk encryption and screen lock enabled
// This is applicable across all major platforms (Windows, Mac, Linux, CrOS, iOS, Android)
// This foundational and should be depended upon by all other access levels
device.encryption_status == DeviceEncryptionStatus.ENCRYPTED &&
device.is_secured_with_screenlock &&
device.is_admin_approved_device
In this example the access level uses the device attribute to require Chrome browser with basic security requirements.
// Require Chrome to be managed at profile or browser level, must have
// security event reporting enabled and must be version 97 or greater
levels.Require_Secure_Device &&
(
device.chrome.management_state == ChromeManagementState.CHROME_MANAGEMENT_STATE_BROWSER_MANAGED ||
device.chrome.management_state == ChromeManagementState.CHROME_MANAGEMENT_STATE_PROFILE_MANAGED
) &&
device.chrome.is_security_event_analysis_enabled &&
device.chrome.versionAtLeast("97")
This example uses the device attribute to require that the user comes from a managed Chrome browser or profile, and that Chrome has threat and data protection connectors turned on. The example uses the levels attribute to refer to the previously described Require Managed Chrome access level. The following example assumes the dependent access level is named Require_Managed_Chrome
.
// Require managed chrome (dependent on “Require_Managed_Chrome” access level)
// and require content inspection for downloads as well as URL check enabled
levels.Require_Managed_Chrome &&
device.chrome.is_file_download_analysis_enabled &&
device.chrome.is_realtime_url_check_enabled
A requirement for controlling access is to only allow access when the device is managed or owned by the company. There are many ways to determine whether a device is corporate-owned or managed, including:
- If a device has a serial number that matches one that’s in the company’s asset management system
- If a device has a valid enterprise certificate that’s issued by the company
These two approaches can be used in the following custom access level that uses levels and device attributes to determine if the device is corporate-owned or managed.
// The device is a corporate if one of the following conditions is true:
// 1. If the serial number matches what the admin has uploaded
// 2. If the device has a valid enterprise-issued certificate
levels.Require_Secure_Device &&
(
device.is_corp_owned_device ||
device.certificates.exists(cert, cert.is_valid && cert.root_ca_fingerprint == "SOME_ROOT_CA_FINGERPRINT")
)
The fingerprint is the unpadded base64
encoded sha256 digest
(in binary format) of the DER-encoded certificate. The string can be generated from the certificate in PEM format using the following procedure with openssl
:
$ openssl x509 -in cert.pem -out cert.der -outform DER
$ openssl dgst -sha256 -binary cert.der > digest.sha
$ openssl base64 -in digest.sha
- Issued at timestamp (iat)
- Expiry timestamp (exp) (which seems to be 2 weeks from issued at Timestamp in the current release)
The access level uses the device attribute to ensure that CrowdStrike data is fresh. Note that Chrome Enterprise Premium has an innate delay of 90 minutes for consuming any new assessment from Falcon ZTA, so using durations less than an hour is ill-advised.
// Ensure one of these conditions is true for data from Crowdstrike:
// Must meet one of these conditions
// 1. Device was assessed within the last day
// 2. Assessment has not expired (2 weeks since last iat)
“CrowdStrike” in device.vendors && (
request.time - timestamp(device.vendors["CrowdStrike"].data["iat"]) < duration("1d") ||
timestamp(device.vendors["CrowdStrike"].data["exp"]) - request.time > duration("0m")
)
Chrome Enterprise Premium
works with many BeyondCorp Alliance ecosystem partners to integrate their device signals and context into the Chrome Enterprise Premium
solution. Partners can share any number of attributes with Chrome Enterprise Premium
, and one of them is the is_compliant_device attribute
. The following example uses the device attribute to show how we can check if any of the BeyondCorp Alliance partners have integrated with Chrome Enterprise Premium
and consider the device to be compliant.
The exists
macro expands the expression for each of the BeyondCorp Alliance partners with a ||
(or) operator.
// Check to see if any of the BCA partners consider the device to be compliant
["CrowdStrike", "Tanium", "PANW", "Check Point", "Lookout"].exists(
v, v in device.vendors && device.vendors[v].is_compliant_device
)
This example uses device attributes to ensure that devices are running a safe version of Android.
Verified Boot checks if executed code comes from a trusted source (usually device OEMs), rather than from an attacker or corruption. For details, go to Verified Boot.
// Require green Android verified boot status
device.android_device_security.verified_boot == true
This example uses device attributes to require devices to pass Compatibility Test Suite (CTS) compliance checks. For details, go to Compatibility Test Suite.
// Require devices to pass CTS compliance checks
device.android_device_security.cts_profile_match == true
This example uses device attributes to require devices to have Google Play Protect Verify Apps turned on.
Verify Apps scans apps for threats when they’re installed from sources other than Google Play. It also periodically scans devices for potentially harmful apps. Verify Apps is on by default. For devices under advanced management, you can specify whether users can turn it off. For more information, see Apply settings for Android mobile devices.
// Require devices to have Google Play Protect Verify Apps enabled
device.android_device_security.verify_apps_enabled == true
This example uses device attributes to deny access to devices that have potentially harmful apps. These apps are often called malware. For details, go to Potentially Harmful Applications (PHAs).
// Deny access to devices that have potentially harmful appsandroid_device_security.has_potentially_harmful_apps != true
Time-based access examples
Expand section | Collapse all & go to top
Enterprises want to ensure that their shift workers can only access corporate resources during their shift hours. The following access levels use the levels attribute to define 3 shifts during Monday to Friday.
// Shift 1 - Monday to Friday, midnight to 8am
levels.Require_Secure_Device &&
request.time.getDayOfWeek("America/Los_Angeles") >= 1 &&
request.time.getDayOfWeek("America/Los_Angeles") <= 5 &&
request.time.timeOfDay("America/Los_Angeles").between('00:00:00', '08:00:00')
// Shift 2 - Monday to Friday, 8am to 4pm
levels.Require_Secure_Device &&
request.time.getDayOfWeek("America/Los_Angeles") >= 1 &&
request.time.getDayOfWeek("America/Los_Angeles") <= 5 &&
request.time.timeOfDay("America/Los_Angeles").between('08:00:00', '16:00:00')
// Shift 3 - Monday to Friday, 4pm to midnight
levels.Require_Secure_Device &&
request.time.getDayOfWeek("America/Los_Angeles") >= 1 &&
request.time.getDayOfWeek("America/Los_Angeles") <= 5 &&
request.time.timeOfDay("America/Los_Angeles").between('16:00:00', '00:00:00')
// Allow shift workers to access resources from Monday to Friday between 9 AM to 5 PM, except for July fourth.
levels.Require_Secure_Device &&
request.time.getDayOfWeek("America/Los_Angeles") >= 1 &&
request.time.getDayOfWeek("America/Los_Angeles") <= 5 &&
!(
request.time.getMonth("America/Los_Angeles") == 6 &&
request.time.getDayOfMonth("America/Los_Angeles") == 3
) &&
request.time.timeOfDay("America/Los_Angeles").between('09:30:00', '17:00:00')
Enterprises sometimes want to allow break glass access during emergencies when the administrator does not have access to a secure device but needs emergency access for a short period of time.
In this case, create a time and location-constrained access level using the levels attribute, and assign it to the specific administrator. When this access level is assigned, it would only be valid during the time specified. After this time period expires, the administrator access would again be controlled by existing requirements.
// Allow temporary access to resources on March 1, 2022, between 10 PM to midnight,
// and this access must come from within the US region.
levels.Require_Secure_Device &&
request.time.between('2022-03-01T23:00:00+08:00', '2022-03-02T23:59:59+08:00') &&
origin.region_code == “US”
// Note that the end time is exclusive, so the above potentially has 2 seconds that
// the users may not have access. Another option is to use this
// !between(‘00:00:01’,’16:00:00’)
Combine conditions from two levels example
Define a new access level by combining conditions from two access levelsThis access level uses levels attributes, and requires that users meet the combined conditions of two access levels. In this example, access_level_name_1 and access_level_name_2 refer to Internal Name.
levels.access_level_name_1 && levels.access_level_name_2