diff --git a/.github/mdl.config.json b/.github/mdl.config.json index 001dc72c..bb9ced36 100644 --- a/.github/mdl.config.json +++ b/.github/mdl.config.json @@ -71,6 +71,12 @@ }, { "pattern": "^https://datatracker.ietf.org" + }, + { + "pattern": "^https://container.googleapis.com/*" + }, + { + "pattern": "^https://console.cloud.google.com/marketplace/product/google/verifiedaccess.googleapis.com" } ], "replacementPatterns": [ diff --git a/manifest.json b/manifest.json index 394c2c8c..b3582087 100644 --- a/manifest.json +++ b/manifest.json @@ -93,6 +93,10 @@ "title": "Configure Browser Certificates", "path": "/tutorials/browser-certificate-setup-guide.mdx" }, + { + "title": "Configure ChromeOS Device Identity Certificates", + "path": "/tutorials/chromeos-device-identity-certificates.mdx" + }, { "title": "Configure Enterprise Relay", "path": "/tutorials/configure-enterprise-relay.mdx" diff --git a/platform/troubleshooting-agent.mdx b/platform/troubleshooting-agent.mdx index 0df22bbc..da9f6202 100644 --- a/platform/troubleshooting-agent.mdx +++ b/platform/troubleshooting-agent.mdx @@ -616,7 +616,7 @@ This may indicate the device needs to be registered and approved. See [Registeri | Check extension version | Click the Smallstep extension icon in Chrome toolbar (version shown at bottom) | | Verify device enrollment | Device must be enrolled in Google Workspace for enterprise/education | | Check policies | Navigate to `chrome://policy` and look for `Smallstep Agent for ChromeOS` | -| Verify certificates | Navigate to `chrome://certificate-manager` | +| Verify certificates | Navigate to `chrome://certificate-manager` — see [Configure ChromeOS Device Identity Certificates](../tutorials/chromeos-device-identity-certificates.mdx) if the device only has an attestation certificate rather than a usable device identity certificate | **ChromeOS Requirements:** - Device enrolled in a Google Workspace domain @@ -628,4 +628,6 @@ This may indicate the device needs to be registered and approved. See [Registeri - `ExtensionInstallForceList` containing the ChromeOS extension ID - `AttestationExtensionAllowList` containing the ChromeOS extension ID +For initial setup of these requirements and policies, see [Connect Google Workspace to Smallstep](../tutorials/connect-google-workspace-to-smallstep.mdx). + The extension retries certificate issuance every ~30 seconds. If enrollment continues to fail, contact Smallstep support. diff --git a/tutorials/chromeos-device-identity-certificates.mdx b/tutorials/chromeos-device-identity-certificates.mdx new file mode 100644 index 00000000..df038efa --- /dev/null +++ b/tutorials/chromeos-device-identity-certificates.mdx @@ -0,0 +1,93 @@ +--- +updated_at: July 31, 2026 +title: Configure ChromeOS Device Identity Certificates +html_title: Configure ChromeOS Device Identity Certificates for mTLS | Smallstep +description: Issue mTLS-capable device identity certificates to ChromeOS devices enrolled in Google Workspace, for use in Wi-Fi, VPN, or internal application authentication. +--- + +Smallstep issues a **device identity certificate** to ChromeOS devices enrolled through [Google Workspace](./connect-google-workspace-to-smallstep.mdx) — the certificate you'll use for mTLS: Wi-Fi (802.1X), VPN, or authenticating to internal applications. + +This guide covers issuing that device identity certificate. It's a prerequisite for [ChromeOS Wi-Fi Enrollment](./protect-wireless-networks.mdx#chromeos-with-google-workspace-acme-device-attestation) and for any other mTLS use case involving ChromeOS devices. + +# Prerequisites + +- A completed [Connect Google Workspace to Smallstep](./connect-google-workspace-to-smallstep.mdx) integration, with devices syncing into Smallstep +- The Smallstep ChromeOS extension deployed to your target Organizational Unit (covered in that same guide) + +A freshly enrolled device isn't ready for mTLS until you complete the steps below, even though it may already appear fully enrolled and "high assurance" in both the Smallstep dashboard and the Admin Console. + +# Step-by-step instructions + +### 1. Confirm your issuing authority + +The device identity certificate is issued from an authority in Certificate Manager, typically set up together with your Smallstep contact during onboarding rather than chosen independently. There are two conceptual patterns: + +- **Device-bound** (e.g. a "Devices" authority) — binds the certificate to the device itself (subject is the hardware serial number). Use this for device-level authentication such as Wi-Fi. +- **User-bound** (e.g. an "Accounts" authority) — binds the certificate to the Google Workspace user currently signed in to the device (subject is the user's email). Use this if you need to authenticate the user rather than the device. + +Confirm with your Smallstep contact which authority applies to your setup before continuing — the rest of this guide refers to it as "the authority you chose." + +Both patterns support ACME Device Attestation, so the enrollment mechanics in the steps below are identical either way — only the resulting certificate's identity differs. + +### 2. Distribute the authority's trust root to Google Admin + +This step must happen **before** step 3, not after. Each authority's ACME directory is served over TLS using a certificate signed by that authority's own private root. If the Chromebook doesn't already trust that root, it cannot reach the directory — the extension retries in the background, but nothing about this is visible: no error appears in the extension, in `chrome://policy`, or in the Smallstep dashboard, and the device keeps presenting its existing certificate until the root is in place. + +1. In Certificate Manager, go to **Authorities**, select the authority you chose in Step 1, and download its **Root Certificate** and **Intermediate Certificate**. +2. In Google Admin, go to **Devices → Networks → Certificates**, select your target Organizational Unit, and add both certificates. Check ✅ **Enabled for Chromebook** for each. + + +
+You can confirm whether trust distribution succeeded from your own computer, without touching a Chromebook at all: `curl -sS https://..ca.smallstep.com/acme/acme-da/directory`. A TLS error like `unable to get local issuer certificate` means the root hasn't propagated yet or wasn't uploaded. A JSON response means you're clear to continue. +
+
+ +### 3. Set the extension policy + +The **Devices** authority is already the default: if that's what you chose in Step 1, the extension issues a device identity certificate from it automatically with just the `team` field, and you can skip to Step 5. + +`devices_ca_directory_url` is only needed if you chose the **Accounts** authority instead, or need to point at a non-default Devices authority. In Google Admin, go to **Devices → Chrome → Apps & Extensions → Users & browsers**, select your Organizational Unit, and open the Smallstep extension's **Policy for extensions**. Add `devices_ca_directory_url`, pointing at the ACME Device Attestation directory of the authority you chose: + +```json +{ + "team": { "Value": "" }, + "devices_ca_directory_url": { + "Value": "https://devices..ca.smallstep.com/acme/acme-da/directory" + } +} +``` + +Use `devices....` for the Devices authority, or `accounts....` for the Accounts authority. + +### 4. Force a fresh enrollment + +This step only applies if you completed the policy change in Step 3 — for example switching to the Accounts authority, or changing `devices_ca_directory_url` on a device that already has a valid certificate. The extension won't pick up a policy change on its own while it already holds a valid certificate, so a policy save alone has no effect. On the Chromebook: + +1. In Google Admin, set the extension's **Installation policy** to **Block**, and save. +2. On the device, open `chrome://policy` and click **Reload policies**. +3. In Google Admin, set the **Installation policy** back to **Force install + pin**, and save. +4. Reload policies again, then **reboot the Chromebook**. + +The reboot matters — a device can otherwise continue presenting its old certificate to an mTLS endpoint even after the new one has been issued. + +### 5. Verify certificate issuance + +On the Chromebook, go to `chrome://certificate-manager/clientcerts/platformclientcerts`. You should see a new certificate issued by your chosen authority's Intermediate CA (there may be other certificates listed too). Open its **Details** and confirm the **Issuer** matches the authority you configured in Step 1. + + +
+The Smallstep dashboard's device detail page may continue to show "This device does not have any identity certificates" even after a certificate has been issued and is actively in use. This is a known gap in the ChromeOS extension today, not a sign anything went wrong — device identity certificates issued to ChromeOS devices don't yet surface on this panel. Confirm issuance on the device itself, or under **Certificate Manager → Certificates → x509** in the Smallstep dashboard, where issued certificates are listed normally. +
+
+ +# Troubleshooting + +**Setting `devices_ca_directory_url` had no visible effect.** Confirm the authority's root and intermediate were uploaded to Google Admin (Step 2) before the policy was set. If they were added afterward, repeat Step 4 to force re-enrollment. + +**Only one certificate appears after re-enrollment.** Confirm the Organizational Unit in Google Admin actually matches the device — and, separately, the signed-in user's OU, since extension policy is scoped to the user's OU rather than the device's. + +**The certificate's issuer doesn't match what a downstream service expects (e.g. a RADIUS server's configured issuer pattern).** Read the issuer directly off the certificate at `chrome://certificate-manager/clientcerts/platformclientcerts` rather than assuming a value — it's the only way to be certain which authority actually signed it. + +# Next steps + +With a device identity certificate issued, continue to [ChromeOS Wi-Fi Enrollment](./protect-wireless-networks.mdx#chromeos-with-google-workspace-acme-device-attestation) to use it for passwordless 802.1X Wi-Fi authentication. diff --git a/tutorials/connect-google-workspace-to-smallstep.mdx b/tutorials/connect-google-workspace-to-smallstep.mdx index 1d9b4773..d24007f8 100644 --- a/tutorials/connect-google-workspace-to-smallstep.mdx +++ b/tutorials/connect-google-workspace-to-smallstep.mdx @@ -5,7 +5,7 @@ html_title: Integrate Google Workspace with Smallstep Tutorial description: Integrate Google Workspace with Smallstep for Chromebook device security. Complete guide for enforcing device trust in ChromeOS environments. --- -Smallstep can integrate with Google Workspace to keep your ChromeOS device inventory in sync. +Smallstep can integrate with Google Workspace to keep your ChromeOS device inventory in sync and manage credentials for ChromeOS devices. # Prerequisites @@ -19,11 +19,12 @@ You will need: In Google Cloud Console, select a project you will use for Smallstep. This can be any project, as long as you can grant domain-wide delegation to the client in a future step. -Your Google Cloud project must have the Admin SDK API enabled. By default, it is disabled. +Your Google Cloud project must have the Admin SDK and Chrome Verified Access APIs enabled. By default, they're disabled. -### 0. Enable admin SDK API +### 0. Enable APIs 1. Go to [Admin SDK API](https://console.cloud.google.com/apis/api/admin.googleapis.com) for your project, and choose **Enable API** +2. Go to [Chrome Verified Access API](https://console.cloud.google.com/marketplace/product/google/verifiedaccess.googleapis.com) for your project, and choose **Enable API** ### 1. Create a service account for Smallstep @@ -34,36 +35,77 @@ Your Google Cloud project must have the Admin SDK API enabled. By default, it is 5. Choose **Done** 6. Open the details for the Service Account you just created 7. Copy the **Unique ID** (numeric) and the **Email** shown on the details tab; you’ll need them later -8. Visit the **Keys** tab, and choose **Add key**, then **Create new key** -9. Choose **Create** to create a JSON key -A file containing the service account key will be downloaded. Keep this safe and secure! +### 2. Setup Workload Identity Federation -### 2. Grant device directory API permissions +The Smallstep platform authenticates to your Google Workspace through Workspace Identity Federation for Google Kubernetes Engine. + +1. In Google Cloud, visit [IAM & Admin → Workload Identity Federation](https://console.cloud.google.com/iam-admin/workload-identity-pools) +2. Choose **Create pool** +3. Set a name, e.g. "Smallstep Google Workspace Sync Pool" +4. Optionally, provide a **Description** for the pool +5. Click **Continue** +6. Select **OpenID Connect (OIDC)** as the provider +7. Set a name, e.g. "Smallstep Google Workspace Sync" +8. Set the issuer URL to **https://container.googleapis.com/v1/projects/prod-us-central1-e5bd/locations/us-central1/clusters/primary** +9. Set **Allowed audiences** to `sts.googleapis.com` +10. Click **Continue** +11. For the **google.subject** attribute, set **assertion.sub** +12. Click **Add mapping**, and set **attribute.k8s_sa** to **assertion.kubernetes.io.serviceaccount.name** +13. Click **Save** + +### 3. Grant Access to the Service Account + +1. Click **Grant access** +2. Select **Grant access using service account impersonation** +3. Select the **Service account** you created earlier from the dropdown +4. Select **k8s_sa** as the attribute +5. Set **system:serviceaccount:prod:inventory** as the value for the attribute +6. Click **Save** +7. When the modal appears, you can **Dismiss** it + +### 4. Grant device directory API permissions 1. In Google Admin, visit [Security → Access and data control → API controls](https://admin.google.com/ac/owl) 2. Under Domain wide delegation, select **Manage Domain Wide Delegation** 3. In the **API Clients** table, select **Add new** 1. Enter the **Unique ID** of the service account from Step 1 - 2. For the **OAuth Scopes**, enter the following scope: + 2. For the **OAuth Scopes**, enter the following scopes: ``` https://www.googleapis.com/auth/admin.directory.device.chromeos + https://www.googleapis.com/auth/verifiedaccess ``` 3. Choose **Authorize** -### 3. Add Google Workspace to Smallstep +### 5. Create and Assign Custom Admin Role to Service Account + +1. In Google Admin, visit [Account → Admin roles](https://admin.google.com/ac/list/roles) +2. Click **Create new role** +3. Give it a descriptive name, e.g. **Google Workspace Sync** +4. Enable the **Manage ChromeOS Devices** privilege (incl. all subitems) +5. Click **Continue** +6. Click **Create role** +7. Click the newly created role +8. Click **Admins assigned** +9. Click **Assign service accounts** +10. Enter the principal of the service account created earlier +11. Click **Assign role** + +### 6. Add Google Workspace to Smallstep In Smallstep, visit [Settings → Device Management](https://smallstep.com/app/?next=/settings/devices). Configure a new Google Workspace Integration with the following values: - The **Customer ID** of your Google Workspace tenant. The Customer ID is a short alphanumeric string. It can be obtained from the Google Workspace Admin [Account Settings](https://admin.google.com/ac/accountsettings/profile) page -- The **Service Account JSON key** you downloaded earlier -- An email address of a user in your Google Workspace directory with admin permissions +- The numeric **Project ID** of the GCP project your service account was created in +- The **workload identity pool** +- The **workload identity provider** +- The service account **principal** -### 4. Add Smallstep certificates to Google Workspace +### 7. Add Smallstep certificates to Google Workspace After saving the Google Workspace connection, you will see settings for your integration. @@ -85,8 +127,48 @@ After saving the Google Workspace connection, you will see settings for your int - Choose **Add** 5. Repeat Step 4 for each of the certificates you downloaded +### 8. Verified Access Mode Configuration + +1. In Google Workspace, visit [Devices → Chrome → Settings](https://admin.google.com/ac/chrome/settings/device). +2. Select **Device settings** +3. Click **Verified mode** +4. Ensure the correct **Organizational Unit** is selected for scoping the configuration +4. Under Configuration, select **Require verified mode boot for verified access** +5. Set the email address of the GCP service account in the **Services with full access** field +6. Click Save + +### 9. ChromeOS Extension Configuration + +1. In Google Workspace, visit [Devices → Chrome → Apps & extension](https://admin.google.com/ac/chrome/apps). +2. Click **Users & browsers** +3. Ensure the proper **Organizational Unit** is selected for scoping the configuration +4. Click the **+** icon on the bottom right +5. Click **Add Chrome app or extension by ID** +6. Set the **Extension ID** to **icjpnolkgdnfgpccpkdlipalcmalkndl** +7. In the dropdown, choose **From a custom URL**, and set it to **https://packages.smallstep.com/chromeos/latest/update.xml** +8. Click **Save** +9. Click the newly created extension to edit it +10. Select **Force install + pin** as the **Installation policy** +11. Under **Certificate management**, enable **allow access to keys** and **Allow enterprise challenge** +12. Under **Policy for extensions**, add the following JSON, replacing `` with your Smallstep team slug: + +``` +{ + "team": { + "Value": "" + } +} +``` +13. Click **Save** in the top right corner +14. Scroll down in the side panel details, and confirm the **Installation URL** field shows the URL you set in step 7. +15. Set the **Update URL** to **Installation URL (see above)** +16. Click **Save** + + ### Confirmation Within a few minutes, you should see all of your ChromeOS devices in Smallstep's [Devices](https://smallstep.com/app/?next=/devices/all) tab. A full sync is performed every 8 hours, and a partial sync every hour. +With the extension deployed, continue to [Configure ChromeOS Device Identity Certificates](./chromeos-device-identity-certificates.mdx) — by default the extension only requests a short-lived attestation certificate, which can't be used for Wi-Fi, VPN, or mTLS. +