Status: draft Scope: Milestone 11 sandbox enforcement contract.
The boundary is between untrusted app program execution and kernel syscall effects. All app operations must flow through capability-checked runtime dispatch. Direct calls to kernel internals are forbidden for untrusted apps.
Default policy:
- deny by default
- explicit allow via manifest and install grant
- all denies must be logged
Each app package manifest must include:
- app_id
- version
- entrypoint
- requested_capabilities
- optional resource_scopes
Example requested capabilities:
- chan.use
- win.manage
- input.route
- fs.use
Resource scopes:
- domains_allowed: list of domain names
- fs_prefixes: list of allowed path prefixes
- channel_peers_allowed: list of domain pairs or wildcard policy
Installer resolves requested capabilities into granted_capabilities. Installer may deny or reduce requested scope.
Output artifact:
- signed grant record for app_id
- immutable at runtime for v0
Runtime enforces policy at instruction dispatch:
- pre-check capability token
- pre-check resource scope
- pre-check handle ownership
- call kernel wrapper only if all checks pass
On deny:
- do not call kernel
- set status denied_capability or denied_scope or denied_handle_owner
- write denial log entry
Handle properties:
- opaque integer id from kernel wrapper
- bound to owner app_id
- bound to handle kind
Rules:
- handle can be used only by owner app_id
- handle kind must match opcode family
- handle cannot be created by raw constant and treated as valid
Validation path:
- runtime checks side table before syscall
- kernel wrapper validates if handle exists in current owner context
Required capabilities:
- EMIT: input.route or domain.emit (if split later)
- CHAN_OPEN: chan.use
- CHAN_SEND: chan.use
- CHAN_RECV: chan.use
- WIN_CREATE: win.manage
- WIN_FOCUS: win.manage
- WIN_RAISE: win.manage
- WIN_SNAP: win.manage
- FS_LIST: fs.use
- FS_OPEN: fs.use
- FS_RENAME: fs.use
- FS_COPY: fs.use
- FS_MOVE: fs.use
- FS_DELETE: fs.use
- FS_RESTORE: fs.use
Control-flow/runtime ops:
- NOP/CONST/MOVE/JUMP/JUMP_IF/SLEEP_TICKS/HALT do not require kernel capabilities.
Domain scope:
- if domains_allowed defined, operation domain args must be in set
Filesystem scope:
- key/path args must match one of fs_prefixes
- delete/restore must preserve scope checks for source and destination
Channel scope:
- CHAN_OPEN peer pair must be allowed by channel_peers_allowed
Each denied instruction creates one log entry with:
- tick
- app_id
- opcode
- args_summary
- deny_reason
- required_capability
- granted_capabilities_snapshot
Deny reasons:
- denied_capability
- denied_scope
- denied_handle_owner
- invalid_handle_kind
Policy mode for v0:
- enforce (default)
- report_only (optional debug mode)
Rules:
- report_only must never be default in packaged runtime
- enforce mode required for Milestone 11 exit criteria
A compliant sandbox implementation must:
- deny by default
- enforce opcode capability mapping
- enforce handle ownership and kind checks
- enforce declared scope restrictions
- produce auditable denial logs
- provide deterministic deny behavior under replay