Files
core/tests/rules/complex-policy-composition.test.js
T

614 lines
21 KiB
JavaScript
Raw Normal View History

import { Arbiter } from '../../src/core/Arbiter.js';
import { RuleEvaluator } from '../../src/authorization/RuleEvaluator.js';
import { describe, it, beforeEach } from 'node:test';
import assert from 'node:assert/strict';
describe.skip('Complex Policy Composition - Enterprise Authorization Scenarios', () => {
let arbiter;
let ruleEvaluator;
beforeEach(() => {
arbiter = new Arbiter({ embeddingDimensions: 256 });
ruleEvaluator = new RuleEvaluator(arbiter);
// Set up comprehensive enterprise entities
setupEnterpriseEntities();
setupFinancialEntities();
setupTeamHierarchies();
setupProjectStructures();
});
function setupEnterpriseEntities() {
// Users
['alice', 'bob', 'charlie', 'diana', 'eve', 'frank', 'grace', 'henry'].forEach(name => {
arbiter.addNode(`user:${name}`, 'user');
});
// Teams and departments
['engineering', 'marketing', 'finance', 'hr', 'legal', 'executive'].forEach(dept => {
arbiter.addNode(`team:${dept}`, 'team');
arbiter.addNode(`dept:${dept}`, 'department');
});
// Roles
['ceo', 'cto', 'vp', 'director', 'manager', 'senior', 'junior', 'intern'].forEach(role => {
arbiter.addNode(`role:${role}`, 'role');
});
}
function setupFinancialEntities() {
// Financial entities
['budget:engineering', 'budget:marketing', 'budget:finance'].forEach(budget => {
arbiter.addNode(budget, 'budget');
});
// Accounts and transactions
['account:corporate', 'account:engineering', 'account:marketing'].forEach(account => {
arbiter.addNode(account, 'account');
});
// Financial thresholds
['threshold:low', 'threshold:medium', 'threshold:high', 'threshold:executive'].forEach(threshold => {
arbiter.addNode(threshold, 'threshold');
});
}
function setupTeamHierarchies() {
// Team memberships
const memberships = [
['user:alice', 'team:engineering'],
['user:bob', 'team:engineering'],
['user:charlie', 'team:marketing'],
['user:diana', 'team:finance'],
['user:eve', 'team:executive'],
['user:frank', 'team:legal'],
['user:grace', 'team:hr'],
['user:henry', 'team:engineering']
];
memberships.forEach(([user, team]) => {
arbiter.addRelation(user, 'member_of', team, {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
});
// Department relationships
const deptRelations = [
['team:engineering', 'dept:engineering'],
['team:marketing', 'dept:marketing'],
['team:finance', 'dept:finance'],
['team:executive', 'dept:executive']
];
deptRelations.forEach(([team, dept]) => {
arbiter.addRelation(team, 'belongs_to', dept, {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
});
}
function setupProjectStructures() {
// Projects
['project:alpha', 'project:beta', 'project:gamma', 'project:classified'].forEach(project => {
arbiter.addNode(project, 'project');
});
// Documents and resources
['doc:public', 'doc:internal', 'doc:confidential', 'doc:secret'].forEach(doc => {
arbiter.addNode(doc, 'document');
});
// Resources
['server:prod', 'server:staging', 'server:dev', 'database:main'].forEach(resource => {
arbiter.addNode(resource, 'resource');
});
}
describe('Enterprise Financial Authorization', () => {
it('handles complex budget approval with team hierarchy and spending limits', () => {
// Set up financial thresholds
arbiter.addRelation('threshold:low', 'amount', 'budget:engineering', {
value: 1000,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('threshold:medium', 'amount', 'budget:engineering', {
value: 5000,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('threshold:high', 'amount', 'budget:engineering', {
value: 25000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up user spending limits based on role
arbiter.addRelation('user:alice', 'spending_limit', 'threshold:medium', {
value: 5000,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:bob', 'spending_limit', 'threshold:low', {
value: 1000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up team budget
arbiter.addRelation('team:engineering', 'budget', 'budget:engineering', {
value: 100000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex authorization: user -> team -> budget -> spending limit
arbiter.setRelationConfig('can_spend', {
type: 'logical',
union: {
rules: [
{ type: 'direct' },
{
type: 'chain',
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'budget', direction: 'out' }
]
},
{
type: 'relational_comparator',
leftRelation: 'spending_limit',
rightRelation: 'amount',
operator: '>=',
decay: { factor: 0.1, maxAge: 86400000 }
}
]
}
});
// Test Alice (medium limit) trying to spend $3000
arbiter.addRelation('user:alice', 'can_spend', 'budget:engineering', {
value: 3000,
possibility: 1.0,
changed_last_at: Date.now()
});
const result = arbiter.authChecker.check('user:alice', 'can_spend', 'budget:engineering');
assert.ok(result.possibility > 0.8, `Expected high possibility for Alice's spending, got ${result.possibility}`);
assert.strictEqual(result.reason, 'logical_operator_evaluation');
});
it('handles multi-level approval with reputation and risk scoring', () => {
// Set up user reputation scores
arbiter.addRelation('user:alice', 'reputation', 'user:alice', {
value: 0.9,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:bob', 'reputation', 'user:bob', {
value: 0.6,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up risk thresholds
arbiter.addRelation('threshold:risk_low', 'risk_score', 'budget:engineering', {
value: 0.3,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('threshold:risk_high', 'risk_score', 'budget:engineering', {
value: 0.7,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex approval: reputation + risk + team membership
arbiter.setRelationConfig('can_approve', {
type: 'logical',
intersection: {
rules: [
{
type: 'chain',
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'can_approve', direction: 'out' }
]
},
{
type: 'relational_comparator',
leftRelation: 'reputation',
rightRelation: 'risk_score',
operator: '>=',
decay: { factor: 0.05, maxAge: 3600000 }
}
]
}
});
// Test approval authorization
const result = arbiter.authChecker.check('user:alice', 'can_approve', 'budget:engineering');
assert.ok(result.possibility > 0.5, `Expected reasonable possibility for approval, got ${result.possibility}`);
});
});
describe('Project Access with Security Clearance', () => {
it('handles classified project access with clearance levels and team membership', () => {
// Set up security clearances
arbiter.addRelation('user:alice', 'clearance', 'user:alice', {
value: 0.9,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:bob', 'clearance', 'user:bob', {
value: 0.4,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up project security levels
arbiter.addRelation('project:classified', 'security_level', 'project:classified', {
value: 0.8,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up team access to projects
arbiter.addRelation('team:engineering', 'can_access', 'project:classified', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex access: clearance + team membership + project security
arbiter.setRelationConfig('can_access_project', {
type: 'logical',
intersection: {
rules: [
{
type: 'chain',
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'can_access', direction: 'out' }
]
},
{
type: 'relational_comparator',
leftRelation: 'clearance',
rightRelation: 'security_level',
operator: '>=',
decay: { factor: 0.02, maxAge: 7200000 }
}
]
}
});
// Test Alice (high clearance) accessing classified project
const aliceResult = arbiter.authChecker.check('user:alice', 'can_access_project', 'project:classified');
assert.ok(aliceResult.possibility > 0.8, `Expected high possibility for Alice, got ${aliceResult.possibility}`);
// Test Bob (low clearance) accessing classified project
const bobResult = arbiter.authChecker.check('user:bob', 'can_access_project', 'project:classified');
assert.ok(bobResult.possibility < 0.5, `Expected low possibility for Bob, got ${bobResult.possibility}`);
});
it('handles document access with similarity and freshness requirements', () => {
// Set up document similarity scores
arbiter.addRelation('doc:confidential', 'similarity', 'doc:secret', {
value: 0.8,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up document freshness
arbiter.addRelation('doc:confidential', 'freshness', 'doc:confidential', {
value: 0.9,
possibility: 1.0,
changed_last_at: Date.now() - 3600000 // 1 hour ago
});
// Set up user document access
arbiter.addRelation('user:alice', 'can_read', 'doc:confidential', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex document access: similarity + freshness + direct access
arbiter.setRelationConfig('can_access_document', {
type: 'logical',
union: {
rules: [
{ type: 'direct' },
{
type: 'similarity',
threshold: 0.7,
relation: 'similarity'
},
{
type: 'relational_comparator',
leftRelation: 'freshness',
rightRelation: 'freshness',
operator: '>=',
decay: { factor: 0.1, maxAge: 1800000 }
}
]
}
});
const result = arbiter.authChecker.check('user:alice', 'can_access_document', 'doc:secret');
assert.ok(result.possibility > 0.5, `Expected reasonable possibility for document access, got ${result.possibility}`);
});
});
describe('Organizational Hierarchy with Delegation', () => {
it('handles complex delegation chains with approval workflows', () => {
// Set up organizational hierarchy
arbiter.addRelation('user:eve', 'reports_to', 'user:alice', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:alice', 'reports_to', 'user:charlie', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up delegation permissions
arbiter.addRelation('user:alice', 'can_delegate', 'user:eve', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up approval authority
arbiter.addRelation('user:charlie', 'can_approve', 'budget:engineering', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex delegation: hierarchy + delegation + approval
arbiter.setRelationConfig('can_approve_via_delegation', {
type: 'logical',
union: {
rules: [
{ type: 'direct' },
{
type: 'chain',
steps: [
{ relation: 'reports_to', direction: 'out' },
{ relation: 'can_approve', direction: 'out' }
]
},
{
type: 'chain',
steps: [
{ relation: 'can_delegate', direction: 'out' },
{ relation: 'can_approve_via_delegation', direction: 'out' }
]
}
]
}
});
// Test delegation chain: Eve -> Alice -> Charlie
const result = arbiter.authChecker.check('user:eve', 'can_approve_via_delegation', 'budget:engineering');
assert.ok(result.possibility > 0.7, `Expected high possibility for delegation chain, got ${result.possibility}`);
});
it('handles team-based resource access with multi-hop traversal', () => {
// Set up resource access through teams
arbiter.addRelation('team:engineering', 'can_access', 'server:prod', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('team:engineering', 'can_access', 'database:main', {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up cross-team access
arbiter.addRelation('team:marketing', 'can_access', 'team:engineering', {
value: 0.5,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure multi-hop access: user -> team -> team -> resource
arbiter.setRelationConfig('can_access_resource', {
type: 'multihop',
maxHops: 3,
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'can_access', direction: 'out' },
{ relation: 'can_access', direction: 'out' }
]
});
// Test direct team access
const directResult = arbiter.authChecker.check('user:alice', 'can_access_resource', 'server:prod');
assert.ok(directResult.possibility > 0.8, `Expected high possibility for direct access, got ${directResult.possibility}`);
// Test cross-team access
const crossTeamResult = arbiter.authChecker.check('user:charlie', 'can_access_resource', 'server:prod');
assert.ok(crossTeamResult.possibility > 0.4, `Expected moderate possibility for cross-team access, got ${crossTeamResult.possibility}`);
});
});
describe('Complex Value-Based Authorization', () => {
it('handles financial transactions with balance, reputation, and risk scoring', () => {
// Set up user balances
arbiter.addRelation('user:alice', 'balance', 'account:corporate', {
value: 50000,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:bob', 'balance', 'account:corporate', {
value: 5000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up transaction amounts
arbiter.addRelation('transaction:large', 'amount', 'account:corporate', {
value: 10000,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('transaction:small', 'amount', 'account:corporate', {
value: 1000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up risk scores
arbiter.addRelation('user:alice', 'risk_score', 'user:alice', {
value: 0.2,
possibility: 1.0,
changed_last_at: Date.now()
});
arbiter.addRelation('user:bob', 'risk_score', 'user:bob', {
value: 0.8,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex transaction authorization: balance + risk + amount
arbiter.setRelationConfig('can_transact', {
type: 'logical',
intersection: {
rules: [
{
type: 'relational_comparator',
leftRelation: 'balance',
rightRelation: 'amount',
operator: '>=',
decay: { factor: 0.05, maxAge: 300000 }
},
{
type: 'relational_comparator',
leftRelation: 'risk_score',
rightRelation: 'risk_score',
operator: '<=',
decay: { factor: 0.1, maxAge: 1800000 }
}
]
}
});
// Test Alice (high balance, low risk) with large transaction
const aliceResult = arbiter.authChecker.check('user:alice', 'can_transact', 'transaction:large');
assert.ok(aliceResult.possibility > 0.8, `Expected high possibility for Alice's large transaction, got ${aliceResult.possibility}`);
// Test Bob (low balance, high risk) with small transaction
const bobResult = arbiter.authChecker.check('user:bob', 'can_transact', 'transaction:small');
assert.ok(bobResult.possibility < 0.5, `Expected low possibility for Bob's transaction, got ${bobResult.possibility}`);
});
it('handles resource allocation with team budgets and individual limits', () => {
// Set up team budgets
arbiter.addRelation('team:engineering', 'budget', 'budget:engineering', {
value: 100000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up individual spending limits
arbiter.addRelation('user:alice', 'spending_limit', 'budget:engineering', {
value: 10000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Set up resource costs
arbiter.addRelation('server:prod', 'cost', 'budget:engineering', {
value: 5000,
possibility: 1.0,
changed_last_at: Date.now()
});
// Configure complex resource allocation: team budget + individual limit + resource cost
arbiter.setRelationConfig('can_allocate_resource', {
type: 'logical',
intersection: {
rules: [
{
type: 'chain',
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'budget', direction: 'out' }
]
},
{
type: 'relational_comparator',
leftRelation: 'spending_limit',
rightRelation: 'cost',
operator: '>=',
decay: { factor: 0.1, maxAge: 3600000 }
}
]
}
});
const result = arbiter.authChecker.check('user:alice', 'can_allocate_resource', 'server:prod');
assert.ok(result.possibility > 0.7, `Expected high possibility for resource allocation, got ${result.possibility}`);
});
});
describe('Performance and Scalability', () => {
it('handles large-scale authorization with performance optimization', () => {
// Set up many users and teams
for (let i = 0; i < 100; i++) {
arbiter.addNode(`user:user${i}`, 'user');
arbiter.addNode(`team:team${i}`, 'team');
arbiter.addRelation(`user:user${i}`, 'member_of', `team:team${i}`, {
value: 1.0,
possibility: 1.0,
changed_last_at: Date.now()
});
}
// Configure performance-optimized authorization
arbiter.setRelationConfig('can_access_large_scale', {
type: 'logical',
union: {
rules: [
{ type: 'direct' },
{
type: 'chain',
steps: [
{ relation: 'member_of', direction: 'out' },
{ relation: 'can_access_large_scale', direction: 'out' }
]
}
]
}
});
// Test with performance options
const result = arbiter.authChecker.check('user:user50', 'can_access_large_scale', 'team:team50', {
fastPath: true,
binary: true,
trackEvaluation: true
});
assert.ok(result.possibility > 0.8, `Expected high possibility for large-scale authorization, got ${result.possibility}`);
assert.ok(result.binary, 'Expected binary mode result');
});
});
});