# 27 Device-trust CAA via MDM

> v0.0.3 · role: Prevent · edition: Ent Std+ + MDM · [policy: #25 · #4, #7](https://docs.google.com/spreadsheets/d/1nOztaPd1Y7eNeRSR_hdovYy-ncpx-bAx/edit?usp=sharing&ouid=115159875779023172526&rtpof=true&sd=true)

Ties access to sensitive apps to the device it comes from, not just to the account. Endpoint verification collects posture signals — OS version, disk encryption, screen lock, admin-approval state, company-owned flag — into the Context-Aware Access attribute set, and an access level built from those attributes is applied through the three DEFAULT policies (all Google-owned apps, all SAML apps, all OAuth apps), which also cover every app enabled later, where a per-app assignment would leave each new app unprotected. Requiring admin approval for devices is what stops an attacker's own laptop enrolling itself into the trusted population. The signals depend on an agent: the Endpoint Verification helper or Chrome extension has to be deployed and the user signed into the managed Chrome profile, or no device reports anything at all.

Documentation: [Protect your business with Context-Aware Access](https://knowledge.workspace.google.com/admin/security/protect-your-business-with-context-aware-access) · [Deploy Context-Aware Access](https://knowledge.workspace.google.com/admin/security/deploy-context-aware-access)

## Caveats

- Block is the only action that is a control — Monitor is a dry run that always allows, and Warn lets the user through regardless, showing only an in-app warning notification, so a policy parked on Warn admits everyone while the log fills with reassuring rows. Switching a policy to Warn also SILENTLY REMOVES every app that does not support Warn from that policy on save, narrowing coverage without telling you. Read the log's Event column rather than the action you configured: 'Access Denied (Monitor mode)' means nothing was enforced.
- Rolling the default policies straight to Block is the classic CAA self-lockout — run Monitor first, read the log, then Block, and keep the break-glass admin (№20) OU exempt throughout. The OAuth default policy bites third-party sign-ins, which is where integrations break quietly, so the monitor log earns its keep there most.
- An access level nothing can satisfy locks everyone out the moment it goes Active — and zero device signals is the usual cause. A CloudManagementEnrollmentToken enrols the BROWSER into Chrome Enterprise Core and delivers no device signals by itself; 'Device state: No Device Signals' with 'Device ID: UNKNOWN' in the CAA log means the user is not signed into the managed Chrome profile with both device-signal toggles on, or the Endpoint Verification helper is not actually deployed on macOS/Windows.
- CAA does not apply to a session already established — combine it with session length (№12) and cloud session control (№38), or an attacker with a stolen cookie keeps access from an untrusted device.
- Requires Enterprise Standard+, Education Standard+, Frontline Standard+, Enterprise Essentials Plus or Cloud Identity Premium AND an MDM/device-management posture — the licence alone is not enough, and standing up device management is the bulk of the work. Personal/BYOD devices will fail a company-owned condition, so decide the BYOD story before enforcing, not during the incident it causes.

## Setup steps

1. Turn on Endpoint verification so devices report posture signals (OS version, disk encryption, screen lock, admin-approval state) into the Context-Aware Access (CAA) attribute set. — `Devices › Mobile & endpoints › Settings › Universal › Data access`

   - **Collect device signals using endpoint verification** = ON
   - **Collect device signals from Chrome browser** = ON (for the target OU)

   docs: [Turn endpoint verification on or off](https://knowledge.workspace.google.com/admin/devices/turn-endpoint-verification-on-or-off) · [Turn Chrome signals sharing on or off](https://knowledge.workspace.google.com/admin/devices/turn-chrome-signals-sharing-on-or-off)

2. Require admin approval for devices so an attacker's own laptop cannot enrol itself into the trusted population. — `Devices › Mobile & endpoints › Settings › Universal › Security`

   Device approvals = Require admin approval. Applies to user-owned/personal devices; company-owned devices registered by serial number are auto-approved (except Android work-profile devices)

   docs: [Require admin approval for device access](https://knowledge.workspace.google.com/admin/devices/require-admin-approval-for-device-access)

3. Create an access level whose conditions are device attributes, not just network attributes. — `Security › Access and data control › Context-Aware Access › Access levels`

   - **Access level 'trusted-device': Device policy** = admin-approved AND encrypted storage AND screen lock AND OS version ≥ baseline
   - **company-owned** = true

   docs: [Create Context-Aware access levels](https://knowledge.workspace.google.com/admin/security/create-context-aware-access-levels)

4. Add an access level that only admits a MANAGED Chrome browser at or above a minimum version, written as a CEL expression in the Advanced tab — the Basic editor cannot express either condition. Both attributes come from the Chrome browser signal collection turned on in the first step, so an unmanaged or signed-out browser fails the managed-state check instead of slipping through with no signals. The version floor is a maintenance commitment, not a set-once value: raise it as Chrome releases ship. — `Security › Access and data control › Context-Aware Access › Access levels`

   ```
   device.chrome.management_state == ChromeManagementState.CHROME_MANAGEMENT_STATE_BROWSER_MANAGED && device.chrome.versionAtLeast("148.0.0.0")
   ```

   docs: [Use case: Managed Chrome browser enforcement](https://knowledge.workspace.google.com/admin/security/use-case-managed-chrome-browser-enforcement)

5. Apply the level through the three DEFAULT policies (Google-owned apps, SAML apps, OAuth apps) rather than app-by-app: a default policy also covers every app enabled later, where a per-app assignment leaves each new app unprotected until someone remembers it. Start in monitor mode; per-app assignment remains the exception path for apps needing a stricter level. — `Security › Context-Aware Access › General settings`

   General settings: Policy for all Google-owned apps / all SAML apps / OAuth apps = trusted-device; Action = Monitor first, then Block once the monitor log is clean. Do not use Warn (OAuth policies offer only Monitor and Block)

   docs: [Assign Context-Aware Access levels to apps](https://knowledge.workspace.google.com/admin/security/assign-context-aware-access-levels-to-apps) · [Apply a default Context-Aware Access policy for all SAML apps](https://knowledge.workspace.google.com/admin/security/apply-caa-policy-for-all-saml-apps)

## Ongoing maintenance

- **[automatable: script]** On every Chrome major release: raise the versionAtLeast() floor in the CEL access level.
- **[requires a human]** Weekly: work the device-approval queue — pending approvals block real users.

## How to verify

1. From an unmanaged browser, sign in as a test user — the CAA log should show the device failing the level (Blocked, or Access Denied (Monitor mode) while ramping).

2. From a managed device, confirm the log shows device signals present (no "No Device Signals" / "Device ID: UNKNOWN").

## Settings screens

- Devices > Mobile & endpoints > Settings > Universal > Data access (device signals / Endpoint verification)
  - console: https://admin.google.com/ac/managedsettings/724141353720/UniversalAdditionalSettingsTab?vid=EMM_UNIVERSAL_SETTINGS_VIEW
  - screenshot: ../screenshots/admin.google.com/ac/managedsettings/724141353720/UniversalAdditionalSettingsTab__vid-EMM_UNIVERSAL_SETTINGS_VIEW.png
- Security > Access and data control > Context-Aware Access > Access levels
  - console: https://admin.google.com/ac/security/context-aware/access-levels
  - screenshot: ../screenshots/admin.google.com/ac/security/context-aware/access-levels.png
- Security > Access and data control > Context-Aware Access > Assign access levels to apps
  - console: https://admin.google.com/ac/security/context-aware
  - screenshot: ../screenshots/admin.google.com/ac/security/context-aware.png
- Security > Context-Aware Access > General settings (default policies for Google-owned, SAML and OAuth apps)
  - console: https://admin.google.com/ac/security/context-aware/settings
  - screenshot: ../screenshots/admin.google.com/ac/security/context-aware/settings.png
