Skip to content

security(agent): add filesystem and process isolation for isolated principals #459

Description

@pando85

Summary

Strengthen the OS boundary for mode = "isolated" principals and their managed browsers so that the implementation matches the intended cross-user isolation story more closely.

Passless already provides credential isolation for isolated profiles: separate credential/PIN/key-provider state and no access to the human credential namespace. The remaining work is to improve process and filesystem isolation around the principal/browser runtime without turning Passless into a general-purpose sandboxing platform.

This issue tracks the isolation work currently described as backlog in the agent security analysis / ADRs, particularly the lack of explicit mount/PID namespace enforcement for isolated deployments.

Security objective

An isolated principal or compromised managed browser should not gain incidental access to daemon-owned or unrelated principal resources merely because they share the host's default namespaces.

The target boundary is:

isolated agent profile
  -> dedicated Unix identity
  -> restricted filesystem view
  -> restricted process visibility / interaction where practical
  -> only explicitly required runtime/device/socket paths
  -> no human credential storage
  -> no other principal runtime/storage

This is additive defense in depth. It does not replace Chromium's own sandbox, the Passless policy engine, credential namespace separation, or host-level sandboxing supplied by containers/VMs when operators need a stronger boundary.

Current limitation

The current isolated/cross-user launcher applies identity changes and other process hardening, but the security analysis notes that browser/principal processes do not yet receive explicit Linux namespace isolation. As a result, a compromised process may retain a broader view of host mounts/processes than the intended principal boundary requires.

The documentation should continue to distinguish:

  • credential isolation — already provided by isolated mode;
  • OS/process isolation — strengthened by this issue;
  • complete hostile-workload containment — not a Passless claim.

Scope

1. Mount/filesystem isolation

Introduce a mount namespace (or equivalent kernel-enforced filesystem view) for isolated principals/browser processes.

The isolated runtime should expose only the paths required for the configured workflow, such as:

  • executable/runtime dependencies needed to launch the principal/browser;
  • the principal's ephemeral runtime directory;
  • the managed browser profile owned for that principal/session;
  • explicitly required device nodes;
  • required Unix sockets/native-messaging files;
  • a minimal /proc view as required;
  • explicit operator-configured work directories where necessary.

It must not expose by default:

  • human Passless credential/PIN storage;
  • agent audit storage;
  • daemon admin sockets;
  • other profiles' storage/runtime directories;
  • unrelated browser profiles;
  • /dev/uhid unless the architecture explicitly requires it for that principal;
  • unrelated hidraw devices;
  • arbitrary host home-directory content.

Prefer an allowlist model over trying to enumerate sensitive paths to hide.

2. Process visibility / interaction

Evaluate a PID namespace or another maintainable mechanism to reduce unnecessary visibility and signalling of unrelated host processes from isolated principals.

The first implementation does not need to force a PID namespace if it creates unacceptable Chromium/runtime complexity. However, the design must explicitly answer:

  • which host processes the principal can observe;
  • which processes it can signal/ptrace under normal kernel rules;
  • whether Yama/ptrace restrictions are relied upon;
  • whether a PID namespace materially improves the threat model;
  • how browser/process lifecycle supervision works across the boundary.

If PID namespaces are deferred, record the residual risk explicitly rather than implying they exist.

3. Runtime-path and ownership invariants

Before launch, validate every writable/exposed path used by the isolated principal:

  • expected ownership and mode;
  • no unsafe symlink traversal;
  • no overlap with human or other-profile storage;
  • no unexpected bind-mount target;
  • fail closed when the intended restricted view cannot be established.

The launcher must not silently fall back to an unrestricted host mount namespace when isolation setup fails.

4. Browser compatibility

Preserve Chromium's own sandbox rather than disabling it to make namespace setup easier.

Test at least:

  • default managed browser mode;
  • extension/native-messaging path;
  • browser-control pipe mode;
  • trusted external CDP port mode where that mode is supported for isolated profiles;
  • normal browser termination, daemon death, and orphan cleanup.

Any incompatibility that requires weakening the boundary should be an explicit configuration/trust decision, not an automatic fallback.

Design constraints

  • Do not reimplement Firejail, Flatpak, Bubblewrap, or a container runtime inside Passless.
  • Prefer small Linux primitives or delegation to an existing, well-defined isolation mechanism where appropriate.
  • Keep same-user mode out of scope: same-user intentionally shares the user's trust domain and should not pretend a namespace turns it into an isolated principal.
  • Keep policy, credential and browser-session semantics unchanged.

Validation

Add adversarial validation proving an isolated principal cannot access representative forbidden resources.

Examples:

human credential path          -> inaccessible
other isolated profile path    -> inaccessible
agent admin socket              -> inaccessible
agent audit path                -> inaccessible
unrelated browser profile       -> inaccessible
/dev/uhid (unless required)     -> inaccessible
unrelated hidraw device         -> inaccessible

Also verify explicitly allowed paths remain functional.

Where feasible, validate namespace identities from the daemon and record enough non-secret diagnostic state to explain launch failures.

Documentation

Update the isolated-mode security documentation to state exactly which OS isolation primitives are active and what they do not protect against.

Avoid ambiguous language such as simply calling the mode "sandboxed".

Suggested terminology:

  • credential-isolated profile;
  • cross-user principal boundary;
  • restricted mount/process view when enabled/available.

Acceptance criteria

  • Isolated principals run with a restricted filesystem view enforced by a mount namespace or equivalent kernel mechanism.
  • Human Passless storage, audit/admin state, and other profiles' runtime/storage are inaccessible from the isolated principal by default.
  • Isolation setup failure aborts launch rather than falling back to the unrestricted host namespace.
  • Writable/exposed paths are ownership/mode/symlink validated before launch.
  • PID/process visibility is either reduced with an explicit mechanism or documented as a consciously retained residual risk after evaluation.
  • Chromium's own sandbox remains enabled.
  • Browser/native-messaging/agent lifecycle tests pass under the restricted environment.
  • Adversarial tests attempt representative forbidden reads/device/socket accesses.
  • Documentation accurately distinguishes credential isolation, OS isolation and full hostile-workload containment.

Non-goals

  • Making same-user mode a security boundary against the local user.
  • Building a generic container or VM runtime.
  • Restricting application-level actions after successful RP login.
  • Replacing Chromium's renderer sandbox.
  • Claiming protection against host root/kernel compromise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions