Expand description
RuntimeScope — per-execution caller identity surface for the
multi-tenant work tracked in Parslee-ai/car#187.
§What this is
A small value the dispatcher attaches to each Runtime::execute_*
invocation so the runtime knows on whose behalf an
ActionProposal is being executed. The fields mirror — and are
sourced from — the proposal-context surfaces #187 phase 1 and
phase 2 already populate:
caller_id— typicallyproposal.context["a2a_caller_verified"].subjectwhen anAuthValidatorreturns anIdentity, elseproposal.context["a2a_caller"].caller_id(cooperative-peer hint).tenant_id— verified-tenant claim if present, else the cooperativea2a_caller.tenant_idhint, elseNone.claims— bag of verified token claims the dispatcher chose to forward (subject is already oncaller_id; this carries the surrounding metadata likeiss,aud,org_id, etc.).
§What this PR enforces vs. what’s deferred
This first PR of #187 phase 3 is foundation only:
-
✅
Runtime::execute_scoped/execute_scoped_with_cancelaccept a&RuntimeScopeand record it on the per-execution event log (eachActionInvokedevent carriescaller_id/tenant_idso downstream audit / log analysis sees who issued what). -
✅ The car-a2a dispatcher derives a scope from the verified
Identity(when present) and the cooperativea2a_callermetadata, and calls the scoped entry point. Default-deny activates when a non-NoAuthvalidator is configured but noIdentitysurfaces (e.g. token validated but subject missing). -
❌ Memgine queries are NOT yet scoped. Facts, skills, and working-set retrieval still hit the global graph regardless of
scope.tenant_id. Tracked as the next PR in #187 phase 3. -
❌ State keys are NOT yet namespaced.
state.get/state.setstill live in a flat KV space. Tracked separately; needs careful migration design for existing persisted state. -
❌ FFI parity is partial. WS dispatches that flow through the car-a2a bridge get scope automatically; the NAPI / PyO3
execute_proposalstandalone functions don’t accept a scope parameter yet. Adding that is one of the issue’s acceptance criteria and lands in a follow-up.
Tools and policies that want per-tenant behaviour today can still
read proposal.context["a2a_caller_verified"] directly — the
phase 1/2 surfaces remain. RuntimeScope is the structured
handle the runtime itself uses; tool handlers should keep reading
the proposal context.
Structs§
- Runtime
Scope - Per-execution identity surface (Parslee-ai/car#187 phase 3).