Session guard protocol
Source candidate for S18a Session-bound worker credentials and S18b fan-out
guards (maia.session-guard/v1). The Node enforces both; this scope declares
the roles, the limits, their typed errors and the Project guard operations.
Operations
| Method | Kind | Exposure | Receipt | MCP tool |
|---|---|---|---|---|
project.guard.show | read | unsupported | no | project_guard_show |
project.guard.preview | read | human-only | no | none |
project.guard.confirm | mutation | human-only | yes | none |
preview shows the current guard and the proposed four limits at the exact
expectedRevision (0 for a Project that never set them) and issues a
one-time proof bound to the inputDigest of that exact change for 30
seconds. confirm repeats the change with both and replaces the limits;
a retry with the same command and input replays the first receipt. Only a
person changes guards: neither operation has an MCP tool or a Session role.
Limits
| Limit | Default | Bounds | Error code when it trips |
|---|---|---|---|
maxDepth | 1 | 1–4 | guard_depth_exceeded |
maxLiveChildren | 8 | 1–64 | guard_live_children_exceeded |
maxMessagesPerMinute | 60 | 1–600 | guard_messages_per_minute_exceeded |
maxLeasesPerSession | 8 | 1–64 | guard_leases_per_session_exceeded |
A Session an operator creates has depth 1; a child has its parent's depth
plus one. With the default maxDepth of 1 no Session creates children.
Approval grants
The guard also records what a coordinator may do with the pending approvals of
the Project's Sessions (D-199). A person sets it with the limits, in the same
preview and confirm; a change that names no grant leaves it as it is. The
preview shows the grant the confirmation would leave, and the inputDigest
binds it. A guard receipt written before the grant existed replays as none.
| Grant | Values | Default |
|---|---|---|
coordinator | none, answer, decide | none |
answer allows answering questions; decide also approves and denies. The
default is the behaviour before the grant existed. An orchestrator has no
grant: it stays at D-186. The grant is read in one place, the Node's
approval.respond for the coordinator principal, at the commit of the answer.
Session credentials and roles
An executor Session gets its own 32-byte credential at launch, in
MAIA_SESSION_CREDENTIAL (base64url), with the Node's loopback origin in
MAIA_NODE_ORIGIN. It authenticates as
Authorization: Maia-Session <credential>, never with the operator's bearer.
SESSION_ROLE_OPERATIONS lists what each role reaches:
worker:node.status,context.show, its ownport.lease.*,session.listfor its Project and its own mailbox (session.message.send,session.inbox.check,session.inbox.ack);orchestrator: the worker operations,project.guard.showfor its own Project,session.createof children in its own Workspace, andsession.show,session.start,session.stop,turn.sendandturn.showfor its own child Sessions.
Any other operation fails with role_denied. session.create takes an
optional role (default worker), and context.show reports the role of
a Session credential.
Imported from Maia OS docs at a2175bb