The Device Trust Gateway is a secure bridge application designed for organizations (specifically Google Workspace and Cloud Identity customers) to enforce strict "Approved Devices Only" access policies via Context-Aware Access (CAA), while providing a seamless, low-friction self-service workflow for end-users to vet and approve their personal BYOD devices.
- ๐ Master Enterprise Deployment Guide
- Architecture & Zero-Trust Overview
- Google Workspace Settings & Extension Guide
- Prerequisites & Billing Check
- โก Automated Interactive Deployer (Recommended)
- ๐ Endpoint Verification & BYOD Approval Lifecycle
- Chromebook Fleet Seeding Tool
- Manual Setup: Local Development
- Manual Setup: Docker (On-Premise)
- Manual Setup: Google Cloud (GCP Cloud Run)
- Configuration & Admin UI
- Firewall, Network Allowlist & Anti-Spoofing
- ๐ Identity-Aware Proxy (IAP) Edge Gating
- ๐ ๏ธ Troubleshooting & AI Diagnostics with Gemini
The Gateway leverages Google Workspace Context-Aware Access (CAA) to establish a zero-trust access perimeter.
For complete documentation detailing supported Workspace editions, end-user flows, Console settings, force-installing extensions, CAA rules, and deployment options:
๐ docs/master_enterprise_deployment_guide.md โ Master Enterprise Guide: Comprehensive blueprint covering portal concepts, Workspace licensing, end-user flows, complete Admin Console checklist, and deployment walkthroughs.
๐ docs/workspace_setup_and_extension_guide.md โ Step-by-step Google Workspace Console settings, Extension Force-Install ID, Mobile vs. Desktop approval behavior, and Mass Baseline Revocation.
๐ docs/troubleshooting_guide.md โ Troubleshooting & AI Diagnostics Guide: Real-world root-cause playbooks (chrome://policy diagnostics, Windows Git Bash path handling, DWD/Cloud Identity debugging) and copy-paste prompts for troubleshooting with Gemini.
๐ docs/caa_architecture_overview.md โ Enterprise zero-trust architecture whitepaper.
- Dual Enforcement Modes โ Disabled by Default on New Installs: Supports Session Management & Circuit Breaker for Google Workspace for Education Fundamentals (
session_watch_enabled), Context-Aware Access (CAA) Integration for Education Standard/Plus (caa_enforcement_enabled), or BOTH simultaneously. On any new installation (./deploy.sh), both modes start disabled by default (enforcement_mode: "DISABLED") in safe standby mode until an administrator explicitly configures and enables them in#/admin. - Sub-10-Second Unapproved Device Termination (3-Layer Pipeline):
- Layer 1 (
< 0.5sInline Portal Check &8sHeartbeat): Opening the portal on an unapproved orBLOCKEDdevice immediately triggersusers.signOut+ OAuth grant revocation and returns401 SESSION_REVOKED_UNAPPROVED_DEVICE. Backend JWT authentication compares the token'siatclaim against the user's last sign-out timestamp to immediately reject pre-revocation tokens. - Layer 2 (
~2โ10sCloud IdentitylastSyncTimeSub-Polling): A 1-minute Cloud Scheduler job (session-watch-login-sweep) executes 5 rapid sub-polls spaced 10 seconds apart (t=0s, 10s, 20s, 30s, 40s), inspecting Cloud IdentitydeviceUsersfor bothPENDING_APPROVALand re-logged-inBLOCKEDBYOD devices whoselastSyncTimeupdated after the user's last sign-out. - Layer 3 (Admin SDK
loginAudit Sweep + OAuth Token Revocation): Sweepsadmin.reports_v1.activities.list(applicationName='login')and revokes both Google session cookies (users.signOut) and OAuth token grants (directory.tokens.delete).
- Layer 1 (
- Unified User & Admin Experience: All usersโincluding Super Administratorsโsee the exact same clean device approval view on
#/, with Company-Owned Devices strictly filtered to hardware the signed-in user has personally accessed (recentUsers). Admin-only operational controls (Sync Inventory Cache,Attest Current Session,Run Live Login Sweep) and enforcement telemetry reside exclusively on#/admin. - Unmanaged BYOD Hardware: Personal devices do not require intrusive Mobile Device Management (MDM) enrollment or profiles. Users sign into their managed Chrome profile with the Endpoint Verification extension, registering the device as "Unmanaged" while allowing the backend to approve (
devices.deviceUsers.approve) or block (devices.deviceUsers.block) access. - Automated Lifecycle Management: A secure cron endpoint (
/api/cron/cleanup) automatically revokes access for inactive BYOD devices older than X days and syncs newly enrolled Chromebooks.
- Google Cloud Project with an Active Billing Account linked. (Google Cloud Run, Cloud Build, Cloud Scheduler, and Secret Manager require billing to be enabled before APIs can be activated).
- Google Workspace / Cloud Identity tenant (supports Education Fundamentals, Education Standard / Plus, and Enterprise editions).
- Google Endpoint Verification Chrome Extension force-installed across target Organizational Units (OUs) to collect device signals and answer Context-Aware Access challenges (Extension ID:
callobklhcbilhphinckomhgkigmfocg). - Service Account Credentials with Domain-Wide Delegation (DWD) authorized in Google Workspace Admin Console (
https://admin.google.com/ac/owl/domainwidedelegation) for the following 6 required OAuth scopes:https://www.googleapis.com/auth/cloud-identity.deviceshttps://www.googleapis.com/auth/admin.directory.user.readonlyhttps://www.googleapis.com/auth/admin.directory.group.member.readonlyhttps://www.googleapis.com/auth/admin.directory.device.chromeos.readonlyhttps://www.googleapis.com/auth/admin.reports.audit.readonly(Required for Session Management login audit sweeps)https://www.googleapis.com/auth/admin.directory.user.security(Required forusers.signOut& OAuth token revocation circuit breaker)
- Node.js (v20+) and Python (3.11+) installed for local development. (Note: Node.js is only required if building the React frontend locally outside of Docker. The automated
./deploy.shscript and Docker builds manage Node.js 20 and Python 3.11 automatically inside container build stages).
Important
Pre-Deployment Billing Verification & Diagnostic Reporting: The automated ./deploy.sh script actively inspects your GCP project's billing status before creating cloud resources.
- Actionable CLI Diagnostics: If billing verification encounters an issue, the CLI prints the exact underlying
gclouderror message (such as missingroles/billing.viewerIAM permissions or disabledcloudbilling.googleapis.comAPI) alongside direct resolution links. - Verbose Mode (
--verbose/-v): Run./deploy.sh --verboseto stream live Cloud Build logs, Cloud Run deploy events, and comprehensive command debug traces. - Bypass Option (
--skip-billing-check): If billing is managed centrally by an organization administrator and your deployment account lacksroles/billing.viewer, pass--skip-billing-checkor confirm the on-screen prompt to proceed.
Because devicetrustportal evaluates domain login and Cloud Identity sync events in batched sweeps rather than per-student background processes, a 1,000-student district and a 40,000-student district have nearly identical GCP running costs. All Google Workspace Admin SDK and Cloud Identity API calls are 100% free (included with Google Workspace for Education):
| Deployment & Enforcement Mode | Detection Speed | Est. Monthly Cost (1,000 โ 40,000 Students) | Why |
|---|---|---|---|
1. On-Premise Docker (./deploy.sh --target 2) |
~2 โ 10s | $0.00 / mo | Runs on any existing district VM (~60 MB RAM). |
2. Cloud Run โ CAA-Only Mode (Education Standard / Plus, session_watch_enabled: false) |
Immediate (Edge 403) | $0.00 โ $0.20 / mo | Scales to zero when idle; < 3% of GCP's 180k vCPU-s monthly Free Tier. |
3. Cloud Run โ Free-Tier 1-Minute Session Sweep (Education Fundamentals, --sweep-cadence 1min) |
~30 โ 60s | $0.00 โ $0.20 / mo | 1 sweep/min (~110k vCPU-s/mo) fits 100% inside GCP's 180k vCPU-s Free Tier. |
4. Cloud Run โ 24/7 Sub-10s Rapid Polling (Education Fundamentals / BOTH, default --sweep-cadence sub10s) |
~2 โ 10s | ~$38.00 โ $43.00 / mo | 5ร 10s sub-polls/min (~43s/min active window โ 1.88M vCPU-s/mo at 1 vCPU, 512 MiB). |
(See ARCHITECTURE_AND_SCALE.md for the full GCP service-by-service line-item breakdown).
This section is designed for administrators or users with zero development experience. Follow these 4 simple steps to download the code and deploy the gateway in under 10 minutes!
You only need two free tools installed on your computer to run the automated installer:
-
Git (Tool to download the repository and provide the bash terminal):
- Windows: Download and run the 64-bit installer from git-scm.com/download/win. Keep all default settings (this installs Git Bash and adds Windows Explorer integration).
- Mac: Open Terminal and type
xcode-select --install(click Install when prompted). - Linux (Ubuntu/Debian): Run
sudo apt update && sudo apt install -y git.
-
Google Cloud SDK (
gcloudCLI) (Tool to connect to your Google Cloud Project):- Windows: Download and run the Windows installer from cloud.google.com/sdk/docs/install. Check the box to "Run
gcloud init" and ensuregcloudis added to your environmentPATH. - macOS / Linux: Run
curl https://sdk.cloud.google.com | bashin your terminal, or download the installer from cloud.google.com/sdk/docs/install.
- Windows: Download and run the Windows installer from cloud.google.com/sdk/docs/install. Check the box to "Run
Important
Windows Users: Always use Git Bash (or WSL) to run the deployment script. Do NOT use standard Windows Command Prompt (cmd.exe) or Windows PowerShell, as ./deploy.sh requires a Bash shell environment.
-
Open your Terminal:
- Windows: Press the Windows Key, type
Git Bash, and press Enter (or right-click anywhere on your Desktop/Downloads folder and choose "Open Git Bash here"). - Mac: Open Terminal (Applications > Utilities > Terminal).
- Linux: Open your preferred shell terminal.
- Windows: Press the Windows Key, type
-
Log into Google Cloud:
gcloud auth login
(Your web browser will open automatically. Sign into the Google Workspace / Google Cloud account with administrator access to your target GCP Project).
-
Download (or Update) the Code Repository:
# Fresh install: Clone the code repository from GitHub git clone https://github.com/googleworkspace/devicetrustportal.git cd devicetrustportal # Updating an existing checkout before redeploying: git fetch origin && git reset --hard origin/main
Run the interactive deployment wizard script inside your terminal (Git Bash on Windows / Terminal on macOS & Linux):
# Optional for macOS / Linux: Ensure the script is executable
chmod +x deploy.sh
# Run the deployment wizard (Standard Interactive Mode)
./deploy.shTip
Windows Git Bash (MINGW64) Notes:
./deploy.shautomatically checks if your local branch is behindorigin/mainand fast-forwards to the latest commit before deploying../deploy.shautomatically configuresMSYS2_ARG_CONV_EXCL="--set-secrets;--set-env-vars;--update-env-vars;GOOGLE_APPLICATION_CREDENTIALS"so container paths like/secrets/dwd_key.jsonare not converted into WindowsC:/Program Files/Git/secrets/dwd_key.jsonpaths.- Do NOT set
MSYS_NO_PATHCONV=1orMSYS2_ARG_CONV_EXCL="*"globally when running manualgcloudcommands in Git Bash on Windows, asgcloudrelies on MSYS path conversion to locate its internalgcloud.pyscript. If running manualgcloud run services updatecommands on Windows Git Bash, useMSYS2_ARG_CONV_EXCL="--update-env-vars;--set-env-vars;--set-secrets".
You can pass command-line flags to customize execution or troubleshoot deployment:
# Run with verbose logging for real-time container build streaming and detailed diagnostics
./deploy.sh --verbose # or -v
# Bypass GCP billing account verification (if billing is managed centrally by an org admin)
./deploy.sh --skip-billing-check
# Pre-specify Project ID, Region, and Deployment Target
./deploy.sh --project my-gcp-project-id --region us-central1 --target 1
# View all available CLI options
./deploy.sh --help| Flag | Env Variable | Description |
|---|---|---|
-v, --verbose |
VERBOSE=true |
Streams real-time container build logs, Cloud Run deploy events, and debug command output. |
--skip-billing-check |
SKIP_BILLING_CHECK=true |
Bypasses the GCP billing verification check if you lack roles/billing.viewer. |
--project <PROJECT_ID> |
GCP_PROJECT=<PROJECT_ID> |
Sets the Google Cloud Project ID directly from the CLI. |
--region <REGION> |
GCP_REGION=<REGION> |
Sets the target GCP region (default: us-central1). |
--target <1|2> |
DEPLOY_TARGET=<1|2> |
Pre-selects deployment target (1: Google Cloud Run, 2: On-Premise Docker). |
--mode <MODE> |
ENFORCEMENT_MODE=<MODE> |
Sets initial enforcement mode (DISABLED [default for new installs], SESSION_WATCH, CAA, or BOTH). |
--sweep-cadence <sub10s|1min> |
SWEEP_CADENCE=<sub10s|1min> |
Selects Session Watch polling cadence (sub10s [default, ~$38โ$43/mo] or 1min [$0/mo GCP Free Tier]). |
-h, --help |
โ | Displays the help and options menu. |
The deployment wizard will guide you through the setup automatically. Here is what to enter when prompted:
-
Select Deployment Target:
- Type
1for Google Cloud (GCP Cloud Run + Secret Manager) and press Enter.
- Type
-
Enter Google Cloud Project ID:
- Enter your GCP Project ID (e.g.,
my-company-device-trust) and press Enter. - Press Enter to accept the default region (
us-central1).
- Enter your GCP Project ID (e.g.,
-
Domain-Wide Delegation (DWD) Authorization (Google Workspace Admin Console):
- The script creates a dedicated Service Account and displays a Numeric Client ID (e.g.,
1083920194817263). - Open your browser to admin.google.com > Security > Domain-wide Delegation.
- Click Add new, paste the Numeric Client ID, and copy-paste the scope string printed in your terminal into the OAuth Scopes field. Click Authorize.
- Return to your terminal, press ENTER, and enter your Workspace Administrator email address (e.g.,
admin@yourdomain.com).
- The script creates a dedicated Service Account and displays a Numeric Client ID (e.g.,
-
OAuth Google Sign-In Authorization:
- The script builds Phase 1 and prints your live Cloud Run HTTPS URL (e.g.,
https://device-trust-gateway-xyz-uc.a.run.app). - Open Google Cloud Credentials Console.
- Click Create Credentials > OAuth client ID > Web application.
- Under Authorized JavaScript origins and Authorized redirect URIs, paste your live Cloud Run URL.
- Click Create, copy your Client ID, and paste it into the terminal prompt.
- The script builds Phase 1 and prints your live Cloud Run HTTPS URL (e.g.,
-
Configure Workspace App Access Control (Crucial for Student Access):
- In Google Workspace, student or restricted organizational units (OUs) may block third-party / custom OAuth apps by default with an error like "Access blocked: Your institution's admin needs to review this app".
- Open Google Workspace Admin Console > Security > Access and data control > API controls > App access control.
- Click Manage Third-Party App Access (or Connected apps), then click Add app > OAuth app name or Client ID.
- Paste your OAuth 2.0 Client ID generated in Step 4 and search for it.
- Select your application, select your target OUs (e.g.,
/Studentsor your top-level domain), and set access to Trusted (allows access to Google services) or Limited. Click Save.
-
Access Control & IAP Edge Defense:
- Recommended for Schools & Hybrid Work (Default: N): Press N (or Enter) to skip IAP Edge Defense. The portal runs in Standard Mode over public HTTPS, secured by Google Sign-In and Trust Chaining (6-digit pairing codes). This ensures students and staff at home can approve personal devices to do homework using their school Chromebook.
- Strict Corporate Mode (Option Y): Places Cloud Run behind Google Cloud IAP and an HTTPS Load Balancer, restricting portal access to campus IP subnets or company hardware. Only use this if your organization strictly requires device approvals to happen on-premises.
-
Configure Google Workspace Device Telemetry, Profile Reporting & Endpoint Verification:
[!IMPORTANT] No CBCM Machine Enrollment Required for Personal BYOD Laptops: Personal Windows and macOS laptops do not require Chrome Browser Cloud Management (CBCM) machine-level token enrollment (
CloudReportingEnabledis ignored on unenrolled BYOD computers). Instead, personal laptops register and report telemetry inPENDING_APPROVALstatus via signed-in Managed Chrome Profile settings (Profile reporting + Chrome signals sharing) combined with Universal Device approvals.- Part A: Enable ChromeOS Device Reporting (For Company-Owned Chromebooks):
- Open admin.google.com > Devices > Chrome > Settings > Device settings.
- Scroll to User and device reporting and turn ON:
- Report device OS information
- Report device hardware information
- Report device telemetry
- Report device user tracking
- Part B: Enable Managed Chrome Profile Reporting & Signals Sharing (Mandatory for Windows/Mac BYOD):
- Open admin.google.com > Devices > Chrome > Settings > Users & browsers.
- Select your target OU (or root domain) and configure the following five user/browser policies:
- Profile reporting (
CloudProfileReportingEnabled) โ Set to Enable profile reporting. - Chrome signals sharing (
UserSecuritySignalsReporting&UserSecurityAuthenticatedReporting) โ Set to Enable signals sharing. - Enterprise Hardware Platform API (
EnterpriseHardwarePlatformAPIEnabled) โ Set to Allow extensions to see hardware platform information. - Browser sign-in โ Set to Force users to sign in to use the browser.
- Managed accounts sign-in restriction (
ManagedAccountsSigninRestriction) โ Set to Block users from signing into secondary accounts (primary_account_strict).
- Profile reporting (
- (Note on
chrome://policyPrecedence Warnings: Do not worry if machine-scoped precedence policies likeCloudPolicyOverridesPlatformPolicyorCloudUserPolicyOverridesCloudMachinePolicyshow an "Ignored because the policy is not set at the machine scope" notice on unenrolled BYOD laptops. You can leave Policy Precedence at default;Cloud userprofile policies apply automatically).
- Part C: Enable Device Signals Globally (Universal Data Access):
- Open admin.google.com > Devices > Mobile & endpoints > Settings > Universal > Data access (labeled Universal or Universal settings in the left menu).
- Expand Device signals (or Endpoint verification) and check both:
- Collect device signals from Chrome browser
- Collect device signals using endpoint verification (or Monitor which devices access organization data)
- Part D: Enable Device Approvals (Universal Security Settings):
- Open admin.google.com > Devices > Mobile & endpoints > Settings > Universal > Security.
- Expand Device approvals, select Require admin approval, and enter an admin notification email address.
- Verify that all target sub-OUs (e.g.
/Students,/Staff,/Admin) inherit or explicitly enable Require admin approval.
- Part E: Force-Install Endpoint Verification Extension (Managed Chrome Profiles):
- Open admin.google.com > Devices > Chrome > Apps & extensions > Users & browsers.
- In the left Organizational Unit tree, select your target OU (e.g.
gwfe.org,/Students, or/Staff). - Click Add (+) > Add Chrome app or extension by ID, and enter Extension ID:
callobklhcbilhphinckomhgkigmfocg - In the right-hand options panel:
- Under Installation policy, select Force install + pin to browser toolbar.
- Under Certificate management, turn ON both Allow access to keys (
KeyPermissions) and Allow enterprise challenge (AttestationExtensionAllowlist). - (Platform Note: In Chromium's policy engine,
KeyPermissionsandAttestationExtensionAllowlistare ChromeOS-only policies (supported_on: ["chrome_os"]) for Verified Access hardware TPM attestation. They will not appear inchrome://policyon Windows or macOS laptopsโthis is normal. Windows and macOS BYOD devices register via the Profile Reporting and Chrome Signals Sharing policies configured in Part B).
- Click Save.
- Part F: Testing on Personal BYOD Laptops:
- On a personal Windows or Mac laptop, open Chrome and sign into the Chrome profile using your managed Google Workspace account (
user@yourdomain.com). - Verify the Endpoint Verification extension (
callobklhcbilhphinckomhgkigmfocg) is installed and click Sync now (or verifyCloudProfileReportingEnabledandUserSecuritySignalsReportingaretrueatchrome://policy). - The device will immediately register in Cloud Identity in Pending approval (
PENDING_APPROVAL) state and appear in the Device Trust Gateway Portal ready for approval.
- On a personal Windows or Mac laptop, open Chrome and sign into the Chrome profile using your managed Google Workspace account (
- Part A: Enable ChromeOS Device Reporting (For Company-Owned Chromebooks):
-
Activate Workspace Policy (Context-Aware Access โ Education Standard/Plus & Enterprise):
- Open Google Workspace Admin Console > Security > Access and data control > Context-Aware Access.
- Click Create Access Level, switch to Advanced mode, and create an Access Level named
Approved Devices Onlywith CEL expression:device.is_corp_owned_device == true || device.is_admin_approved_device == true[!NOTE] Company-Owned vs. Admin-Approved Explained:
device.is_corp_owned_device == true: Matches official enterprise hardware trust anchors (e.g., district Chromebooks enrolled via Directory API or Macs/PCs imported into Company-Owned Inventory). These devices access Workspace apps directly without self-service approval.device.is_admin_approved_device == true: Matches personal BYOD hardware (Macs, Windows laptops, phones) where the user binding has been explicitly approved via the Device Trust Portal (managementState: APPROVED). Personal devices start blocked and regain access only after approval.
- Click Assign to apps:
โ ๏ธ Important (Target Organizational Unit Selection): In the left Organizational Unit tree, do NOT leave this policy assigned to the Root Organizational Unit (/). The Admin Console defaults to the Root OU, which will immediately apply the policy domain-wide to all users (including Super Admins and faculty) and can cause catastrophic lockouts. Instead, explicitly select your target OU (e.g.,StudentsOU or a dedicatedTest / Pilot OU).- App Assignment: Assign this level to the Workspace Apps of your choice (eg. Gmail, Driveโฆ).
- Enforcement Policy: Set policies to Block when policies / access levels are not met.
- Desktop & Mobile Apps: Ensure policy is set to Enable for Apply to Google desktop and mobile apps (to enforce policy across native clients like Gmail mobile and Google Drive for Desktop in addition to web browsers).
-
Enable Enforcement in the Admin Portal (
#/adminโ Disabled by Default on New Installs):- For safety, every fresh installation starts with both Session Management (
session_watch_enabled: false) and Context-Aware Access Integration (caa_enforcement_enabled: false) disabled by default (โ๏ธ ENFORCEMENT STANDBY โ CONFIGURE IN ADMIN). - Open your live portal URL and click โ๏ธ Admin Config (
#/admin). - Toggle on Session Management (Education Fundamentals), Context-Aware Access Integration (Education Standard & Plus), or Both, configure your target Organizational Units / Groups if desired, and click ๐พ Save Configurations.
- Click ๐ Sync Inventory Cache in the Admin Telemetry card to pre-warm your approved device inventory.
- For safety, every fresh installation starts with both Session Management (
๐ Done! Your portal is now fully live and securing your enterprise workspace!
Tip
๐ก Misplaced your live Portal URL? If you need to retrieve your unique portal URL later for testing or bookmarking:
- In Google Cloud Console: Go to Cloud Run > click
device-trust-gateway. The live HTTPS service URL is displayed directly at the top of the service page. - Via Terminal (CLI): Run
gcloud run services describe device-trust-gateway --region us-central1 --format='value(status.url)' - Admin Configuration UI: Append
/#/adminto your portal URL (e.g.https://device-trust-gateway-xyz-uc.a.run.app/#/admin).
We have included a robust interactive deployment script (deploy.sh) that streamlines setup across all target environments.
To launch the deployer from your terminal, run:
./deploy.shYou can pass command-line flags or environment variables to customize the deployment workflow or diagnose issues:
# Enable verbose logging and live Cloud Build streaming
./deploy.sh --verbose # or -v
# Bypass GCP billing account verification (useful if billing is managed centrally)
./deploy.sh --skip-billing-check
# Provide Project ID and Region directly
./deploy.sh --project my-gcp-project-id --region us-central1 --target 1
# View full CLI help
./deploy.sh --help| Flag | Env Variable | Description |
|---|---|---|
-v, --verbose |
VERBOSE=true |
Enables verbose logging, debug command output, and live Cloud Build streaming. |
--skip-billing-check |
SKIP_BILLING_CHECK=true |
Bypasses pre-flight billing verification if your account lacks billing viewer IAM rights. |
--project <ID> |
GCP_PROJECT=<ID> |
Pre-configures Google Cloud Project ID. |
--region <REGION> |
GCP_REGION=<REGION> |
Pre-configures Cloud Run / Scheduler target region (default: us-central1). |
--target <1|2> |
DEPLOY_TARGET=<1|2> |
Pre-selects deployment target (1: Google Cloud Run, 2: On-Premise Docker). |
--mode <MODE> |
ENFORCEMENT_MODE=<MODE> |
Sets initial enforcement mode (DISABLED [default for new installs], SESSION_WATCH, CAA, or BOTH). |
--sweep-cadence <sub10s|1min> |
SWEEP_CADENCE=<sub10s|1min> |
Selects Session Watch polling cadence (sub10s [default, ~$38โ$43/mo] or 1min [$0/mo GCP Free Tier]). |
-h, --help |
โ | Displays the CLI help and options menu. |
You will be presented with a simplified interactive menu:
Please select your desired deployment target:
1) Google Cloud (GCP Cloud Run + Secret Manager)
2) On-Premise (Docker Compose + Local .env)
3) Exit
When deploying to Google Cloud, the script seamlessly solves the OAuth origin "chicken-and-egg" problem:
- Phase 1 (Baseline Service): Executes an initial container build and Cloud Run deployment to establish your unique live HTTPS service URL (
https://device-trust-gateway-HASH-uc.a.run.app). - Phase 2 (Interactive Setup): Displays explicit instructions prompting you to authorize this newly generated live URL as an Authorized JavaScript Origin in the Google Cloud Console, pausing to collect your resulting Client ID string.
- Phase 3 (Final Revision): Re-executes Cloud Build forwarding the authorized Client ID, permanently baking it into the compiled Webpack React static bundle and deploying the final revision.
When configuring live API execution or Chromebook fleet seeding, the script launches an interactive DWD Setup Wizard:
- Automatically verifies or creates a dedicated Google Cloud Service Account (
device-trust-gateway-sa). - Generates and downloads a private JSON key (
dwd_key.json). - Extracts your exact Service Account Client ID.
- Displays explicit instructions to authorize the Client ID and required scopes in the Google Workspace Admin Console (
https://admin.google.com/ac/owl/domainwidedelegation), pausing execution until you confirm authorization. - Prompts for your Super Administrator email and exports credentials for flawless impersonation.
To successfully deploy Context-Aware Access (CAA) policies that mandate device approval without enforcing intrusive Mobile Device Management (MDM) enrollment on employee personal hardware, organizations rely on the interplay between Google Endpoint Verification and the Device Trust Gateway.
+-----------------------------------------------------------------------------------+
| Personal BYOD Laptop / Phone |
| (Employee installs Endpoint Verification extension) |
+-----------------------------------------+-----------------------------------------+
|
| 1. Registers hardware in Cloud Identity
v
+-----------------------------------------------------------------------------------+
| Google Cloud Identity Catalog |
| |
| [ INITIAL STATE: managementState == PENDING_APPROVAL / UNMANAGED ] |
+-----------------------------------------+-----------------------------------------+
|
| 2. Employee attempts Workspace login
v
+-----------------------------------------------------------------------------------+
| Google Workspace Context-Aware Access (CAA) |
| |
| [ RULE: device.is_corp_owned_device == true || device.is_admin_approved_device == true ] |
| [ RESULT: Blocks unapproved BYOD laptop with 403 Access Denied screen ] |
+-----------------------------------------+-----------------------------------------+
|
| 3. Blocked employee visits Gateway
v
+-----------------------------------------------------------------------------------+
| Device Trust Gateway Approval Portal |
| |
| [ ACTION: Employee clicks โ Approve on their pending hardware row ] |
| [ BACKEND: Executes service.devices().deviceUsers().approve(...) ] |
+-----------------------------------------+-----------------------------------------+
|
| 4. Instantly updates Cloud Identity
v
+-----------------------------------------------------------------------------------+
| Google Cloud Identity Catalog |
| |
| [ UPDATED STATE: managementState == APPROVED ] |
| [ CAA RESULT: Evaluates is_admin_approved_device == true. Access Granted! ] |
+-----------------------------------------------------------------------------------+
- Endpoint Verification Enrollment: Administrators force-install the lightweight Google Endpoint Verification browser extension (
callobklhcbilhphinckomhgkigmfocg) via the Google Admin Console across target OUs (or users install it on personal Chrome profiles / Google Smart Lock on mobile). The extension collects hardware identifiers, OS version, and cryptographic certificates, registering the device in Cloud Identity as an unmanaged asset. By default, its device user binding initializes withmanagementStateset toPENDING_APPROVALorUNMANAGED. - CAA Guardrail Interception: The Workspace Administrator activates a Custom Access Level in the Workspace Admin Console (
https://admin.google.com/ac/security/contextaware) enforcing:When the employee attempts to open Gmail, Google evaluates their personal laptop. Because it is not company owned (device.is_corp_owned_device == true || device.is_admin_approved_device == trueis_corp_owned_device == false) and its Cloud Identity binding is still pending (is_admin_approved_device == false), CAA blocks them instantly at the edge with a403 Access Deniedscreen. - Gateway Self-Service Approval: The employee navigates to the Gateway portal (
https://device-trust-gateway-...), authenticating securely via Google Sign-In. Our backend executes a filtered query (service.devices().list(filter=f"email:{user_email}")) and surfaces their pending laptop. - Instant Policy Resolution: The employee clicks
[โ Approve]. The Gateway backend invokes Cloud Identity (service.devices().deviceUsers().approve(...)), immediately shifting the binding'smanagementStatetoAPPROVED. The employee reloads Gmail, CAA evaluatesdevice.is_admin_approved_deviceastrue, and enterprise access is instantly restored!
In Google Workspace Context-Aware Access, devices evaluating device.is_corp_owned_device == true must be registered in Company-Owned Inventory (distinct from personal BYOD devices that require device.is_admin_approved_device == true).
If you have already deployed the Gateway (or skipped seeding during the ./deploy.sh installer), you can move devices into Company-Owned Inventory at any time using the methods below:
To immediately crawl all active enterprise Chromebooks from the Directory API and anchor them in Cloud Identity as Company-Owned assets:
# Run from your local repository folder:
WORKSPACE_ADMIN_EMAIL=admin@yourdomain.com \
GOOGLE_APPLICATION_CREDENTIALS=dwd_key.json \
backend/venv/bin/python backend/scripts/seed_company_inventory.py- What it does: Automatically queries
admin.directory.device.chromeosand batch-registers all managed Chromebooks into Cloud Identity underownerType: COMPANY.
To continuously synchronize newly enrolled enterprise Chromebooks automatically on a daily schedule:
gcloud scheduler jobs create http seed-chromebook-inventory-daily \
--schedule="0 2 * * *" \
--uri="https://YOUR-GATEWAY-URL/api/cron/cleanup" \
--http-method=POST \
--headers="X-CloudScheduler=true" \
--location=us-central1For non-ChromeOS company assets (such as district-issued MacBooks, Windows desktops, or school iPads):
- Open Google Admin Console > Devices > Mobile & endpoints > Company-owned inventory.
- Click Import company-owned devices (the
+/ Import button at the top). - Select your device type (Company-owned computers for Mac/PC/Linux, or Company-owned mobile devices for iOS/Android).
- Download the CSV template and populate your hardware Serial Numbers and Asset Tags.
- Upload the CSV and click Import.
- How it works: When users sign in with the Endpoint Verification extension installed on these company Macs/PCs, Google automatically matches the hardware serial number to the Company-Owned inventory, tagging the device as
is_corp_owned_device == true!
If you prefer setting up the environment manually without the script:
Navigate to the root directory and install Python dependencies:
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn backend.main:app --host 127.0.0.1 --port 8080 --reloadInteractive API documentation will be available at http://127.0.0.1:8080/docs.
In a new terminal, start the React server:
cd frontend
npm install
npm startThe frontend UI will automatically open at http://localhost:3000.
- Create a local
.envfile at the root directory:
USE_SECRET_MANAGER=false
TENANT_CUSTOMER_ID=customers/my_customer
TENANT_INACTIVITY_THRESHOLD=90
TENANT_PORTAL_ADMINS=[]- Build and start the container:
docker-compose -f deploy/docker-compose.yml up --build -d- Enable required Google Cloud APIs:
gcloud services enable run.googleapis.com secretmanager.googleapis.com cloudidentity.googleapis.com cloudbuild.googleapis.com cloudscheduler.googleapis.com pubsub.googleapis.com firestore.googleapis.com admin.googleapis.com iap.googleapis.com compute.googleapis.com accesscontextmanager.googleapis.com- Create a Secret Manager secret to hold dynamic tenant configurations:
gcloud secrets create device_trust_gateway_config --replication-policy="automatic"- Build and deploy the container to Cloud Run:
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/device-trust-gateway deploy/
gcloud run deploy device-trust-gateway --image gcr.io/YOUR_PROJECT_ID/device-trust-gateway --platform managed --region us-central1 --set-env-vars="USE_SECRET_MANAGER=true,SECRET_NAME=device_trust_gateway_config"Once the application is running, Workspace Administrators can dynamically configure enforcement modes, rollout scope, and inspect real-time session telemetry directly via the Admin Portal (#/admin).
- Fresh Installations Start Disabled by Default: Every new installation via
./deploy.sh, Docker Compose, or a blank Secret Manager secret initializes with:session_watch_enabled: false(Session Management for Education Fundamentals)caa_enforcement_enabled: false(Context-Aware Access Integration for Education Standard & Plus)enforcement_mode: "DISABLED"
- Why Standby by Default? This ensures zero unexpected session revocations or user lockouts while the administrator completes initial Domain-Wide Delegation, Chrome Profile Reporting, and Chromebook inventory seeding. While disabled, administrators see a prominent
โ๏ธ ENFORCEMENT STANDBY โ CONFIGURE IN ADMINbadge in the top bar, and the 1-minute Cloud Scheduler sweep safely returnsSKIPPED_DISABLED. - Activating Enforcement in
#/admin:- Navigate to
#/admin(or click โ๏ธ Admin Config in the top navigation bar). - Check Session Management (Education Fundamentals) to enable the 3-layer
<0.5sinline check +~2โ10sCloud IdentitylastSyncTimesub-polling +users.signOut& OAuth grant revocation pipeline. - Check Context-Aware Access Integration (Education Standard & Plus) to enable CAA policy remediation banners and self-service pairing code workflows.
- (Optional) Enable Both simultaneously (
enforcement_mode: "BOTH") for defense-in-depth (CAA blocks Workspace web apps at the edge while Session Management immediately terminates underlyingaccounts.google.comsessions and OAuth tokens on unapproved devices). - Click ๐พ Save Configurations. Changes persist immediately to Google Cloud Secret Manager (
device_trust_gateway_config) or.env.
- Navigate to
- Unified Main Dashboard (
#/): All usersโincluding Super Administratorsโexperience the exact same clean device approval interface on#/.- Company-Owned Devices (
ownerType: COMPANY): Strictly filtered to hardware the signed-in user has personally accessed (email in recentUsers). Administrators are never cluttered with domain-wide Chromebooks they haven't logged into. - Personal BYOD Devices (
ownerType: USER): Displays the user's personal laptops and phones with self-service โ Approve, โ Revoke, ๐ Generate Pairing Code, and โฑ๏ธ + Add Personal Device (15m Grace Pass) actions.
- Company-Owned Devices (
- Admin-Only Operational Controls (
#/admin):- ๐ Sync Inventory Cache: Pre-warms and synchronizes approved ChromeOS serials and Cloud Identity
APPROVEDBYOD serials into the backend SQLite/RAM cache. - ๐ก๏ธ Attest Current Session: Manually records an attested browser heartbeat for the admin's current session.
- โก Run Live Login Sweep: Triggers an immediate on-demand audit sweep (
force=true) across Cloud IdentitydeviceUsers(PENDING_APPROVAL&BLOCKEDsyncs) and Admin SDK Reports APIloginevents, displaying evaluated counts, revocations, and the Recent Session Enforcement & Verification Events feed.
- ๐ Sync Inventory Cache: Pre-warms and synchronizes approved ChromeOS serials and Cloud Identity
| Setting / Capability | New Install Default (./deploy.sh) |
Active Live Test Environment (gwfe.org) |
|---|---|---|
session_watch_enabled (Fundamentals Session Management) |
false (Standby until enabled in #/admin) |
true (Enabled for live testing) |
caa_enforcement_enabled (Standard/Plus CAA Integration) |
false (Standby until enabled in #/admin) |
true (Enabled for live testing) |
enforcement_mode |
"DISABLED" |
"BOTH" |
Cloud Scheduler (session-watch-login-sweep) |
* * * * * (No-ops with SKIPPED_DISABLED until enabled) |
* * * * * (Active: 5x 10s sub-polls per minute) |
Inline Portal Session Check (GET /api/session-watch/session-status) |
Inactive until session_watch_enabled: true |
Active (< 0.5s on mount + 8s heartbeat + JWT iat validation) |
Admin Exemption (session_watch_exempt_admins) |
false (Admins can test enforcement with their own account) |
false (Verified live with claycodes@gwfe.org) |
You can run the complete backend and frontend test suites locally before deploying:
# 1. Run Backend Unit & Integration Tests (75 pytest tests covering 3-layer session guard,
# Cloud Identity PENDING_APPROVAL & re-logged-in BLOCKED sweeps, JWT iat invalidation,
# shared Wi-Fi NAT protection, OU/Group scoping, and strict recentUsers filtering):
PYTHONPATH=. backend/venv/bin/pytest backend/tests/ -q
# 2. Run Frontend Component & Heartbeat Tests (10 Vitest tests covering unified Dashboard,
# inline 401 session termination, 15m onboarding grace pass, and Admin Config):
npm --prefix frontend test
# 3. Verify Production Frontend Bundle Compilation:
npm --prefix frontend run buildIf you are deploying the Gateway on-premise (Docker Compose) inside an enterprise network, explicit firewall rules are required for both incoming user traffic and outgoing Google API communication, alongside strict reverse proxy anti-spoofing security measures.
For the complete, detailed specification covering exact ports, protocols, reverse proxy header stripping, and Uvicorn trust configurations, please refer to our dedicated enterprise guide: ๐ docs/network_requirements.md
- ๐ก๏ธ Upstream Proxy Stripping: Enterprise reverse proxies (Nginx, F5, Cloudflare) must actively strip forged
X-Forwarded-Forheaders arriving from external internet interfaces, overwriting them with authentic TCP socket client IPs. - ๐ Uvicorn Trust Gating (
--forwarded-allow-ips): Configure Uvicorn to only accept forwarded IP headers if they arrive directly from the known internal IP address of your reverse proxy host. - ๐ Session Binding: Network IP trust alone cannot grant device approval. Requesting clients must also present a valid, authenticated Google Workspace OIDC Bearer token session for the target user.
When deploying the Device Trust Gateway, administrators must decide how the portal itself is accessed:
- How it works: Cloud Run is hosted over public HTTPS and secured by Google Workspace OAuth 2.0 Sign-In and Trust Chaining (6-digit pairing codes).
- Why it's essential for Schools & Homework: Students at home working on a personal PC or Mac can open the portal on their school-issued Chromebook, generate a 6-digit pairing code, and approve their home computer in seconds. They are never locked out of doing evening homework or accessing Google Classroom/Drive.
- How it works: Cloud Run is placed behind an External HTTP(S) Load Balancer and Google Cloud Identity-Aware Proxy (IAP), restricting ingress strictly to corporate egress IP CIDRs or company-owned hardware.
โ ๏ธ Warning for Schools: If enabled, students attempting to access the portal from home internet will receive a403 Forbiddenerror. They will not be able to approve personal devices or complete assignments until they physically connect to the school network or VPN.
For full architectural blueprints, diagrams, and Access Context Manager setup guides: ๐ docs/caa_architecture_overview.md โ Comprehensive Zero-Trust & IAP Architecture Whitepaper ๐ docs/master_enterprise_deployment_guide.md โ Master Enterprise Deployment Guide
If personal BYOD devices are not appearing as Pending approval, if you see unexpected warnings in chrome://policy, or if gcloud encounters path issues on Windows Git Bash (MINGW64), see our dedicated guide:
๐ docs/troubleshooting_guide.md โ Full Troubleshooting & AI Diagnostics Guide
The portal automatically streams frontend browser events ([CLIENT_LOG]) directly into Cloud Run server logs alongside backend Cloud Identity API traces ([devices.py], [cloud_identity.py]). You can export a diagnostic bundle and ask Gemini to pinpoint the exact configuration fix:
- Export Cloud Run Server + Client Telemetry Logs:
gcloud logging read \ 'resource.type="cloud_run_revision" AND resource.labels.service_name="device-trust-gateway"' \ --project=YOUR_GCP_PROJECT_ID \ --limit=150 \ --format=json > cloud_run_logs.json
- Export Chrome Policies from the Test Device:
Open
chrome://policyon the test laptop, click Reload policies, and click Export to JSON (policies.json). - Ask Gemini:
Attach
cloud_run_logs.jsonandpolicies.jsonto Gemini (along with the prompt template in docs/troubleshooting_guide.md) to automatically verify Domain-Wide Delegation scopes,WORKSPACE_ADMIN_EMAILimpersonation, Cloud Identity device states, and Chrome Profile Reporting policies (CloudProfileReportingEnabled,UserSecuritySignalsReporting,UserSecurityAuthenticatedReporting).