Status: implemented on main for the verified external-library worker path.
This page documents how RBE treats capability declarations from published library packages. It complements library-host-web-build.md and the package/install contracts in library-system.md.
A package is not limited to the SDK surface
An RBE package is free to implement its own APIs, services, internal backend, queues, adapters, provider integrations, protocols, caches, and other package-specific behavior.
The SDK is the bridge into RBE-owned privileged resources. It is not an allowlist of everything a package is allowed to create internally.
For example, a mail package may internally define concepts such as:
Those names do not automatically become RBE host privileges and they do not prevent the package worker from starting. They may be entirely private implementation details.
The security boundary begins when package code asks RBE to do privileged work on its behalf, such as network access, storage, router mutation, or another trusted host operation.
Requests are not grants
A package manifest may request runtime capabilities, but the manifest does not grant them by itself.
A package therefore cannot gain RBE authority merely by adding another capability name to its manifest. Backend remains the grant authority.
Unknown, package-specific, or currently unavailable capability names are not promoted into RBE host grants. They also do not make the whole package invalid; package code can inspect the accepted host session and choose its own fallback behavior.
Current host-owned privileges
log is an implicit host-owned capability for every verified package. RBE fixes its target to:
Child logger scopes remain structured data below that target, for example:
A package cannot retarget logging to another package identity.
net:http is an explicit verified runtime request mapped into an RBE host grant. It is dispatched through RBE's hardened public-HTTP broker rather than giving package code a raw socket or unrestricted host network handle.
net:dns is also an explicit verified runtime request. Approved package workers may request only the bounded lookup, ip, and mx operations through RBE's DNS broker. The broker normalizes names, rejects local-only/single-label/private targets, and never gives the package a raw resolver or socket. The trusted Backend dispatcher accepts the call only when the retained Library Host session contains the matching net:dns grant.
net:tcp is an explicit verified runtime request for packages that need a stateful public TCP conversation, such as a future self-hosted SMTP adapter. The package never receives a host TcpStream or raw socket object. Backend keeps the connection and returns an opaque tcp:<random> handle that is bound to the accepted package and its session-scoped capability identity.
The current net:tcp broker admits only these operations:
Its current hard bounds are:
TCP destinations must be publicly routable. RBE rejects loopback, private, link-local, multicast, unspecified, CGNAT, documentation/special-purpose ranges, single-label names, localhost, and .local names. DNS names are resolved by trusted Backend code and the resolved set is rejected if any address is non-public. Handles cannot be used by another package/session, and all retained TCP handles are discarded when the verified Library Host sessions are rebuilt.
net:tcp does not currently imply TLS or STARTTLS. TLS upgrade is a separate trusted-host capability step because certificate validation and server-name verification must stay inside RBE rather than being delegated to package code.
Other package-defined capabilities remain package-owned unless and until RBE deliberately implements a privileged host surface for them.
Project-local approval commands
Explicit host privileges are approved per project. RBE stores the approval state at:
The file is project-local and is not a machine-wide permission database.
Inspect the exact verified package requests and current approvals with:
Approve the explicit RBE host privileges needed by the package:
The approval command replaces the explicit host privilege set for that package. Passing no capabilities revokes all explicit privileges:
log never appears in the explicit approval file because it is implicit, package-scoped, and host-owned.
Each approval is bound to all three of these identities:
A package upgrade, artifact replacement, or project-lock change therefore invalidates the old approval automatically. Backend also re-opens the SHA-pinned package artifact and verifies that every approved capability is still requested by the package before constructing the Library Host session.
For a package such as mail, a normal authoring flow is therefore:
A future GUI/Studio permission prompt should call the same verified approval model instead of maintaining a separate permission database.
Capability evidence is not worker identity
RBE deliberately keeps capability evidence out of VerifiedPackageWorkerIdentity.
The worker identity is reserved for the executable identity that must remain stable across the launch chain, including package/version, artifact identity, ABI, SDK/runtime identity, and worker entry information.
Capability requests are recovered separately when RBE needs them. This avoids accidentally treating a previously copied capability list as permanent authority.
Re-read from the SHA-pinned artifact
VerifiedPackageWorkerIdentity::read_requested_capabilities(...) re-opens the package through the active project cache/lock state before returning capability requests.
The fail-closed sequence is:
If the artifact, manifest, resolved runtime/SDK, package version, or reconstructed worker identity has drifted, RBE fails instead of returning capability evidence from that package.
Backend performs this re-read while constructing the retained Library Host session. It then maps only the supported RBE-owned requests that also have an active project-local approval into grants.
Cache location is never authority
The existence of:
is not sufficient evidence by itself. RBE re-hashes the artifact and rejects unsafe/symlinked cache entries before inspecting capability requests.
This follows the general RBE rule that caches are reconstructible state and become trustworthy only after their pinned identities are verified at the boundary that consumes them.
Disabled capabilities
Only manifest capability entries whose value is enabled are returned as requests. Disabled entries are not converted into requests.
The resulting strings still remain requests, not host grants.
Privilege disclosure UX
Installer/UI permission text should describe RBE privileges, not package architecture.
A package having an internal backend, queue, worker, or provider adapter is not itself a permission and does not need to be exposed as implementation trivia. A user-facing disclosure should instead describe meaningful authority such as:
- network access;
- persistent storage;
- route registration or mutation;
- other advanced RBE host access.
This keeps the permission model simple without hiding actual RBE authority. CLI and future GUI/Studio installers should derive the disclosure from the same verified package capability evidence used by Backend, rather than trusting package-written prose.
Library Host boundary
The complete authority split is:
Capability request evidence must never be used to bypass the sealed worker proof, Library Host session identity, Container sandbox, or later library.hello / library.accept validation.
Why the evidence is re-read
The separation protects against two classes of mistakes:
- stale copied authority — a capability list captured earlier is not silently treated as valid forever;
- identity/evidence confusion — adding or removing a requested capability does not redefine the executable identity object or turn a request into a grant.
When RBE needs capability evidence, it proves the current SHA-pinned package and reconstructed worker identity first, then reads the current verified manifest requests and applies only the still-valid project-local approvals.