Skip to content

cli: add custom chrome policy flags to browser and pool commands#180

Merged
rgarcia merged 2 commits into
mainfrom
hypeship/cli-chrome-policy
Jun 11, 2026
Merged

cli: add custom chrome policy flags to browser and pool commands#180
rgarcia merged 2 commits into
mainfrom
hypeship/cli-chrome-policy

Conversation

@rgarcia

@rgarcia rgarcia commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds CLI support for setting a custom Chrome enterprise policy (the API's chrome_policy field, already supported by the Go SDK) on three commands:

  • kernel browsers create
  • kernel browser-pools create
  • kernel browser-pools update

Each gains two mutually-exclusive flags:

  • --chrome-policy '<json>' — an inline JSON object
  • --chrome-policy-file <path> — read the object from a file (- reads stdin)

This mirrors the existing --payload / --payload-file and --data / --data-file conventions.

kernel browsers create --chrome-policy '{"BookmarkBarEnabled": false}'
kernel browsers create --chrome-policy-file policy.json
cat policy.json | kernel browser-pools update my-pool --chrome-policy-file -

Design notes

  • A shared parseChromePolicy helper parses into map[string]any, so non-object JSON (arrays, scalars, null) is rejected with a clear error before any request is sent.
  • chrome_policy uses omitzero, which only drops a nil map — a non-nil empty {} would serialize as "chrome_policy":{}. Assignment is therefore guarded by len > 0, so an empty object is treated as "unset".
  • On browser-pools update, an empty {} cannot clear an existing policy (omitzero strips it before it reaches the server). Rather than silently no-op, this surfaces a warning in human output (suppressed under -o json to keep stdout valid).
  • Kernel-managed policies (extensions, proxy, automation) are enforced server-side. The CLI forwards the object verbatim and surfaces the API's error, rather than duplicating a blocklist that would drift.

Scope

  • browsers update and invoke are intentionally excluded: their SDK params structs (BrowserUpdateParams, InvocationNewParams) carry no chrome_policy field, so there's nothing to wire until the SDK is regenerated.
  • The policy echoes back via --output json with no printer changes (response structs already carry the field).

Test plan

  • Unit tests for all three commands: inline policy applied, empty {} omitted (asserted at both the Go field and the serialized JSON), invalid JSON / null rejected, parser covers file + stdin + whitespace + missing-file, and the pool-lease conflict contract is locked (--chrome-policy stays out of the allowed-flag set).
  • make test (go vet + go test ./...) passes; gofmt clean.
  • E2E against a live environment via the built binary: inline/file/stdin create echo the policy; pool create + get persist it; pool update replaces it and an empty {} no-ops without clearing; invalid/null/mutual-exclusion exit non-zero before any API call; and the server correctly rejects ProxyMode / ExtensionInstallForcelist with the CLI surfacing the error.

Note (pre-existing, unrelated)

When a browser-config flag is combined with --pool-id/--pool-name, the existing conflict-confirmation prompt (pterm.DefaultInteractiveConfirm) does not treat EOF / non-TTY stdin as "no", so it blocks in a non-interactive pipeline. This predates this change and affects all config flags equally; flagging it as a possible follow-up.

🤖 Generated with Claude Code


Note

Low Risk
CLI-only feature forwarding JSON to existing API fields; validation is local and server enforces blocked policies. No auth or data-path changes.

Overview
Adds --chrome-policy and --chrome-policy-file (mutually exclusive, - for stdin) to kernel browsers create and kernel browser-pools create / update, wiring the API’s chrome_policy field through a shared parseChromePolicy helper.

Policies are only sent when the parsed object is non-empty (len > 0), so {} is not serialized on create. On pool update, passing {} does not clear an existing policy; the CLI warns in human output and stays silent with -o json. poolLeaseAllowedFlags is extracted so --chrome-policy is not treated as allowed alongside --pool-id/--pool-name, surfacing the existing pool-lease conflict warning instead of ignoring the flag.

README documents flags, examples, and the pool-update clearing limitation. Unit tests cover parsing, SDK params, JSON omission, warnings, and pool-lease behavior.

Reviewed by Cursor Bugbot for commit 6a470a3. Bugbot is set up for automated code reviews on this repo. Configure here.

Add --chrome-policy / --chrome-policy-file to `browsers create`,
`browser-pools create`, and `browser-pools update`, wiring the API's
chrome_policy field (already supported by the Go SDK) through the CLI.

The two flags are mutually exclusive; --chrome-policy takes an inline
JSON object and --chrome-policy-file reads one from a path ("-" = stdin),
matching the existing --payload/--payload-file convention. A shared
parseChromePolicy helper validates the input is a JSON object. Blocked
kernel-managed policies are enforced server-side, so the CLI forwards
verbatim and surfaces the API error rather than duplicating the rules.

An explicit empty object is dropped from the request (chrome_policy uses
omitzero, which only drops a nil map, so assignment is guarded by len>0);
on pool update an empty object cannot clear an existing policy, which is
surfaced with a warning in human output.
@rgarcia rgarcia marked this pull request as ready for review June 9, 2026 21:20
@rgarcia rgarcia requested a review from masnwilliams June 9, 2026 21:22

@masnwilliams masnwilliams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Whitespace policy triggers false update warning
    • The warning now only appears for an explicit empty JSON object by checking for a non-nil parsed policy map, and a regression test confirms whitespace-only input stays quiet.

Create PR

Or push these changes by commenting:

@cursor push 901ffb4d16

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 6a470a3. Configure here.

Comment thread cmd/browser_pools.go
// An empty policy ({}) cannot clear an existing one: omitzero drops it before it
// reaches the server. Warn instead of silently doing nothing, but stay quiet on the
// json path so stdout remains valid JSON.
pterm.Warning.Println("An empty chrome policy is ignored and does not clear the pool's existing policy; recreate the pool to remove a policy.")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace policy triggers false update warning

Low Severity

On browser-pools update, the empty-policy warning keys off whether --chrome-policy or --chrome-policy-file was provided, not whether parsing produced an explicit {} object. Whitespace-only inline values, an empty policy file, or stdin with only blanks return nil from parseChromePolicy but still print that an empty policy will not clear the pool.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6a470a3. Configure here.

@rgarcia rgarcia merged commit 905b022 into main Jun 11, 2026
7 checks passed
@rgarcia rgarcia deleted the hypeship/cli-chrome-policy branch June 11, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants