For Developers‎ > ‎How-Tos‎ > ‎Enterprise‎ > ‎

Running the cloud policy test server

Chromium can pull down enterprise policy configuration from a cloud service. We have a simplistic python implementation of the management service, so we are able to test features without relying on a full cloud policy server implementation. This page explains how to run it:

Running the test server

  1. You need a Linux Chromium checkout that's in good shape for building the browser. See Get the Code
  2. Make sure you have the protocol buffer source compiled:
    make py_proto policy
  3. Start the test server. You can start directly from the src/ directory of your Chrome source tree:
    PYTHONPATH=third_party/tlslite:third_party/pyftpdlib/src:out/Debug/pyproto:out/Debug/pyproto/chrome/browser/policy/proto/cloud:out/Debug/pyproto/chrome/browser/chromeos/policy/proto:out/Debug/pyproto/policy/proto:net/tools/testserver python chrome/browser/policy/test/ --data-dir ~/tmp/ --host --port 8889

    Note: replace out/Debug with out/Release if appropriate, depending on your build configuration.

    Or, as is done in this example, go through some shell magic to enable logging in the server:
    cd chrome/src
    echo -e "import logging\nlogging.basicConfig(filename='/dev/stdout',level=logging.DEBUG)" |\
    cat - ./net/tools/testserver/ |\
    PYTHONPATH=third_party/tlslite:third_party/pyftpdlib/src:out/Debug/pyproto:out/Debug/pyproto/chrome/browser/policy/proto/cloud:out/Debug/pyproto/chrome/browser/chromeos/policy/proto:out/Debug/pyproto/policy/proto:net/tools/testserver |\
    python - --data-dir ~/tmp/ --host 
    --port 8889 
    Notes on parameters:
    • --data-dir specifies the directory from which the server will read the policy file (see below). Up to you where to place it.
    • --port specifies the port the server should listen on, you can pick a port of your liking.
    • --host The IP address the server should bind to. Note that if you want to test a Chromium OS image running on a Chromebook or in a Virtual Machine against the server, you need to specify the host name or IP address of the public interface in your machine. Note that the server only accepts connections from that IP. To work around these restrictions you can use a port forwarding (ssh is your friend) or local proxy server.
  4. Check whether the server answers requests. Point your browser to http://localhost:8889/ (or the public IP you've passed to the --host switch). The server should respond with a page saying "Default response given for path: /".
  5. Ready to roll!

Setting up a policy file

The test server reads policy to supply to clients from a text file in JSON format. The file needs to be placed in the directory specified with the --data-dir switch and must be named device_management. The file is re-consulted on each policy request, so you can change policy definitions on the file without restarting the server (which would invalidate existing DMTokens, so restarting the server is usually not advised). Below is an example file. Note that I like to keep all different kinds of policies in the file, and I disable them by prefixing the name with a dash. That works because the server just ignores keys it doesn't understand:

  "google/chrome/user" : {
    "mandatory" : {
      "HomepageLocation" : "",
      "-HomepageIsNewTabPage" : false,
      "RestoreOnStartup" : 4,
      "RestoreOnStartupURLs" : [ "chrome://policy", "chrome://settings" ],
      "ShowHomeButton": true,

      "-SyncDisabled": true
    "recommended" : {
      "-ProxyMode" : "pac_script",
      "-ProxyPacUrl": "http://proxyconfig/wpad.dat",
      "-ProxyBypassList": ",localhost"
  "google/chromeos/user" : {
    "mandatory" : {
      "HomepageLocation" : "",
      "-HomepageIsNewTabPage" : false,
      "RestoreOnStartup" : 4,
      "RestoreOnStartupURLs" : [ "chrome://policy", "chrome://settings" ],
      "ShowHomeButton": true,

      "-ApplicationLocaleValue" : "de",

      "-SyncDisabled": true,
      "-PasswordManagerEnabled": false,
      "-PasswordManagerAllowShowPasswords": false,
      "-AutoFillEnabled": false,

      "-AlternateErrorPagesEnabled": false,
      "-SearchSuggestEnabled": false,
      "-DnsPrefetchingEnabled": false,
      "-SafeBrowsingEnabled": true,
      "-MetricsReportingEnabled": false,

      "-DisableSpdy": true,
      "-JavascriptEnabled": false,

      "-ProxyServerMode" : 2,
      "-ProxyMode" : "pac_script",
      "-ProxyPacUrl": "http://wpad/wpad.dat",
      "-ProxyBypassList": ",localhost",

      "-PrintingEnabled" : false,

      "-DisabledPlugins": [ "*Shockwave Flash*" ],

      "-DisabledSchemes" : [ "mailto", "ftp" ],

      "-SavingBrowserHistoryDisabled" : true,

      "-DeveloperToolsDisabled": true,

      "-Disable3DAPIs": true,

      "-DefaultSearchProviderEnabled": true,
      "-DefaultSearchProviderName": "TIMES",
      "-DefaultSearchProviderKeyword": "",
      "-DefaultSearchProviderSearchURL": "{searchTerms}&type=nyt&x=0&y=0",
      "-DefaultSearchProviderEncodings": [ "UTF-8" ],

      "-ExtensionInstallForcelist": [

      "-ExtensionInstallBlacklist" : [

      "-ExtensionInstallWhitelist" : [

      "-DefaultPopupsSetting": 1,
      "-PopupsBlockedForUrls" : [

      "-PopupsAllowedForUrls" : [

      "-DefaultCookiesSetting" : 2,
      "-CookiesAllowedForUrls" : [
      "-CookiesBlockedForUrls" : [
      "-CookiesSessionOnlyForUrls" : [

      "-DefaultNotificationsSetting": 1,

      "-BlockThirdPartyCookies" : true,

      "-PolicyRefreshRate" : 30000,

      "ChromeOsLockOnIdleSuspend" : true
    "recommended" : {
      "-ProxyMode" : "pac_script",
      "-ProxyPacUrl": "http://proxyconfig/wpad.dat",
      "-ProxyBypassList": ",localhost"
  "google/chromeos/device" : {
    "device_policy_refresh_rate" : 120000,
    "user_whitelist" : [ "*" ],
    "guest_mode_enabled" : true,

    "show_user_names" : true,
    "data_roaming_enabled" : false,
    "allow_new_users" : true,
    "metrics_enabled" : true,
    "release_channel" : "dev-channel",

    "open_network_configuration" : "{  \"NetworkConfigurations\": [ { \"Type\": \"WiFi\", \"GUID\": \"1234-5678-device\", \"Name\": \"Device Network\", \"WiFi\": { \"SSID\": \"Device Test\", \"Passphrase\": \"password.\", \"AutoConnect\": true, \"HiddenSSID\": false, \"Security\": \"WPA-PSK\" } } ] }",

    "report_version_info" : true,
    "report_activity_times" : true,
    "report_boot_mode" : true,

    "ephemeral_users_enabled" : true
  "managed_users" : [ "*" ],
  "policy_user" : ""

Some notes on the file contents:
  • The google/chromeos/user and google/chrome/user sections contain users policies for the chrome and chromeos platforms as specified in the documentation (generated from the master template). There are two subsections: mandatory configures forced policy that the user cannot change, recommended configures admin-supplied defaults. The policy keys are the same in both sections, but some policies just don't make sense as defaults, so they only work as mandatory policy.
  • google/chromeos/device refers to device-level policy (device settings) for Chromium OS. That section contains values as defined in the device settings protobuf; the keys are the field names from the individual protobuf messages for each setting group.
  • managed_users is a list of users that the server will accept for policy management. The wildcard as shown above is a fine choice for most situations and only needs to be changed if you specifically want to test behavior for the case that the server denies management
  • policy_user is the user ID that the server will put into the policy replies as the intended receiver.

Configuring Chromium OS to talk to the test server

In order to do something useful with the test server, you can configure Chromium built for Chromium OS to talk to the test server for device- and user-level policy. Here is what you need to do:
  1. Log into the VM or Chromebook that you want to talk to the test server.
  2. Make sure you have a writable root file system. Try mount -o remount,rw / if you don't, if that fails, you're likely on an actual device with enabled root file system protection, in that case check out /usr/share/vboot/bin/
  3. Edit /sbin/ Change the line reading
    # Device Manager Server used to fetch the enterprise policy, if applicable.
    # Device Manager Server used to fetch the enterprise policy, if applicable.
  4. On a shell, say
    restart ui
  5. You're now set up to fetch policy from the test server!

Configuring Chromium to talk to the test server

Pass the following command line flag to chrome:
  • --device-management-url=http://<your-ip>:<yourport>/device_management
Additionally, for Chrome 25, you'll need to pass the --load-cloud-policy-on-signin flag or enable the associated option in about:flags. This will cause Chromium to download policy for signed-in users.

User policy

To test some user policy setting, configure the policy file as desired and then just log in. The browser should automatically pull policy. You can verify that the policy is correctly pulled down from the server by inspecting chrome://policy. To test policy changes, you can also just update the policy in the file, and use the "Reload policies" button on chrome://policy to refresh policy at runtime.

Device policy

For devices to receive device policy, they need to be enrolled for enterprise management at device setup time. There are some requirements for that to succeed:
  • The device's TPM needs to be clear. In particular, running cryptohome --action=tpm_status should indicate that the TPM is not yet owned. If you have an owned TPM, you better flip the dev switch, boot till the Chrome OS is damaged screen, flip the switch back, reboot, and check the cryptohome status again.
  • The device may not have a consumer owner already, i.e. you shouldn't have logged in previously. Ownership is mainly indicated through files in /var/lib/whitelist, which you can clear like this
    stop ui
    rm -rf /var/lib/whitelist/*
    start ui
    This works well in a VM, note that you probably need a TPM reset an actual hardware (see above).
  • For enrollment with the actual cloud service (the test server doesn't care), you need the file /tmp/machine-info contain the serial number of the device. If you don't have it, you can do this:
    echo 'serial_number="my fake serial for testing"' > /tmp/machine-info
    restart ui
To perform the actual enrollment, hit Ctrl+Alt+E on the sign in screen. Provide credentials (note that in case of the test server, you must match the "policy_user" field from your "device_management" JSON file) and speak a short prayer. If you get lucky, the device will enroll. Log in and check chrome://policy for whether it says device policy is present.