Extend and embed
Sandbox Policy adapter
Map canonical MIR into Executor plans without sharing private representations or weakening capabilities.The two plan types intentionally describe different stages and therefore have different names in Executor ABI 9:
canonical MIR + trusted HostContext
|
v
maelys_sandbox_policy_plan_t
resolved policy decision
|
Warden Policy adapter
|
v
maelys_executor_plan_t
mechanical launch contract
|
backend prepare/spawnlibmaelys-sandbox-policy owns maelys_sandbox_policy_plan_t. It resolves symbolic MIR
roots and carries the MIR digest and trusted mediator identifier.
libmaelys-executor owns maelys_executor_plan_t. It adds backend-facing
mount vocabulary, exact missing-path behaviour and the capability set used for
selection. Neither representation is cast, aliased or passed to the other's
functions.
The optional libmaelys-warden-policy-adapter is the only component that
includes both public headers. It copies every resolved rule and seals a new
Executor plan. The source plan remains owned by its caller.
The adapter copies the canonical MIR digest into Executor's generic
decision_digest; the Executor plan digest then binds this source identity to
the mechanical rules, and both digests are available in execution receipts.
The current adapter resolves workspace, temp and minimal-runtime against
the local host and is therefore the product path for local Seatbelt or
Bubblewrap targets. It is not an OCI guest-path compiler. Apple Container
integrators must construct a trusted Executor plan whose mount destinations
and recursive filesystem rules refer to the intended guest paths; Warden must
not reinterpret a host-resolved rule as guest authority silently.
Network mapping
| maelys-sandbox-policy decision | Executor plan | Current status |
|---|---|---|
NONE | NETWORK_NONE | enforced only by a backend claiming strong denial |
DIRECT | NETWORK_INHERIT | supported |
MEDIATED + maelys-egress/fd4-v1 | NETWORK_EXTERNAL_CHANNEL + copied destinations | fd4 broker → Egress native connector |
MEDIATED + maelys-egress/proxy-v1 | NETWORK_MEDIATED_PROXY + copied destinations | Egress adapter + Bubblewrap relay or exact Seatbelt loopback endpoint |
NETWORK_IP_NONE has no portable maelys-sandbox-policy equivalent. Bubblewrap
satisfies MIR NONE only when both its network namespace and native seccomp
socket denial were proven by the backend probe; the namespace-only capability
remains distinct.
The capability converter advertises NETWORK_MEDIATED when the selected
backend claims either exact mediated frontend. The adapter copies every canonical
TCP hostname/port destination and the source MIR digest into the Executor plan.
It requires the trusted HostContext mediator identifier to equal
MAELYS_WARDEN_POLICY_FD4_MEDIATOR_ID or
MAELYS_WARDEN_POLICY_EGRESS_MEDIATOR_ID; an arbitrary mediator name is never
silently discarded or rebound. This explicit split is adapter ABI 4. Both
frontends terminate in Egress; the split is client compatibility, not separate
enforcement.
Root mapping
Sandbox Policy ABI 4 carries the MIR v3 root disposition into its opaque
SandboxPlan. The adapter maps READ_ONLY to an Executor readonly root and
EPHEMERAL_WRITE to MAELYS_EXECUTOR_ROOT_EPHEMERAL_WRITE, which requires the
ABI 9 capability bit. Scratch size is deliberately absent from MIR and
SandboxPlan: the trusted RunSpec and execution request must agree on that
deployment/resource ceiling exactly.
Process-tree mapping
MIR process_tree_required means confinement-policy inheritance by descendants
and maps to MAELYS_BACKEND_CAP_PROCESS_CONFINEMENT. It does not set Executor's
process_tree_required flag, which deliberately means the stronger lifecycle
promise that wait/stop covers an adversarial descendant tree, including a
descendant that creates a new session.
Capability handshake
The trusted registry should:
- query the selected backend with
maelys_executor_backend_capabilities(executor, name, ...); - convert that exact mask with
maelys_warden_policy_capabilities_from_executor(...); - pass the result to
maelys_sandbox_policy_compile; - lower the returned plan with
maelys_warden_plan_from_sandbox_policy; - set the same backend name on the execution request before spawn.
Using the same name in steps 1 and 5 prevents a capability check against one
backend followed by enforcement through another. POSIX maps to no portable
sandbox capabilities. Seatbelt currently maps READ/WRITE, direct/none network,
both mediated frontends and descendant policy inheritance. Bubblewrap maps
portable recursive-directory and literal-file READ/WRITE rules to pinned
--ro-bind/--bind operations.
Explicit DENY is lowered to a final mode-000 read-only mount overlay. Literal
directory rules and create-protection for absent paths remain rejected because
Bubblewrap mounts cannot represent those narrower vnode semantics exactly.
Build
With sibling checkouts:
make warden-policy-adapter-check MAELYS_SANDBOX_POLICY_DIR=../maelys-sandbox-policyThis test compiles and links both static libraries in one executable, proving that their public and internal symbols no longer collide.