Cua Docs

Permission modes and bounded autonomy

Standard, bounded, and unrestricted startup modes, protected consent, session manifests, and revocation in Cua Driver.

Cua Driver resolves one permission mode when the daemon starts. A tool call cannot change the mode. The mode controls when work stops for protected human approval; permission policies still decide which calls are allowed.

Modes#

ModeStartupHuman interventionExisting logged-in profile
standardDefaultCurrently once for existing-profile attachment; other risk classes are metadata-only until their adapters shipRequires a certified protected-consent provider and its persistent Stop indicator
bounded--permission-mode bounded --session-policy <path> --approve-session-policyOnce when a trusted launcher reviews and approves the bounded manifestAllowed only when the manifest names the exact PID/window and a certified indicator provider is available
unrestricted--dangerously-bypass-approvalsOnce at trusted launch; no runtime Cua approval promptsMay attach without a protected provider after the explicit launch warning

autonomous remains a compatibility alias for bounded; new launchers and manifests should use bounded. yolo remains a configuration alias for unrestricted. The CLI's deliberately alarming bypass flag selects unrestricted and records the launch-time risk acknowledgement in one step. Passing --permission-mode unrestricted without that flag still fails closed.

Unrestricted mode does not defend against prompt injection or unintended input. It suppresses Cua approval prompts inside the same built-in, managed, and user-policy ceilings. Run it only in a disposable VM or with accounts and data whose full compromise you accept.

The authorization stack#

Every daemon transport reaches the same authorization coordinator. A call must pass each active layer:

  1. The reviewed built-in tool and risk map.
  2. The administrator policy from CUA_DRIVER_MANAGED_POLICY_FILE, when set.
  3. The user policy from CUA_DRIVER_POLICY_FILE, when set.
  4. The bounded session manifest, in bounded mode.
  5. A live resource grant for adapters marked risk.enforcement: "active".

Each layer can narrow access. Approval and unrestricted mode cannot widen a policy layer. An unknown tool has no reviewed risk class and is denied.

Tool-list and description responses include risk metadata with class, enforcement, operation_sensitive, and version. The first active adapter is browser_prepare with strategy.kind=existing_profile. Other listed risks are metadata_only until their resource, output, and revocation adapters ship.

A protected provider must return a decision directly to the daemon over an authenticated host or OS channel. The request binds the decision to the daemon instance, request nonce, generation, mode, policy hashes, sessions, operation, expiry, and exact resource. An accepted request becomes live only after the provider activates a persistent indicator with a Stop control.

Ordinary MCP elicitation, MCP tool arguments, inherited standard input, a TTY, environment variables, and files do not satisfy this contract. They are writable by the calling process. If the daemon has no certified provider, standard and bounded refuse existing-profile attachment.

The current standalone CLI/MCP daemon has no certified Codex or Claude host provider. Its protected-consent status therefore reports unavailable. Isolated browser profiles remain available. A trusted embedding host can install the provider interface in process.

The old file-backed browser-approve artifact is disabled by default for existing profiles. A trusted launcher can temporarily enable it with --allow-legacy-existing-profile-approval, but the artifact is a compatibility mechanism, not protected human consent. It is accepted only in standard mode and cannot be combined with bounded or unrestricted startup.

Bounded session manifest#

The launcher loads one YAML manifest at startup and confirms it with the separate --approve-session-policy flag. The daemon hashes the file, keeps an immutable in-memory copy, and refuses to bind when the file is missing, invalid, unapproved, or already expired. The maximum lifetime is 24 hours. The idle timeout refreshes only after a fully authorized dispatch. Once it expires, the manifest is terminal for that daemon instance and cannot be revived by another call.

version: 1
mode: bounded
expires_after: 8h
idle_timeout: 30m
 
resources:
  browser:
    existing_profiles:
      - pid: 844
        window_id: 10725
    origins:
      - https://docs.example.com
      - https://app.example.com
 
allow:
  tools:
    - start_session
    - end_session
    - get_browser_state
    - browser_prepare
    - browser_navigate
    - browser_click
    - browser_type
 
deny:
  tools:
    - page
 
ask:
  tools:
    - browser_download
    - browser_set_input_files

Tools omitted from all three sets are denied. ask also denies unattended dispatch because an agent cannot accept its own prompt. A future protected host adapter may resume such a call after protected approval.

For existing-profile preparation, the requested PID and native window must match an existing_profiles entry. Requested navigation must use an allowed origin. Before every browser mutation, the daemon reads the live top-level URL through CDP and refuses browser_origin_outside_scope if a redirect moved the tab outside the manifest.

An origin-scoped manifest cannot also allow generic page, desktop input, or desktop-state tools that bypass the typed browser-origin adapter. Use browser_click, browser_type, and the other typed browser tools instead.

PID/window binding reduces confused-deputy risk but does not provide permanent process identity over a long session: an OS can eventually reuse identifiers. Keep manifests short-lived and revoke or restart after a browser relaunch. Launch supervisors must preserve --permission-mode, the session-policy path, and its explicit approval flag on restart; falling back to default standard is a fail-closed change, not a continuation of the bounded session.

Embedded and managed launchers#

The CLI flag is intentionally convenient, but programmatic launchers retain a two-part contract. Set both values on the trusted daemon process:

CUA_DRIVER_PERMISSION_MODE=unrestricted \
CUA_DRIVER_DANGEROUSLY_BYPASS_APPROVALS=1 \
  cua-driver serve --embedded --socket <private-socket>

Setting only the mode or only the acknowledgement fails before the daemon binds. Treat these as trusted-launch configuration, not tool arguments an agent can choose at runtime.

Managed controls#

Set CUA_DRIVER_MANAGED_POLICY_FILE to apply an administrator-owned YAML or Rego ceiling before the user policy. Both files are loaded once and intersected. An explicitly configured missing or invalid path prevents the daemon from binding its action endpoint.

Administrators can also set CUA_DRIVER_DISABLE_UNRESTRICTED=1. The daemon then rejects unrestricted startup even when the danger flag is present.

Status and revocation#

cua-driver status reports the effective mode, policy hashes, session-manifest hash and expiry, active risk adapters, and protected-provider availability. It does not print policy contents or browser data.

End one session and every grant it owns:

cua-driver revoke --session research-1

End all live authorization scopes:

cua-driver revoke --all

Session end, indicator Stop, grant expiry, policy-context mismatch, browser identity drift, reconnect exhaustion, and daemon restart also revoke the existing-profile grant.