Skip to content

feat(server): allocate allowances from HostAdmin without a forged frame - #467

Open
filvecchiato wants to merge 6 commits into
mainfrom
rfc/host-allowance-admin
Open

feat(server): allocate allowances from HostAdmin without a forged frame#467
filvecchiato wants to merge 6 commits into
mainfrom
rfc/host-allowance-admin

Conversation

@filvecchiato

@filvecchiato filvecchiato commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

HostAdmin::allocate_allowances(resources, origin) allocates product-scoped
resources on the host's own initiative — startup warm-up, foreground re-check,
recovery after a rejection. It calls ProductAuthority::allocate_resources
directly and does not raise the product-facing ResourceAllocation confirmation
review, whose contract is "a product asked for this": no product is asking.
HostAllowanceOrigin (StartupReadiness, ForegroundRenewal, Recovery)
records which lifecycle moment did, so a host prompting policy can be added later
without touching a signature.

RFC-0010 made allowance "entirely the Host's concern", but only the
product-facing half landed. HostAdmin carries no allowance operation, so a host
administering its own allowances has to reach the implementation by impersonating
a product: synthesize a ProtocolMessage, push it through a short-lived product
endpoint, capture the response frame. That forged frame then arrives as an
ordinary UserConfirmationReview::ResourceAllocation, so the host cannot tell the
runtime "this one is mine" and instead arms an out-of-band token keyed by
(product_id, resource) that its own consent delegate silently approves. A
genuine product request for the same product and resource, landing while a host
dispatch is armed, consumes that token and is approved without asking the user.
Only the runtime knows which call it originated, so only the runtime can close
that window.

No wire-protocol change and no new generated method.

Not included

allowance_status and invalidate_allowance are the obvious companions and are
left out on purpose: they mean different things in the two roles. PairingHost
caches keys received over SSO, where presence and eviction are well defined and
the primitives already exist as pub(super) (evict_bulletin_allowance_key,
clear_*_allowance_keys). SigningHost is the Account Holder and provisions on
demand via OnExistingAllowancePolicy::Ignore, so cache presence is the wrong
question and an on-chain slot probe is the meaningful one. That wants agreement
before code.

Native bindings are also out of scope here — a separately CI-gated step with
committed bindings. Renewal already reaches the FFI via #308, so allocation and
status remaining Rust-only is a known asymmetry to close next.

Allocation alone retires both the forged frame and the auto-confirm registry,
which is the half with a security consequence.

Tests

cargo +nightly fmt --check, cargo clippy --workspace --all-targets --all-features -- -D warnings and cargo test --workspace are clean.

Three new tests: no-session rejection, correlation-id uniqueness (the SSO channel
matches responses on it, so concurrent host allocations must not collide), and
that the host path raises no confirmation review. The last asserts the product
path raises exactly one review against the same platform first, so it cannot pass
vacuously.

RFC-0028. HostAdmin::allocate_allowances reaches
ProductAuthority::allocate_resources directly and does not raise the
product-facing ResourceAllocation confirmation review, since no product is
asking. Hosts previously had to synthesize a ProtocolMessage through a
short-lived product endpoint and suppress the resulting prompt with an
out-of-band token keyed by (product_id, resource), which could match and
silently approve a concurrent real product request.

Status and invalidate are specified in the RFC but not implemented here:
their semantics differ between the pairing and signing roles and need
agreement first.
@filvecchiato
filvecchiato requested review from a team August 20, 2026 14:50
The check-rfc gate requires every docs/rfcs/ change to carry a matching
rust/crates/truapi/ change. This surface is host-side and adds no
product-facing protocol method, and the crate invariants keep host-side
runtime types out of truapi, so it cannot satisfy that gate.
@filvecchiato filvecchiato changed the title RFC 0028: Host allowance administration feat(server): allocate allowances from HostAdmin without a forged frame Aug 20, 2026
The HostAdmin change stands on its own; the crate README documents it.
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.

1 participant