# Authorization Rules API Specification This document defines the standardized API that all authorization rules must implement to ensure consistency, performance, and maintainability across the zanzibar-graph system. ## Overview All authorization rules must extend the `BaseRule` class and implement the required abstract methods. This ensures: - **Consistent Interface**: All rules have the same public API - **Performance Tracking**: Built-in performance monitoring - **Error Handling**: Standardized error responses - **Batch Processing**: Optional but encouraged for performance - **Early Exit**: Threshold-based optimization support - **Input Validation**: Automatic parameter validation ## Core Interface ### Constructor ```javascript constructor(arbiter) ``` **Parameters:** - `arbiter` (Arbiter): The main Arbiter instance **Requirements:** - Must call `super(arbiter)` first - Should initialize any rule-specific state - Must not throw exceptions ### Primary Evaluation Method ```javascript evaluate(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options = {}) ``` **Parameters:** - `userId` (number): Internal user node ID - `userKey` (string): User key (e.g., "user:alice") - `objectId` (number): Internal object node ID - `objectKey` (string): Object key (e.g., "doc:secret") - `rule` (Object): Rule configuration object - `visited` (Set): Set of visited nodes for cycle detection - `currentRelation` (string): Current relation being evaluated - `options` (Object): Evaluation options **Returns:** `RuleEvaluationResult` object **Standard Options:** ```javascript { // Performance options fastPath: false, // Enable early termination minAllowPossibility: null, // Threshold for allow early exit (0-1) maxDenyPossibility: null, // Threshold for deny early exit (0-1) // Inference options noInfer: false, // Disable inference allowInference: true, // Allow inference (opposite of noInfer) // Binary mode binary: false, // Return binary allow/deny decisions // Evaluation tracking trackEvaluation: true, // Include evaluation metadata // Rule-specific options (passed through) // ... additional options specific to rule type } ``` ### Batch Evaluation Method (Optional) ```javascript batchEvaluate(queries, batchOptions = {}) ``` **Parameters:** - `queries` (Array): Array of query objects with same structure as `evaluate` parameters - `batchOptions` (Object): Batch-specific options **Returns:** Array of `RuleEvaluationResult` objects **Query Object Structure:** ```javascript { userId: number, userKey: string, objectId: number, objectKey: string, rule: Object, visited: Set, currentRelation: string, options: Object } ``` ### Batch Support Check ```javascript canBatchProcess() ``` **Returns:** `boolean` - Whether this rule supports efficient batch processing ## Standard Result Structure All evaluation methods must return a `RuleEvaluationResult` object: ```javascript { // Core evaluation results (required) possibility_allow: number, // 0-1, possibility of allowing access possibility_deny: number, // 0-1, possibility of denying access reliability: number, // 0-1, reliability of the evaluation // Metadata (required, can be null) meta_allow: Object | null, // Metadata for allow decision meta_deny: Object | null, // Metadata for deny decision // Optional fields reason: string, // Reason for the result error: boolean, // Whether this is an error result details: Object, // Additional details evaluation: Object // Evaluation tracking data } ``` ### Standard Metadata Structure ```javascript // meta_allow / meta_deny structure { ruleType: string, // Type of rule (e.g., 'direct', 'tuple_to_userset') reason: string, // Reason for decision rule: Object, // Original rule configuration // Performance metadata earlyExit: boolean, // Whether early exit was used earlyExitReason: string, // Reason for early exit // Rule-specific metadata // ... additional fields specific to rule type } ``` ## Implementation Requirements ### Abstract Methods (Must Implement) ```javascript // Core evaluation logic _evaluateRule(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options) // Batch evaluation logic (optional, only if canBatchProcess() returns true) _batchEvaluateRule(queries, batchOptions) ``` ### Performance Tracking All rules automatically track: - Individual evaluation count and timing - Batch evaluation count and timing - Average evaluation times Access via: ```javascript rule.getPerformanceStats() rule.resetPerformanceStats() ``` ### Error Handling Rules should handle errors gracefully: - Input validation is automatic - Exceptions are caught and converted to error results - Batch operations fall back to individual evaluations on error ## Rule-Specific Configurations ### Common Rule Properties ```javascript { type: string, // Rule type identifier ruleType: string, // 'defeasible', 'defeater', 'strict' priority: number, // Rule priority (higher = more important) weight: number, // Rule weight for aggregation // Performance options no_infer: boolean, // Disable inference for this rule allowInference: boolean, // Allow inference // Aggregation options owaWeights: Array, // OWA aggregation weights aggregator: string, // Aggregation method ('max', 'min', 'avg', etc.) // Rule-specific properties // ... varies by rule type } ``` ### DirectRule Configuration ```javascript { type: 'direct', relation: string, // Relation to check (optional, uses currentRelation) reverse: boolean // Check in reverse direction } ``` ### TupleToUsersetRule Configuration ```javascript { type: 'tuple_to_userset', tuplesetRelation: string, // Relation from object to intermediate computedRelation: string, // Relation from user to intermediate reverse: boolean // Check in reverse direction } ``` ### ParentRule Configuration ```javascript { type: 'parent', parentRelation: string, // Relation defining parent-child relation: string, // Relation to check on parent reverse: boolean // Check in reverse direction } ``` ### SimilarityRule Configuration ```javascript { type: 'similar_to', relation: string, // Relation to find similarities for k: number, // Number of similar entities to consider similarityThreshold: number, // Minimum similarity threshold (0-1) reverse: boolean, // Check in reverse direction fallbackToBasicSimilarity: boolean // Use basic similarity when embeddings unavailable } ``` ### MultiHopRule Configuration ```javascript { type: 'multi_hop', relation: string, // Relation to traverse maxDepth: number, // Maximum path depth minReliability: number, // Minimum path reliability decayFactor: number, // Reliability decay per hop pathAggregation: string, // How to aggregate multiple paths ('max', 'sum', 'owa') reverse: boolean, // Search in reverse direction allowInference: boolean, // Allow inference for missing edges fallbackToBasicPaths: boolean // Use basic path finding as fallback } ``` ### ComputedRule Configuration ```javascript { type: 'computed', relation: string // Relation to recursively evaluate } ``` ## Logical Operators ### Union (OR) Configuration ```javascript { union: Array, // Array of rules to OR together aggregator: string, // Aggregation method owaWeights: Array, // OWA weights for fusion reliabilityWeighting: boolean // Weight by reliability } ``` ### Intersection (AND) Configuration ```javascript { intersection: Array, // Array of rules to AND together aggregator: string, // Aggregation method (defaults to 'min') owaWeights: Array // OWA weights for fusion } ``` ### Exclusion (A AND NOT B) Configuration ```javascript { exclusion: [RuleConfig, RuleConfig] // [base rule, exclusion rule] } ``` ## Performance Optimization Guidelines ### Early Exit Support Rules should support early termination when: - `options.fastPath` is true - `options.minAllowPossibility` threshold is met - `options.maxDenyPossibility` threshold is met ### Batch Processing Rules that can benefit from batch processing should: - Override `canBatchProcess()` to return `true` - Implement `_batchEvaluateRule()` method - Group similar operations for efficiency - Use indexed lookups instead of linear scans ### Caching Rules should leverage: - Arbiter's built-in caching mechanisms - Batch caches for intermediate results - Embedding caches for similarity calculations ## Testing Requirements All rules must include: - Unit tests for individual evaluation - Batch evaluation tests (if supported) - Performance benchmarks - Error handling tests - Edge case coverage ## Migration Guide To migrate existing rules to the new API: 1. **Extend BaseRule**: Change `export class MyRule` to `export class MyRule extends BaseRule` 2. **Rename evaluate**: Rename `evaluate()` to `_evaluateRule()` 3. **Update constructor**: Call `super(arbiter)` first 4. **Handle options**: Use normalized options parameter 5. **Update tests**: Test against new interface ## Example Implementation ```javascript import { BaseRule } from './BaseRule.js'; export class ExampleRule extends BaseRule { constructor(arbiter) { super(arbiter); // Rule-specific initialization } canBatchProcess() { return true; // This rule supports batching } _evaluateRule(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options) { // Implement rule-specific logic const result = { possibility_allow: 0.8, possibility_deny: 0.1, reliability: 0.9, meta_allow: { ruleType: 'example', reason: 'example_evaluation', rule }, meta_deny: null, reason: 'example_result' }; return result; } _batchEvaluateRule(queries, batchOptions) { // Implement efficient batch processing return queries.map(query => this._evaluateRule( query.userId, query.userKey, query.objectId, query.objectKey, query.rule, query.visited, query.currentRelation, query.options ) ); } } ``` This standardized API ensures all rules work consistently while allowing for rule-specific optimizations and features.