Skip to content

control: process-wide switch to disable registration - #333

Merged
congwang-mk merged 5 commits into
mainfrom
control-disable-registration
Oct 30, 2026
Merged

congwang-mk merged 5 commits into
mainfrom
control-disable-registration

Conversation

@congwang-mk

Copy link
Copy Markdown
Contributor

Closes #317.

Why

Every sandbox claims its name in the per-user SysV registry and binds an abstract control socket, even in embedders that never use sandlock ps. Each spawn takes a UID-wide registry lock, and any process of the same user can list the embedder's sandboxes, read their effective policy through the config verb, and kill them. Whether to register is the host program's call and the same for every sandbox it runs, so this is a process-wide switch rather than a policy field (the per-sandbox knob was removed in 9c1981b).

What

  • core: sandlock_core::control::disable_registration(). Every later spawn skips the name claim, the control socket and the control loop. .name() still sets the virtual hostname; Controller and pidfd-based control are unaffected. The switch is one-way, so a process never ends up half registered by accident, and the best-effort fallback for a failed bind is unchanged.
  • ffi: sandlock_disable_registration(), header regenerated.
  • python: sandlock.disable_registration(). go: DisableRegistration().
  • docs: architecture, CLI and SDK READMEs note what an embedder gives up: ps, kill by name, and UID-wide name uniqueness.

The CLI is unchanged and stays registered. A --unregistered flag would be consistent with the scoping (one CLI invocation is one process) and can follow if someone needs it.

Tests

Because the switch is process-wide, each test runs in its own process:

  • Rust: separate test binary crates/sandlock-core/tests/registration_disabled.rs.
  • Python: python/tests/test_registration.py runs in a child interpreter.
  • Go: TestDisableRegistrationFreesNames re-executes the test binary.

Each starts a long-running sandbox and a second one with the same name, which fails with "already running" when registration is on. The Rust test also checks the name is absent from list_sandboxes(). The Rust and Go tests were confirmed to fail without the call. Existing test_control integration tests: 34 passed.

🤖 Generated with Claude Code

@congwang-mk
congwang-mk force-pushed the control-disable-registration branch from 5debf42 to 7642cc9 Compare October 30, 2026 04:09
Add registration(false) on SandboxBuilder to configure individual
sandbox instances. Unregistered instances skip the name claim, control socket,
and control loop without changing other sandboxes in the same process.
Names still set the virtual hostname, and direct lifecycle control works.

Registration defaults to enabled, including through clap, and stays out
of serialized policy. Clones retain the instance setting. Tests cover
mixed registration with and without a supervisor, duplicate names,
cloning, policy deserialization, and the clap default.

Refs #317.

Signed-off-by: Cong Wang <cwang@multikernel.io>
Add sandlock_sandbox_builder_registration so C callers and SDK bindings
can disable registration for individual sandbox instances. Regenerate
the C header for the builder setter.

Refs #317.

Signed-off-by: Cong Wang <cwang@multikernel.io>
Expose Sandbox(registration=False) as a runtime setting and forward it
to the native builder. Registration remains enabled by default.

Test that registered and unregistered sandboxes coexist in one process,
with duplicate-name checks retained for registered instances.

Refs #317.

Signed-off-by: Cong Wang <cwang@multikernel.io>
Add Sandbox.DisableRegistration and forward it to the native builder.
The zero value keeps registration enabled. Exclude the runtime setting
from JSON serialization.

Test registered and unregistered sandboxes in one process, including
name reuse and registered-instance collision checks.

Refs #317.

Signed-off-by: Cong Wang <cwang@multikernel.io>
Document the Rust, C, Python, and Go instance settings, their enabled
default, and their exclusion from serialized policy. Explain that
unregistered instances give up discovery, control by name, and UID-wide
name reservation while retaining virtual hostnames and direct control.

Closes #317.

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk
congwang-mk force-pushed the control-disable-registration branch from 7642cc9 to f1e2148 Compare October 30, 2026 04:12
@congwang-mk
congwang-mk merged commit 8c69af7 into main Oct 30, 2026
25 checks passed
@congwang-mk
congwang-mk deleted the control-disable-registration branch October 30, 2026 15:59
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.

control: process-wide switch to disable the control socket and name registry

1 participant