Repository navigation
fix(console): skip the native admin probe for a caller without agent administer - #3622
Conversation
…administer The Agent page asked GET .../native-admin for every caller. A caller without Agent administer got a browser console error and an audited denial for each Agent, once per tab (review of #3600, nit 6). GET agents/{id}/permissions now also answers administer: the Agent administer decision the native admin endpoint makes on the exact Agent, with no audit row or side effect. The native admin card waits for that answer and does not ask when it is false. A failed read keeps today's probe and its once-per-tab denial memory.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs changes before merge. What this changesThis PR adds an advisory Agent administer permission and skips the native-admin probe when that permission is denied. Example: A Namespace member can read an Agent but cannot administer it.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Needs changes before merge - 1 item remains Keep open: this maintainer-authored PR addresses unnecessary authorization denials with a focused change; its runtime flow documentation needs updating. Priority: P2 Before merge
Findings
Tests
Agent review detailsHow this fits togetherThe Console reads advisory permissions from the controller's selected IAM Driver before requesting native-admin availability; actual native-admin requests retain independent server authorization. flowchart TD
Console[Agent detail Console] --> Permissions[Caller permissions endpoint]
Permissions --> IAM[Selected IAM Driver]
IAM --> Hint[Advisory administer answer]
Hint --> Gate[Native admin card]
Gate --> Native[Authorized native-admin endpoint]
Technical reviewBest possible solution: Keep the existing advisory permission owner and server authorization, and document the new permission-gated probe in the native-admin flow. Do we have a high-confidence way to reproduce the issue? Current main unconditionally probes native-admin status, whose real server path requires exact-Agent administer; a reader without that permission therefore reaches the reported 403 path. Is this the best way to solve the issue? The patch uses the existing permission-summary owner and preserves unknown-answer fallback, remembered denials, refresh coalescing, and server authorization; no introduced runtime defect was established. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 9892abfb1471. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceAcceptance criteria:
What I checked:
Likely related people:
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 25, 2026, 7:36 AM ET / 11:36 UTC. |
…; storybook scenario gains administer
Problem
The Agent page asks
GET /namespaces/{namespaceId}/agents/{agentId}/native-adminfor every caller. The endpoint requires Agentadminister. So every viewer without it gets a browser console error and an auditedopenclaw.agents.native_admin.readdenial for each Agent, once per tab. This was nit 6 in the internal review of #3600, and it stayed open.Change
GET .../agents/{agentId}/permissionsalso answersadminister. This is the Agentadministerdecision that the native admin endpoints make on the exact Agent (getAdministerableAgent). Like the other bits, it uses the samecallerMaypath, writes no audit row and has no side effect. It is additive. Contracts, OpenAPI anddocs/reference/api.mdare regenerated./native-admin, which costs them a 403 and costs the Installation an audit row. So the bit reveals nothing new. Native admin UI also needs a signed-in console session. That condition is listed in the field description, not folded into the bit, because the bit reports only the IAM action, like the others.administerisfalse, the card does not ask and stays hidden, as it does after a denial today. If the read fails or the bit is missing, the card asks as before and still remembers the denial once per tab.credentialsSourcesOperateDeniedscenario that fix(console): disable agent-side saves when an agent update would be refused for a bound source #3618 added.docs/flows/agent-native-admin.md: the flow and its console step now show that the console reads native admin status only when theadministeranswer allows it or is unknown. To stay under the 2,500-word limit, two repeated sentences and one Debugging bullet that restated step 7 were shortened.Verification
tests/integration/console-api.test.mjs, new test: a member with every other Agent action (read, update, deploy, operate, delete) getsadminister: false, and the answer writes no audit row. The real/native-adminGET is then refused with 403 and audited. After anadministergrant, the answer istrueand the GET returns 200. Mutants killed: each other action in place ofadminister(read, update, deploy, operate, delete), and a Namespace or Configuration target.tests/browser/console-agent-detail-2.test.mjs, new test: a viewer getsadminister: false. Across two views of the page the card makes no/native-adminrequest and no denial is audited. With the console change reverted (the server bit kept), the test fails: 1 request. The existing once-per-tab test now runs with the permission answer withheld (a failed read), so the fallback path keeps its coverage. Both tests passed 20/20 at 2 CPUs on a remote test VM.console-agent-detail.test.mjs,console-agent-detail-2.test.mjsandconsole-agent-overview.test.mjsall pass (191 tests).tsc --build, eslint and prettier pass on the touched files.docs/reference/api.mdandocc-api.openapi.jsonwere regenerated withnode scripts/generate-occ-openapi.mjs;--checkis clean. On the merged head,tests/integration/console-api.test.mjspasses locally (13 tests), andconsole-agent-detail.test.mjs,console-agent-detail-2.test.mjsandconsole-agent-logs.test.tspass on a remote test VM (177 tests).tscpasses.Risks
administer, the native admin status read now starts after the permission answer instead of in parallel with it. The first reveal waits for both, so the page can show one round trip later. It still has the existing 2 s reveal cap.