Getting Started
Welcome to Arbiter, a framework-agnostic policy evaluation engine for hierarchical path-based access control. This guide will help you install, configure, and start using Arbiter in your application.
What is Arbiter?
Section titled “What is Arbiter?”Arbiter provides a powerful system for answering the question: “Can service X perform action Y on resource path Z?”
Think of it as a flexible authorization layer that works with hierarchical paths like:
/customers/cust-123/carriers/fedex/api-key/platform/carriers/*/credentials/internal/services/order-service/config
Installation
Section titled “Installation”Install Arbiter via Composer:
composer require cline/arbiterLaravel Setup
Section titled “Laravel Setup”If using Laravel, register the service provider in config/app.php:
'providers' => [ // ... Cline\Arbiter\ArbiterServiceProvider::class,],
'aliases' => [ // ... 'Arbiter' => Cline\Arbiter\Facades\Arbiter::class,],Or add to bootstrap/providers.php in Laravel 11+:
return [ // ... Cline\Arbiter\ArbiterServiceProvider::class,];Core Concepts
Section titled “Core Concepts”Hierarchical resource identifiers separated by /:
/platform/carriers/fedex/api-key/customers/cust-123/carriers/ups/credentials/internal/services/order-service/configPolicies
Section titled “Policies”Named collections of rules that define access:
use Cline\Arbiter\Policy;use Cline\Arbiter\Rule;use Cline\Arbiter\Capability;
$policy = Policy::create('shipping-service') ->addRule( Rule::allow('/platform/carriers/*') ->capabilities(Capability::Read, Capability::List) ) ->addRule( Rule::allow('/customers/*/carriers/*') ->capabilities(Capability::Read) ) ->addRule( Rule::deny('/customers/*/payments/*') );Capabilities
Section titled “Capabilities”Actions that can be performed:
read- View/fetch resourcelist- List children at pathcreate- Create new resourceupdate- Modify existing resourcedelete- Remove resourceadmin- Full control (implies all others)deny- Explicit denial (overrides allows)
Rule Matching
Section titled “Rule Matching”- Exact:
/carriers/fedexmatches only/carriers/fedex - Single wildcard:
/carriers/*matches/carriers/fedex,/carriers/ups - Glob wildcard:
/customers/**matches any depth under/customers/ - Variables:
/customers/${customer_id}/*with runtime substitution
Fluent API Approaches
Section titled “Fluent API Approaches”Arbiter provides two fluent API styles:
Policy-First (Most Common)
Section titled “Policy-First (Most Common)”Start with the policy and check specific paths:
Arbiter::for('policy-name') ->can('/path', Capability::Read) ->allowed();Path-First
Section titled “Path-First”Start with the path and check which capabilities exist:
Arbiter::path('/some/path') ->against('policy-name') ->allows(Capability::Read);
// Or get all available capabilities$caps = Arbiter::path('/some/path') ->against('policy-name') ->capabilities();Basic Usage
Section titled “Basic Usage”use Cline\Arbiter\Facades\Arbiter;use Cline\Arbiter\Policy;use Cline\Arbiter\Rule;use Cline\Arbiter\Capability;
// Define a policy$policy = Policy::create('shipping-service') ->addRule( Rule::allow('/platform/carriers/*') ->capabilities(Capability::Read, Capability::List) ) ->addRule( Rule::allow('/customers/*/carriers/*') ->capabilities(Capability::Read) ) ->addRule( Rule::deny('/customers/*/payments/*') );
// Register policyArbiter::register($policy);
// Check access using fluent APIArbiter::for('shipping-service') ->can('/platform/carriers/fedex', Capability::Read) ->allowed();// => true
Arbiter::for('shipping-service') ->can('/customers/cust-123/carriers/ups', Capability::Read) ->allowed();// => true
Arbiter::for('shipping-service') ->can('/customers/cust-123/payments/stripe', Capability::Read) ->allowed();// => false (explicit deny)
Arbiter::for('shipping-service') ->can('/platform/carriers/new', Capability::Create) ->allowed();// => false (no create capability)Quick Examples
Section titled “Quick Examples”Example 1: API Access Control
Section titled “Example 1: API Access Control”$apiPolicy = Policy::create('api-client') ->addRule( Rule::allow('/api/v1/users/*') ->capabilities(Capability::Read, Capability::List) ) ->addRule( Rule::allow('/api/v1/posts/**') ->capabilities(Capability::Read, Capability::Create, Capability::Update) ) ->addRule( Rule::deny('/api/v1/admin/**') );
Arbiter::register($apiPolicy);
Arbiter::for('api-client') ->can('/api/v1/users/123', Capability::Read) ->allowed();// => true
Arbiter::for('api-client') ->can('/api/v1/posts/new', Capability::Create) ->allowed();// => true
Arbiter::for('api-client') ->can('/api/v1/admin/settings', Capability::Read) ->allowed();// => false (explicit deny)Example 2: Multi-Tenant Access
Section titled “Example 2: Multi-Tenant Access”$tenantPolicy = Policy::create('tenant-app') ->addRule( Rule::allow('/tenants/${tenant_id}/**') ->capabilities(Capability::Read, Capability::Update, Capability::Create) );
Arbiter::register($tenantPolicy);
// Context provides variable values$context = ['tenant_id' => 'tenant-123'];
Arbiter::for('tenant-app') ->with($context) ->can('/tenants/tenant-123/settings', Capability::Read) ->allowed();// => true (tenant_id matches)
Arbiter::for('tenant-app') ->with($context) ->can('/tenants/tenant-456/settings', Capability::Read) ->allowed();// => false (tenant_id mismatch)Example 3: Conditional Access
Section titled “Example 3: Conditional Access”$envPolicy = Policy::create('production-only') ->addRule( Rule::allow('/platform/**') ->capabilities(Capability::Read) ->when('environment', 'production') ) ->addRule( Rule::allow('/platform/**') ->capabilities(Capability::Read, Capability::Update) ->when('environment', ['staging', 'development']) ->when('role', fn($v) => in_array($v, ['admin', 'developer'])) );
Arbiter::register($envPolicy);
$context = ['environment' => 'production', 'role' => 'viewer'];Arbiter::for('production-only') ->with($context) ->can('/platform/config', Capability::Read) ->allowed();// => true
$context = ['environment' => 'staging', 'role' => 'admin'];Arbiter::for('production-only') ->with($context) ->can('/platform/config', Capability::Update) ->allowed();// => trueNext Steps
Section titled “Next Steps”- Learn about policy patterns for common use cases
- Explore advanced features like repositories and evaluation results
- See real-world examples for credential vaults, file systems, and more
- Review the API reference for complete documentation
Use Cases
Section titled “Use Cases”Arbiter is perfect for:
- Credential Vaults - Control access to
/customers/*/carriers/*paths - File Systems - Permission checks on hierarchical file paths
- API Authorization - Route-based access control with wildcards
- Multi-Tenant Apps - Tenant-scoped resource access
- Feature Flags - Path-based feature toggles
- CMS/Content - Hierarchical content permissions