@checkstack/backend-api 0.21.4 → 0.21.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/package.json +8 -8
- package/src/plugin-system.ts +6 -0
- package/src/rpc.test.ts +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @checkstack/backend-api
|
|
2
2
|
|
|
3
|
+
## 0.21.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0626782: Guard the role editor against granting inert (and misleading) permissions to the
|
|
8
|
+
anonymous role.
|
|
9
|
+
|
|
10
|
+
RPC procedures carry two independent axes: `userType` (the hard authentication
|
|
11
|
+
gate) and `access` rules (authorization). An admin can grant the anonymous role
|
|
12
|
+
any access rule, but if the procedures needing that rule are `userType:
|
|
13
|
+
"authenticated"`/`"user"`, the grant does nothing - the auth middleware rejects
|
|
14
|
+
unauthenticated callers BEFORE access rules are checked (so there is no security
|
|
15
|
+
hole; the grant is simply inert). After anonymous users started seeing
|
|
16
|
+
permission-gated UI, such a grant would surface as visible-but-broken controls.
|
|
17
|
+
|
|
18
|
+
- The backend now computes, from contract metadata, the access rules an anonymous
|
|
19
|
+
caller can actually use (a rule is "usable" iff at least one `public` procedure
|
|
20
|
+
requires it) via `pluginManager.getAnonymousUsableAccessRuleIds()`, exposed to
|
|
21
|
+
plugins through the plugin environment.
|
|
22
|
+
- `auth.getAccessRules` annotates each rule with `anonymousUsable`.
|
|
23
|
+
- `auth.updateRole` REFUSES to ADD a non-usable rule to the anonymous role
|
|
24
|
+
(existing grants are untouched, so no configuration can be wedged). This is a
|
|
25
|
+
guardrail, not an enforcement change - RPC authorization is unchanged.
|
|
26
|
+
- The role editor disables non-usable rules (with an explanation) when editing
|
|
27
|
+
the anonymous role.
|
|
28
|
+
|
|
29
|
+
Verified live: `getAccessRules` reports 11 anonymous-usable vs 58 not; granting
|
|
30
|
+
`incident.incident.manage` to the anonymous role returns HTTP 400 with a clear
|
|
31
|
+
message.
|
|
32
|
+
|
|
33
|
+
- Updated dependencies [56e7c75]
|
|
34
|
+
- @checkstack/common@0.15.0
|
|
35
|
+
- @checkstack/healthcheck-common@1.5.4
|
|
36
|
+
- @checkstack/cache-api@0.3.12
|
|
37
|
+
- @checkstack/queue-api@0.3.12
|
|
38
|
+
- @checkstack/signal-common@0.2.9
|
|
39
|
+
- @checkstack/template-engine@0.4.3
|
|
40
|
+
|
|
3
41
|
## 0.21.4
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/backend-api",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.5",
|
|
4
4
|
"license": "Elastic-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
"lint:code": "eslint . --max-warnings 0"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@checkstack/cache-api": "0.3.
|
|
14
|
-
"@checkstack/common": "0.
|
|
15
|
-
"@checkstack/healthcheck-common": "1.5.
|
|
16
|
-
"@checkstack/queue-api": "0.3.
|
|
17
|
-
"@checkstack/signal-common": "0.2.
|
|
18
|
-
"@checkstack/template-engine": "0.4.
|
|
13
|
+
"@checkstack/cache-api": "0.3.12",
|
|
14
|
+
"@checkstack/common": "0.15.0",
|
|
15
|
+
"@checkstack/healthcheck-common": "1.5.4",
|
|
16
|
+
"@checkstack/queue-api": "0.3.12",
|
|
17
|
+
"@checkstack/signal-common": "0.2.9",
|
|
18
|
+
"@checkstack/template-engine": "0.4.3",
|
|
19
19
|
"@orpc/client": "^1.14.4",
|
|
20
20
|
"@orpc/contract": "^1.14.4",
|
|
21
21
|
"@orpc/openapi": "^1.14.4",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"zod": "^4.2.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@checkstack/scripts": "0.6.
|
|
30
|
+
"@checkstack/scripts": "0.6.1",
|
|
31
31
|
"@checkstack/tsconfig": "0.0.7",
|
|
32
32
|
"@types/bun": "latest",
|
|
33
33
|
"@types/pg": "^8.20.0",
|
package/src/plugin-system.ts
CHANGED
|
@@ -139,6 +139,12 @@ export type BackendPluginRegistry = {
|
|
|
139
139
|
) => void;
|
|
140
140
|
pluginManager: {
|
|
141
141
|
getAllAccessRules: () => { id: string; description?: string }[];
|
|
142
|
+
/**
|
|
143
|
+
* Qualified ids of access rules an anonymous caller can actually use (rules
|
|
144
|
+
* required by at least one `public` procedure). Used to guard the role
|
|
145
|
+
* editor against granting inert permissions to the anonymous role.
|
|
146
|
+
*/
|
|
147
|
+
getAnonymousUsableAccessRuleIds: () => string[];
|
|
142
148
|
};
|
|
143
149
|
};
|
|
144
150
|
|
package/src/rpc.test.ts
CHANGED
|
@@ -25,7 +25,7 @@ const testContracts = {
|
|
|
25
25
|
publicGlobalEndpoint: proc({
|
|
26
26
|
userType: "public",
|
|
27
27
|
operationType: "query",
|
|
28
|
-
access: [access("resource", "read", "Test access")],
|
|
28
|
+
access: [access("resource", "read", "Test access", { pluginId: "test" })],
|
|
29
29
|
}).output(z.object({ message: z.string() })),
|
|
30
30
|
|
|
31
31
|
// Public endpoint with list filtering
|
|
@@ -39,7 +39,7 @@ const testContracts = {
|
|
|
39
39
|
read: { description: "View systems", isPublic: true },
|
|
40
40
|
manage: { description: "Manage systems" },
|
|
41
41
|
},
|
|
42
|
-
{ listKey: "systems" },
|
|
42
|
+
{ listKey: "systems", pluginId: "test" },
|
|
43
43
|
).read,
|
|
44
44
|
],
|
|
45
45
|
}).output(
|
|
@@ -80,7 +80,7 @@ const testContracts = {
|
|
|
80
80
|
read: { description: "View systems", isPublic: true },
|
|
81
81
|
manage: { description: "Manage systems" },
|
|
82
82
|
},
|
|
83
|
-
{ idParam: "systemId" },
|
|
83
|
+
{ idParam: "systemId", pluginId: "test" },
|
|
84
84
|
).read,
|
|
85
85
|
],
|
|
86
86
|
})
|
|
@@ -95,6 +95,7 @@ const testContracts = {
|
|
|
95
95
|
access("bulk", "read", "Bulk read", {
|
|
96
96
|
recordKey: "statuses",
|
|
97
97
|
isPublic: true,
|
|
98
|
+
pluginId: "test",
|
|
98
99
|
}),
|
|
99
100
|
],
|
|
100
101
|
})
|
|
@@ -129,7 +130,7 @@ const testContracts = {
|
|
|
129
130
|
read: { description: "View systems", isPublic: true },
|
|
130
131
|
manage: { description: "Manage systems" },
|
|
131
132
|
},
|
|
132
|
-
{ idParam: "systemId" },
|
|
133
|
+
{ idParam: "systemId", pluginId: "test" },
|
|
133
134
|
).read,
|
|
134
135
|
],
|
|
135
136
|
instanceAccess: { recordKey: "statuses" },
|