Deploy the Certificate Enrollment for Chrome OS Extension

This article focuses on the steps required to successfully deploy the Certificate Enrollment for Chrome OS extension. It also provides helpful troubleshooting information for common errors that users may run into. If you have comments or suggestions, please send them via email to

Note regarding third-party products: This article may describe how Google products work with third-party products and the configurations that Google recommends. Google does not provide technical support for configuring third-party products. Google accepts no responsibility for third-party products. Please consult the product's Web site for the latest configuration and support information. You may also contact Google solutions providers for consulting services.

Minimum Requirements

  • Windows Server 2008 R2 or higher
  • Internet Information Services (IIS) 7.0 or higher
  • Active Directory Certificate Services (ADCS) including:
    • Certificate Enrollment Web Service
    • Certificate Enrollment Policy Web Service
    • A valid certificate associated to the ADCS website in IIS
    • A visible endpoint for both the policy web service (CEP) and enrollment web service (CES)

      For detailed setup instructions for ADCS, see Setting up ADCS for auto-enrolling Chrome devices.

    1. Add the extension in the Google Admin console

    Configure the extension in the Chrome management console:

    1. Sign in to the Google Admin console.
    2. Go to Device Management > Chrome Management > App Management, and in the Find or Update Apps field, type in the following extension ID: fhndealchbngfhdoncgcokameljahhog.


    Force-install the extension via the User settings UI:

    1. Select the organizational unit where you want to deploy the extension.
    2. Ensure that Allow installation and Force installation are enabled (blue bar), using Override, if necessary.

    2. Apply the extension policy

    On the same menu, do the following:

    Please note that the server currently accepts invalid JSON files but the Chrome OS client will not properly receive and parse those files. Please run your file through a JSON sanitizer to ensure policy will be properly delivered to your client machines. For example, entries such as “MyOrg\Username” will break the JSON format; entries using backslash must escape those with another backslash i.e. “MyOrg\\Username”.

    1. Under Configure, click Upload configuration file. You may need to click Override if you apply this setting at the organizational unit level.
    2. Select the policy file created by following the instructions in Configure the extension policy below.
    3. Configure the Wi-Fi network to enroll with the extension
    1. Go to Device Management > Network > Wi-Fi to create your new EAP-TLS network.
    2. In the Client enrollment URL field, point the network to the enrollment extension by entering chrome-extension://fhndealchbngfhdoncgcokameljahhog/html/request_certificate.html.

    Note: The above URL is accessible in the Chrome browser even if no networks are yet configured to enroll at this URL. This is handy for deployment purposes as you could test out this URL manually before configuring any networks. It is also convenient if you only want to enroll certificates for uses other than EAP-TLS networks (for example, certificate-based VPN). In that case, it is sufficient to simply instruct users to go to the above indicated URL in their browser and skip the network configuration step.

    4. Configure the extension policy

    For the extension to work properly, you need to configure the following basic Chrome extension policies. It's best to start with the sample file given below and tweak the policies per your needs.

    Note on internationalization: User facing strings unchanged by policy will be translated according to the user locale. If the administrator decides to change those values, then the translation will not be applied to the administrator's strings.

    • cep_proxy_url—The https endpoint for the Certificate Enrollment Policy Web Services. This can be found under IIS Manager by going to the CEP website (typically has CEP in the name) and viewing application settings. It will be listed there under the name “uri”. If this field is empty or does not start with https, there will be an error.

      Important: Please be especially cautious when configuring this variable as we consider any value that starts with https as valid. If a malicious value is input here and starts with https, it will not be caught and will flow all the way through to all users.
    • enable_auto_enrollment—Control whether the extension initiates enrollment automatically or waits for the user attempt at connecting to the EAP-TLS network. Default is false.
    • allow_machine_cert_enrollment—Control whether the user in question is allowed to install a device-wide certificate. Device-wide certificates are shared across all users in your organization on the same device. If this is enabled, users may opt to request a device-wide certificate or not. If this is disabled, users are only allowed to request user certificates. The default is false.
    • user_enrollment_templates—List of matching certificate template common names in order of priority for user-enrollment flows. The extension will traverse the list of policies to find a matching certificate. The default is ChromeOSWirelessUser. This must have at least one value in the list.
    • device_enrollment_templates—List of matching certificate template common names in order of priority for device-enrollment flows. The extension will traverse the list of policies to find a matching certificate. The default is ChromeOSWirelessDevice. This must have at least one value in the list.
    • placeholder_values—The JSON object that holds the username, password, URI, request ID, and header placeholders. This helps organizations guide their users when logging in. The Username, Password, URI, and RequestID fields are displayed over the input fields to show what each input field does. The Header field is used for the page’s title.
      • If your organization uses other terminology (such as email address or ‘GAIA ID’ instead of username, or passphrase instead of password), then you can customize these values to be more appropriate; however it will remain static when the user changes languages (so ‘GAIA ID’ will show up in English even if the user sets the language to Spanish, for example).
      • Additionally, there are special values for the Username, Password, and Header fields that allow customers to use our internationalized default names, ‘Username’, ‘Password’, and ‘Certificate Enrollment’. That means setting Username to managed_username_placeholder (as shown below) will result in the default value of ‘Username’ displaying when the user is viewing in English, and ‘用户名’ (or similar text) displaying when the user is viewing in Chinese for example. These special values are managed_username_placeholder for Username, managed_password_placeholder for Password, and managed_login_header for Header.
      • Below is the structure and default values.

        Username: “managed_username_placeholder” (default),
            // alternatively “COMPANY\user” or “”
        Password: “managed_password_placeholder” (default)    ,
            // alternatively “passphrase” or “login credential”
        Uri: “Enrollment URI” (default),
        RequestId: “Request ID” (default),
        Header: “managed_login_header” (default)

    • company_info—JSON object holding the relevant branding information for a company. The help url can be set to direct users for more information. However, if that page is blocked for users without any certificate (on the first request), you can specify your own helping text. Setting both will cause the url to be appended at the bottom of the text when displaying on the screen. Below is the structure and default values.

        Name: “Product Name” (default),

            // e.g. “Company A Enrollment”,
        Logo: “<Product Logo>” (default empty),    
            // e.g.    “data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABA..”,
            // Recommended size in the range of 150px
            // Existing logos can be converted to this base64 format online
        HelpURL: “<Google Help Center URL>” (default),
            //  e.g. “”,
        HelpText: “<>” (default)
            //  e.g. “Contact your local IT specialist for more help.”

    • log_level—The relevant log level to be used in the application. The log level must be set to one of these 5 values or there will be an error.
      • LogLevel “NONE” (default) Nothing is logged to the console.
      • LogLevel “ERROR” Only distinct errors are logged to the console.
      • LogLevel “WARNING” Distinct errors and warnings are logged to the console.
      • LogLevel “INFO” Distinct errors and warnings along with relevant action information are logged to the console.
      • LogLevel “DEBUG” Everything is logged to the console. For the initial version, this is recommended to facilitate troubleshooting potential issues. When set at “DEBUG”, an extra button will appear in More Options to automatically copy all logs to the clipboard.
    • signature_algo—Controls what signature algorithm the extension uses to sign certificate requests.
      • “SHA1” Not recommended - SHA1 is a weak algorithm that can compromise the security of your users. Use SHA-1 as the signature algorithm.
      • “SHA256” Use SHA-256 as the signature algorithm.
      • “SHA512” (default) Use SHA-512 as the signature algorithm.
    • pending_ui_enabled—Controls whether or not the pending request UI should be reachable in the extension. If your CA never leaves certificate requests in a pending state, then it is recommended to set this to false. Default is false.
    • renew_hours_before_expiry—This combined with renew_reminder_interval controls notifications for renewing certificates that will expire soon. Notifications will begin at the certificate’s expiration time minus the amount of hours set in this variable. Default is 120.
    • renew_reminder_interval—This combined with renew_hours_before_expiry controls notifications for renewing certificates that will expire soon. After an initial notification, if the user does not renew the certificate and does not select ‘Ignore all Reminders’ (or similar message), then another notification will display after the amount of hours set in this variable. For example, if renew_hours_before_expiry is set to 120, this is set to 24, and a user always selected ‘Remind Me Later’ (or similar message), then the user would receive 5 total renewal notifications (one each day) until the certificate expired. Default is 24.

    Sample Extension Policies JSON

      "cep_proxy_url": {
        "Value": "https://Your_CEP_Endpoint_Goes_Here"
      "enable_auto_enrollment": {
        "Value": false
      "allow_machine_cert_enrollment": {
        "Value": false
      "user_enrollment_templates": {
        "Value": ["ChromeOSWirelessUser"]
      "device_enrollment_templates": {
        "Value": ["ChromeOSWirelessDevice"]
      "placeholder_values": {
        "Value": {
                   "Username": "managed_username_placeholder",
                   "Password": "managed_password_placeholder",
                   "Uri": "Pending Request Enrollment URI",
                   "RequestId": "Pending Request ID",
                   "Header": "managed_login_header"
      "company_info": {
        "Value": {
                   "name": "Company A",
                   "logo": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABA...",
                   "help_url": "",
                   "help_text": "Contact your local IT specialist for more help."
      "log_level": {
        "Value": "DEBUG"
      "signature_algo": {
        "Value": "SHA512"
      "pending_ui_enabled": {
        "Value": false
      "renew_hours_before_expiry": {
        "Value": 120
      "renew_reminder_interval": {
        "Value": 24


    Error messages

    Error message: "Could not find a valid user token. Your device may not be enrolled in the domain."

    Make sure that the extension is force installed. You can do this by making sure Force installation is enabled in in Step 1: Add the extension in the Google Admin console.

    Error message: "No enrollment uris available" 

    This error usually stems from your configured template not being found by the Certificate Policy Service (CEP). This can happen for a variety of reasons and it can be difficult to find the exact fix for this issue. Check whether you configured the role services for Certificate Enrollment to accept username and password authentication (rather than Kerberos for example), and whether you exported the template you need in addition to creating it. Also check what level of security the template is set to.  Ensure the user_enrollment_templates value is set to the template name and NOT the template display name.

    Accessing logs

    Currently, logs are sent to the javascript console in Chrome. The verbosity or log level is configured through a managed policy setting (see above). To access the logs in chrome follow these steps to launch the javascript console in Chrome or navigate to More Options > Copy Logs to Clipboard to have all current logs copied to the user’s clipboard.

    Policy fails to reach the Chrome OS client

    To verify if policy is being applied to your Chrome OS client, navigate to chrome://policy and ensure that the proper entries are recorded under the section belonging to the extension. If the policy is not being updated or is simply not being delivered, the policy file you supplied in Step #2 could be malformed. Please run your file through a JSON sanitizer to ensure that the JSON is valid so that Chrome OS client can receive and parse it.

    For example, entries such as “MyOrg\Username” will break the JSON format; entries using backslash must escape those with another backslash i.e. “MyOrg\\Username”.

    Extension requests enrollment endpoints from itself

    If you are having this problem, requests going across the wire look like this: chrome-extension://userNameGoesHere:passWordGoesHere@fhndealchbngfhdoncgcokameljahhog/html/request_certificate.html instead of https://userNameGoesHere:passWordGoesHere@yourCEPServiceUriGoesHere.

    This seems to happen when the chrome extension is first installed (or updated) and has no existing (loses its previous) state information, meaning the current managed policy which is held in the background script. In some cases, after this new installation the managed section of storage will not be found. We are working to implement retry functionality ourselves, but for now there is a work around.

    If you push a new policy (or potentially an empty policy) that is somehow different from the existing one (such that chrome will register a change), ensure that the Chromebook picks up that new policy, then re-push the policy you want, and ensure that the Chromebook picks up the changes, it will update the background script to once again hold that policy in its state. It is recommended to push an empty policy and then the one you want so that all policy values are effectively flushed and reset.

    To ensure that the Chromebook picks up the changes, you can go to chrome://policy on the Chromebook and find the section for Chrome OS Certificate Requester. You can manually request any new policy by clicking Refresh at the top; the policy is then reflected on the page. By pushing an empty policy and refreshing, all variables should be cleared out from the Chrome OS Certificate Requester section. Similarly, by then pushing the policy desired and refreshing, all variables should reflect their desired values.

    Finally, refreshing the UI page after all of this is done will allow users to proceed as normal. The UI page will not re-request the policy from the background until it is refreshed, so this must be done to propagate the policy along.

    Insecure connections

    If you see ERR_INSECURE_RESPONSE in your console when trying to reach the enrollment endpoint, it means your browser does not trust the certificate being presented by that server. To fix this issue, you need to add that certificate to the management console and instruct Chrome to install it as a certificate authority. You can find steps to perform this here.

Was this article helpful?
How can we improve it?