fix: boot_context fallback when status omits identity - #2
Conversation
Older mupot pots omit bound_agent_id/role on status self-echo. Probe boot_context in that case so operator tools stay fail-closed but usable. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f4794c881
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| and "bound_agent_id" in status_result | ||
| and "role" in status_result |
There was a problem hiding this comment.
Reject partially populated status identities
When /actions/status includes one identity field but omits the other—for example, a mismatched bound_agent_id without role—this condition enters the fallback path, where _identity_snapshot replaces the presented ID with the boot-context value; the subsequent action is then allowed instead of returning identity_mismatch. Since the compatibility case is a status response omitting both identity fields, only fall back when both are absent, or reject any conflicting field already present.
Useful? React with 👍 / 👎.
| "bound_agent_id": boot_result.get("bound_agent_id"), | ||
| # Org-role layer for agent-bound tokens is always member; capability | ||
| # grants remain the real authorization surface. | ||
| "role": boot_result.get("role") or "member", |
There was a problem hiding this comment.
Do not synthesize a member role from missing boot data
When the compatibility status response omits role and /actions/boot_context also lacks it, this fallback manufactures "member", so a bound owner/admin identity whose capability list does not itself contain an admin or owner entry passes _validate_identity. Role and capability grants are independent—the existing exact-role test covers an elevated role with an ordinary capability—so a missing boot role must remain unverifiable rather than satisfying the member-only gate.
Useful? React with 👍 / 👎.
| "tenant": boot_result.get("tenant", merged.get("tenant")), | ||
| "member_id": boot_result.get("member_id", merged.get("member_id")), | ||
| "channel": boot_result.get("channel", merged.get("channel")), | ||
| "capabilities": boot_result.get("capabilities", merged.get("capabilities")), |
There was a problem hiding this comment.
Preserve security fields from the status response
In the intended fallback case where status omits only the identity fields, these assignments still replace its already-present tenant and capabilities with boot-context values. If status reports a tenant mismatch or an owner/admin grant but boot context returns the configured tenant or a less-privileged list, _validate_identity sees only the replacement and permits the action; preserve the status values or reject conflicting snapshots, using boot context solely to fill the missing identity data.
Useful? React with 👍 / 👎.
Summary
/actions/statusomitsbound_agent_id/role(older pot self-echo), operator identity probe merges/actions/boot_contextinstead of failing closed asidentity_mismatch.Test plan
./scripts/test.shclient.status()ok with bound kayhermes id after fallbackMade with Cursor