nucleus-core-ts 0.9.718 → 0.9.719
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.
|
@@ -95,8 +95,15 @@ function matchesGlob(path, patterns) {
|
|
|
95
95
|
reason: 'godmin',
|
|
96
96
|
action
|
|
97
97
|
};
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
// A ClaimGuard's `invalidates` entries are PREFIX-aware, mirroring how claim grants work
|
|
99
|
+
// (and how firedGuards naming below matches): suppressing `llm` (or `llm.prediction`) removes
|
|
100
|
+
// every claim AT or UNDER it. This lets a guard invalidate a whole capability with one short
|
|
101
|
+
// prefix instead of enumerating each discovered leaf — an exact leaf is just the zero-descendant
|
|
102
|
+
// case. (Without this, an operator/AI-proposed `invalidates:["llm"]` would silently no-op, since
|
|
103
|
+
// discovered claims are leaves and none equals the bare prefix.)
|
|
104
|
+
const suppressed = suppressedClaims && suppressedClaims.length ? suppressedClaims : null;
|
|
105
|
+
const isSuppressed = (c)=>!!suppressed && suppressed.some((s)=>c === s || c.startsWith(`${s}.`));
|
|
106
|
+
const effectiveClaims = suppressed ? claims.filter((c)=>!isSuppressed(c)) : claims;
|
|
100
107
|
if (claimSatisfies(effectiveClaims, action)) return {
|
|
101
108
|
decision: 'allow',
|
|
102
109
|
reason: 'claim',
|
|
@@ -249,6 +249,34 @@ describe('evaluateAccess', ()=>{
|
|
|
249
249
|
reason: 'claim'
|
|
250
250
|
});
|
|
251
251
|
});
|
|
252
|
+
it('suppresses by PREFIX — invalidating "agent" removes every agent.* leaf', ()=>{
|
|
253
|
+
// A guard whose invalidates is a short prefix must suppress the leaf the user actually
|
|
254
|
+
// holds (discovered claims are leaves). Regression: exact-only subtraction would ALLOW.
|
|
255
|
+
const d = evaluateAccess({
|
|
256
|
+
...base,
|
|
257
|
+
method: 'GET',
|
|
258
|
+
path: '/api/v1/templates',
|
|
259
|
+
claims: [
|
|
260
|
+
'agent.templates.list'
|
|
261
|
+
],
|
|
262
|
+
suppressedClaims: [
|
|
263
|
+
'agent'
|
|
264
|
+
],
|
|
265
|
+
firedGuards: [
|
|
266
|
+
{
|
|
267
|
+
action: 'maintenance_mode',
|
|
268
|
+
invalidates: [
|
|
269
|
+
'agent'
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
expect(d).toMatchObject({
|
|
275
|
+
decision: 'deny',
|
|
276
|
+
reason: 'claim_guard',
|
|
277
|
+
guard: 'maintenance_mode'
|
|
278
|
+
});
|
|
279
|
+
});
|
|
252
280
|
it('suppression never elevates godmin denial (godmin bypasses by role)', ()=>{
|
|
253
281
|
const d = evaluateAccess({
|
|
254
282
|
...base,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nucleus-core-ts",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.719",
|
|
4
4
|
"description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
|
|
5
5
|
"author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|