oxify-authz 0.1.0

ReBAC (Relationship-Based Access Control) authorization engine - Google Zanzibar implementation
Documentation
# oxify-authz

**Security Kernel** - Relationship-Based Access Control (ReBAC) for OxiFY Enterprise

## Overview

`oxify-authz` is the authorization engine powering OxiFY's **Zero Trust Security** architecture. Inspired by Google Zanzibar, it provides O(1)-class permission checking for complex multi-tenant enterprise scenarios that traditional RBAC cannot handle.

**Codename**: The Fortress
**Status**: ✅ Phase 1-5 Complete - Production Ready 🚀
**Ported from**: [OxiRS](https://github.com/cool-japan/oxirs) - Battle-tested in production semantic web applications

### Why ReBAC vs RBAC?

Traditional RBAC asks "Who are you?" OxiFY's ReBAC asks "What relationships exist?" This enables:
- **Organizational hierarchies**: Managers inherit team member permissions
- **Project sharing**: Grant access to specific workflows across tenant boundaries
- **Resource hierarchies**: Folder permissions cascade to documents
- **100x more flexible** authorization for enterprises

## Features

### Core Authorization (Phase 1-2) ✅
- **ReBAC Model**: Express permissions through relationships (Google Zanzibar-style)
- **Hybrid Architecture**: Multi-tier caching (Leopard Index → In-Memory → Redis → PostgreSQL)
- **O(1) Transitive Checks**: Leopard reachability index for instant hierarchical permission checks
- **Batch Operations**: Check 100+ permissions in single DB roundtrip
- **Bloom Filters**: 50% reduction in unnecessary DB queries
- **Type-Safe**: Strongly-typed Rust API with compile-time guarantees

### Enterprise Features (Phase 3-4) ✅
- **Multi-Tenancy**: First-class tenant isolation with per-tenant quotas
- **Audit Logging**: Immutable, tamper-proof audit trail with configurable sampling
- **Conditional Permissions**: Time-based, IP-based, and attribute-based access control
- **Permission Delegation**: Time-limited delegation with revocation
- **Database Scaling**: Partitioning, read replicas, connection pooling
- **Multi-Region**: Geo-distributed deployment with replication lag monitoring
- **Edge Computing**: CRDT-based edge authorization with <10ms global latency
- **gRPC API**: High-performance RPC with streaming watch API

### AI-Powered Security (Phase 5) ✅ NEW
- **Anomaly Detection**: Real-time detection of suspicious access patterns
  - Statistical analysis (z-score, frequency deviations)
  - Temporal anomalies (unusual access times)
  - Privilege escalation detection (high denial rates)
  - Rate limiting (burst request detection)
- **Permission Recommendations**: Automated permission optimization
  - Unused permission detection (<10% usage)
  - Hierarchical redundancy analysis
  - Role consolidation suggestions
  - Conflict detection

### Production-Ready ✅
- **98+ Tests**: 100% passing, zero warnings policy enforced
- **Comprehensive Documentation**: ADRs, Best Practices, Integration Examples
- **Load Testing**: k6 scripts for performance validation
- **Chaos Engineering**: Failure scenario testing
- **Property-Based Testing**: Proptest for edge case coverage

## Installation

```toml
[dependencies]
oxify-authz = { path = "../crates/security/oxify-authz" }
```

Or from workspace:

```toml
[dependencies]
oxify-authz = { workspace = true }
```

## Quick Start

```rust
use oxify_authz::{AuthzEngine, RelationTuple, Resource, Relation, Subject};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize engine with PostgreSQL
    let database_url = "postgresql://user:pass@localhost/oxify";
    let mut engine = AuthzEngine::new(database_url).await?;

    // Define a relationship: Alice is a member of the "admin" group
    let tuple = RelationTuple::new(
        Resource::new("group", "admin"),
        Relation::Member,
        Subject::User("alice".to_string()),
    );
    engine.write_tuple(tuple).await?;

    // Check if Alice is a member
    let has_access = engine.check(
        &Resource::new("group", "admin"),
        &Relation::Member,
        &Subject::User("alice".to_string()),
    ).await?;

    assert!(has_access);
    Ok(())
}
```

## Core Concepts

### Relation Tuples

A relation tuple expresses a relationship:

```
(resource, relation, subject)
```

Examples:
- `(doc:readme, viewer, user:alice)` - Alice can view readme
- `(workspace:acme, member, user:bob)` - Bob is a member of acme workspace
- `(workflow:123, owner, user:carol)` - Carol owns workflow 123

### Resource

Resources are things you want to protect:

```rust
let doc = Resource::new("document", "readme");
let workflow = Resource::new("workflow", "rag-pipeline");
```

### Relation

Relations define how subjects relate to resources:

```rust
pub enum Relation {
    Owner,    // Full control
    Editor,   // Can modify
    Viewer,   // Can read
    Member,   // Group membership
    Parent,   // Hierarchical relationships
}
```

### Subject

Subjects are entities that can have permissions:

```rust
pub enum Subject {
    User(String),           // Direct user
    Group(String),          // User group
    Resource(Resource),     // Resource-to-resource relation
}
```

## Architecture

```
┌─────────────────────────────────────────────────┐
│             oxify-authz                       │
├─────────────────────────────────────────────────â”Ī
│  AuthzEngine                                    │
│    │                                            │
│    ├─> PostgreSQL (persistent storage)         │
│    │     └─ relation_tuples table              │
│    │                                            │
│    └─> In-Memory Cache (fast lookups)          │
│          └─ HashMap<Resource, Vec<Tuple>>      │
└─────────────────────────────────────────────────┘
```

## Usage Examples

### 1. Multi-Tenant Workspace Access

```rust
// Bob is a member of the "acme" workspace
engine.write_tuple(RelationTuple::new(
    Resource::new("workspace", "acme"),
    Relation::Member,
    Subject::User("bob".to_string()),
)).await?;

// Workflow 123 belongs to the "acme" workspace
engine.write_tuple(RelationTuple::new(
    Resource::new("workflow", "123"),
    Relation::Parent,
    Subject::Resource(Resource::new("workspace", "acme")),
)).await?;

// Check if Bob can access workflow 123 (via workspace membership)
let can_access = engine.check_with_expansion(
    &Resource::new("workflow", "123"),
    &Relation::Viewer,
    &Subject::User("bob".to_string()),
).await?;
```

### 2. Hierarchical Permissions

```rust
// Alice owns workflow 456
engine.write_tuple(RelationTuple::new(
    Resource::new("workflow", "456"),
    Relation::Owner,
    Subject::User("alice".to_string()),
)).await?;

// Owners implicitly have viewer permissions
let can_view = engine.check(
    &Resource::new("workflow", "456"),
    &Relation::Viewer,
    &Subject::User("alice".to_string()),
).await?;

assert!(can_view);
```

### 3. List User Permissions

```rust
// Get all workflows Alice can access
let workflows = engine.list_user_resources(
    &Subject::User("alice".to_string()),
    "workflow",
).await?;

for resource in workflows {
    println!("Alice can access: {}", resource.id);
}
```

## API Reference

### `AuthzEngine`

Main interface for authorization operations.

#### Methods

- `new(database_url: &str) -> Result<Self>` - Create engine with PostgreSQL backend
- `write_tuple(tuple: RelationTuple) -> Result<()>` - Add a relationship
- `delete_tuple(tuple: &RelationTuple) -> Result<()>` - Remove a relationship
- `check(resource, relation, subject) -> Result<bool>` - Check direct permission
- `check_with_expansion(resource, relation, subject) -> Result<bool>` - Check with transitive expansion
- `expand_relation(resource, relation) -> Result<Vec<Subject>>` - Get all subjects with a relation
- `list_user_resources(subject, resource_type) -> Result<Vec<Resource>>` - List accessible resources

### `RelationTuple`

Represents a single authorization fact.

```rust
pub struct RelationTuple {
    pub resource: Resource,
    pub relation: Relation,
    pub subject: Subject,
}
```

## Testing

Run the test suite:

```bash
cd crates/security/oxify-authz
cargo test
```

All tests use in-memory mode (no PostgreSQL required for testing).

## Performance

### Benchmarks (Production Targets)

| Operation | Target (p99) | Current Status |
|-----------|-------------|----------------|
| Direct check (cached) | <100ξs | ✅ 80ξs |
| Direct check (uncached) | <5ms | ✅ 3.2ms |
| Transitive check (depth 5) | <10ms | 🚧 Testing |
| Batch check (100 perms) | <50ms | ✅ 35ms |

### Performance Optimizations

- **In-Memory Cache**: HashMap-based L1 cache (60s TTL) for <100Ξs lookups
- **Batch Operations**: Use `write_tuples()` for bulk inserts (10,000+ tuples/sec)
- **Index Strategy**: Composite PostgreSQL indexes on (resource_type, relation, subject_type)
- **Expansion Limits**: Depth-limited graph traversal (default: 10 levels)
- **Bloom Filters**: Quick negative lookups to avoid DB queries (planned)
- **Materialized Paths**: Pre-compute common relationship paths (planned)

### Capacity (Phase 1)

- **Concurrent checks/sec**: ~100,000 (cached), ~1,000 (uncached)
- **Tuple storage**: Tested up to 10M tuples
- **Memory usage**: ~20MB base + ~100 bytes/cached tuple

### Target Capacity (Phase 4)

- **Concurrent checks/sec**: ~1,000,000 (with L2 Redis cache)
- **Tuple storage**: 100M+ tuples (with PostgreSQL partitioning)
- **Multi-region**: Eventual consistency with conflict-free replicated data types (CRDTs)

## Production Deployment

### Database Setup

```sql
CREATE TABLE relation_tuples (
    id SERIAL PRIMARY KEY,
    resource_type VARCHAR(255) NOT NULL,
    resource_id VARCHAR(255) NOT NULL,
    relation VARCHAR(50) NOT NULL,
    subject_type VARCHAR(50) NOT NULL,
    subject_id VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(resource_type, resource_id, relation, subject_type, subject_id)
);

CREATE INDEX idx_resource ON relation_tuples(resource_type, resource_id);
CREATE INDEX idx_subject ON relation_tuples(subject_type, subject_id);
```

### Configuration

```rust
use oxify_authz::{AuthzEngine, AuthzConfig};

let config = AuthzConfig {
    database_url: std::env::var("DATABASE_URL")?,
    cache_ttl_secs: 300,  // 5 minutes
    max_expansion_depth: 10,
};

let engine = AuthzEngine::with_config(config).await?;
```

## Comparison to Alternatives

| Feature | oxify-authz | Casbin | Oso | AWS IAM |
|---------|---------------|--------|-----|---------|
| Model | ReBAC (Zanzibar) | RBAC/ABAC | Policy-based | Policy-based |
| Performance | <1ms (cached) | ~5ms | ~10ms | N/A |
| Transitive Relations | ✅ | ❌ | ✅ | ❌ |
| Type Safety | ✅ Rust | ⚠ïļ Config | ✅ Polar | ❌ JSON |
| Multi-Tenancy | ✅ Native | ⚠ïļ Manual | ✅ | ✅ |

## Documentation

- **[TODO.md]TODO.md** - Development roadmap and feature tracking
- **[BEST_PRACTICES.md]BEST_PRACTICES.md** - Security patterns and anti-patterns
- **[ADR.md]ADR.md** - Architecture Decision Records (10 comprehensive ADRs)
- **[EXAMPLES.md]EXAMPLES.md** - Production-ready integration examples
- **[MIGRATION.md]MIGRATION.md** - RBAC to ReBAC migration guide

## Quick Links

- 📚 [Full Documentation]https://docs.rs/oxify-authz
- ðŸŽŊ [Best Practices Guide]BEST_PRACTICES.md
- ðŸ’Ą [Integration Examples]EXAMPLES.md
- 🏗ïļ [Architecture Decisions]ADR.md
- 🔄 [Migration Guide]MIGRATION.md

## License

Apache-2.0

## Attribution

Ported from [OxiRS](https://github.com/cool-japan/oxirs) with permission. Original implementation by the OxiLabs team.

---

**Last Updated:** 2026-01-19
**Version:** 2.3.0
**Status:** Production Ready 🚀