initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/ binary modes, condensed snapshots, value relations) with 39 rigor test campaigns. Includes fixes for snapshot binary writer/reader format mismatch (snapshot-of-snapshot corruption), possibility write-boundary validation, empty-graph snapshot serialization, relation lookup cache direction collision, config-redefinition cache invalidation, binary threshold semantics, defeasible compiled routing, and comparator reason whitelisting.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { Arbiter } from '../../src/core/Arbiter.js';
|
||||
|
||||
export function createTestArbiter(options = {}) {
|
||||
const defaults = {
|
||||
embeddingDimensions: 256,
|
||||
directCheckCacheSize: 10000,
|
||||
directCheckCacheTTL: 60000,
|
||||
disableCaching: false,
|
||||
disableChainCaching: false,
|
||||
disableDirectCaching: false
|
||||
};
|
||||
|
||||
return new Arbiter({ ...defaults, ...options });
|
||||
}
|
||||
|
||||
export function seedBasicGraph(arbiter) {
|
||||
const nodes = [
|
||||
['user:alice', 'user'],
|
||||
['user:bob', 'user'],
|
||||
['user:charlie', 'user'],
|
||||
['doc:report', 'document'],
|
||||
['doc:invoice', 'document'],
|
||||
['project:web-app', 'project'],
|
||||
['group:engineering', 'group'],
|
||||
['group:management', 'group'],
|
||||
['account:main', 'account'],
|
||||
['session:sess-1', 'session']
|
||||
];
|
||||
|
||||
for (const [key, type] of nodes) {
|
||||
arbiter.addNode(key, type);
|
||||
}
|
||||
|
||||
const relations = [
|
||||
['user:alice', 'member_of', 'group:engineering', 1.0],
|
||||
['user:bob', 'member_of', 'group:management', 1.0],
|
||||
['group:engineering', 'can_read', 'doc:report', 0.8],
|
||||
['group:engineering', 'can_read', 'project:web-app', 0.9],
|
||||
['group:management', 'can_read', 'doc:invoice', 1.0],
|
||||
['user:alice', 'controls', 'account:main', 1.0],
|
||||
['session:sess-1', 'authenticated_as', 'user:alice', 1.0]
|
||||
];
|
||||
|
||||
for (const [src, rel, dst, possibility, metadata] of relations) {
|
||||
arbiter.addRelation(src, rel, dst, possibility, metadata);
|
||||
}
|
||||
|
||||
const relationConfigs = [
|
||||
['member_of', { type: 'direct' }],
|
||||
['can_read', { type: 'direct' }],
|
||||
['controls', { type: 'direct' }],
|
||||
['authenticated_as', { type: 'direct' }]
|
||||
];
|
||||
|
||||
for (const [rel, config] of relationConfigs) {
|
||||
arbiter.setRelationConfig(rel, config);
|
||||
}
|
||||
|
||||
return arbiter;
|
||||
}
|
||||
|
||||
export function seedRelation(arbiter, src, rel, dst, possibility = 1.0, metadata = {}) {
|
||||
arbiter.addRelation(src, rel, dst, possibility, metadata);
|
||||
if (!arbiter.relationConfigs.has(rel)) {
|
||||
arbiter.setRelationConfig(rel, { type: 'direct' });
|
||||
}
|
||||
return arbiter;
|
||||
}
|
||||
|
||||
export function createPartialGraph(nodes = [], relations = []) {
|
||||
return { nodes, relations };
|
||||
}
|
||||
|
||||
export function seedPartialRelation(arbiter, src, rel, dst, possibility = 1.0, value = undefined) {
|
||||
const relObj = { src, relation: rel, dst, possibility };
|
||||
if (value !== undefined) {
|
||||
relObj.value = value;
|
||||
}
|
||||
return { nodes: [], relations: [relObj] };
|
||||
}
|
||||
Reference in New Issue
Block a user