Skip to content

Commit b5c3788

Browse files
committed
fix(webapp): let the agent read a queue's own row, not only its metrics
Metrics authorize as a query read; paused, depth and limit live on the queue row, which is a queues read the agent's token did not carry — so a live lookup 403'd and read as a missing queue.
1 parent 7c929fe commit b5c3788

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

apps/webapp/app/services/dashboardAgent.server.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const DASHBOARD_AGENT_UAT_CAP = [
2020
"read:environments",
2121
"read:errors",
2222
"read:query",
23+
// Queue metrics ride on `read:query`, but a queue's own row — paused, depth, limit —
24+
// is a `queues` read, and without it the agent can only see the metrics window.
25+
"read:queues",
2326
];
2427

2528
// Minted fresh on every turn (the `in` proxy injects it), so the lifetime only

apps/webapp/test/dashboardAgentDelegatedScopeCeiling.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ it("still hands over the reads the cap does carry", async () => {
5858
expect(clamped.scopes).toEqual(["read:runs"]);
5959
});
6060

61+
it("can read a queue's own row, not just its metrics", async () => {
62+
// Queue metrics authorize as a `query` read, but `paused` / depth / limit live on the
63+
// queue row itself — a `queues` read. Without it the agent sees an empty window and
64+
// says the queue does not exist.
65+
const { ability } = await abilityFor(["read:query", "read:queues"]);
66+
67+
expect(ability.can("read", { type: "queues" })).toBe(true);
68+
expect(ability.can("read", { type: "query", id: "queue_metrics" })).toBe(true);
69+
});
70+
6171
it("refuses a write the cap forbids even when the user's role allows it", async () => {
6272
// The cloud path builds the ability from the user's role, not from the token's cap —
6373
// so the role alone would hand a read-only agent token a write JWT.

0 commit comments

Comments
 (0)