Guard your access
Role-based, attribute-based, and relationship-based authorization unified behind a single Check API — tenant-scoped, plugin-extensible, and composable.
go get github.com/xraph/wardenEverything you need for authorization
Warden handles the hard parts — role hierarchies, policy evaluation, graph traversal, and decision merging — so you can focus on your application.
Role-Based Access Control
Hierarchical roles with permissions, resource-scoped assignments, and glob-based permission matching. The most common authorization model.
"text-fd-muted-foreground/60 italic">// Create role with permissionsr := &role.Role{ID: id.NewRoleID(), Name: "Editor", Slug: "editor"}store.CreateRole(ctx, r)store.AttachPermission(ctx, r.ID, permID) "text-fd-muted-foreground/60 italic">// Assign to userstore.CreateAssignment(ctx, &assignment.Assignment{ RoleID: r.ID, SubjectKind: "user", SubjectID: "user-42",})Attribute-Based Policies
Define deny/allow policies with conditions on IP ranges, time windows, departments, and custom attributes. Conditions support 12+ operators.
p := &policy.Policy{ Name: "Office Hours Only", Effect: policy.EffectDeny, Actions: []string{"write", "delete"}, Conditions: []policy.Condition{{ Field: "time", Operator: policy.OpTimeAfter, Value: "18:00", }}, IsActive: true,}Relationship-Based (ReBAC)
Google Zanzibar-inspired relation tuples with BFS graph traversal. Model document sharing, team membership, and org hierarchies.
"text-fd-muted-foreground/60 italic">// user:42 is viewer of document:123store.CreateRelation(ctx, &relation.Tuple{ ObjectType: "document", ObjectID: "doc-123", Relation: "viewer", SubjectType: "user", SubjectID: "user-42",})"text-fd-muted-foreground/60 italic">// Transitive: user → team → projectUnified Check API
A single Check() call evaluates RBAC, ABAC, and ReBAC together. Explicit deny beats allow, which beats default deny.
result, _ := eng.Check(ctx, &warden.CheckRequest{ Subject: warden.Subject{Kind: "user", ID: "user-42"}, Action: "read", ResourceType: "document", ResourceID: "doc-123", Context: map[string]any{"ip": "10.0.1.5"},})"text-fd-muted-foreground/60 italic">// result.Allowed, result.Reason, result.SourcesMulti-Tenant Isolation
Every operation is scoped to a tenant via context. Cross-tenant access is structurally impossible at the store layer.
"text-fd-muted-foreground/60 italic">// With Forge(automatic)ctx = forge.WithScope(ctx, forge.Scope{ AppID: "myapp", TenantID: "tenant-123",}) "text-fd-muted-foreground/60 italic">// Standalonectx = warden.WithTenant(ctx, "myapp", "tenant-123")"text-fd-muted-foreground/60 italic">// All operations scoped automaticallyPlugin System
Register plugins that implement lifecycle hooks for audit logging, metrics, and custom behavior. Auto-discovered via type assertion.
eng, _ := warden.NewEngine( warden.WithStore(store), warden.WithPlugin(audit_hook.New(chronicle)), warden.WithPlugin(observability.New()),)"text-fd-muted-foreground/60 italic">// Hooks: BeforeCheck, AfterCheck, RoleCreated,"text-fd-muted-foreground/60 italic">// PolicyUpdated, RelationWritten, ...From request to decision.
Warden orchestrates the entire authorization lifecycle — RBAC evaluation, ABAC policy matching, ReBAC graph traversal, and decision merging.
Three Models, One Check
RBAC, ABAC, and ReBAC are evaluated in parallel and their decisions merged with deny-overrides priority. A single Check() call handles everything.
BFS Graph Traversal
ReBAC uses breadth-first search with cycle detection and configurable max depth to traverse relation graphs and find transitive permissions.
Audit Trail & Metrics
Every check is logged with subject, action, resource, decision, and duration. Wire in Chronicle for audit events or Prometheus for metrics via the plugin system.
Simple API. Powerful primitives.
Set up role-based access or traverse a relationship graph in under 30 lines. Warden handles evaluation, merging, and audit logging.
1package main2 3import (4 "context"5 "fmt"6 "time"7 8 "github.com/xraph/warden"9 "github.com/xraph/warden/assignment"10 "github.com/xraph/warden/id"11 "github.com/xraph/warden/permission"12 "github.com/xraph/warden/role"13 "github.com/xraph/warden/store/memory"14)15 16func main() {17 ctx := context.Background()18 st := memory.New()19 eng, _ := warden.NewEngine(warden.WithStore(st))20 21 now := time.Now()22 perm := &permission.Permission{23 ID: id.NewPermissionID(), Resource: "document",24 Action: "read", Name: "Read Docs",25 CreatedAt: now, UpdatedAt: now,26 }27 r := &role.Role{28 ID: id.NewRoleID(), Name: "Viewer", Slug: "viewer",29 CreatedAt: now, UpdatedAt: now,30 }31 _ = st.CreatePermission(ctx, perm)32 _ = st.CreateRole(ctx, r)33 _ = st.AttachPermission(ctx, r.ID, perm.ID)34 _ = st.CreateAssignment(ctx, &assignment.Assignment{35 ID: id.NewAssignmentID(), RoleID: r.ID,36 SubjectKind: "user", SubjectID: "alice",37 CreatedAt: now,38 })39 40 result, _ := eng.Check(ctx, &warden.CheckRequest{41 Subject: warden.Subject{Kind: "user", ID: "alice"},42 Action: "read",43 ResourceType: "document",44 })45 fmt.Printf("allowed=%v reason=%q\n",46 result.Allowed, result.Reason)47 "text-fd-muted-foreground/60 italic">// allowed=true reason="rbac: granted"48}1package main2 3import (4 "context"5 "fmt"6 "time"7 8 "github.com/xraph/warden"9 "github.com/xraph/warden/id"10 "github.com/xraph/warden/relation"11 "github.com/xraph/warden/store/memory"12)13 14func main() {15 ctx := context.Background()16 st := memory.New()17 eng, _ := warden.NewEngine(warden.WithStore(st))18 19 now := time.Now()20 21 "text-fd-muted-foreground/60 italic">// user:alice is member of team:eng22 _ = st.CreateRelation(ctx, &relation.Tuple{23 ID: id.NewRelationID(),24 ObjectType: "team", ObjectID: "eng",25 Relation: "member",26 SubjectType: "user", SubjectID: "alice",27 CreatedAt: now,28 })29 30 "text-fd-muted-foreground/60 italic">// team:eng is editor of project:alpha31 _ = st.CreateRelation(ctx, &relation.Tuple{32 ID: id.NewRelationID(),33 ObjectType: "project", ObjectID: "alpha",34 Relation: "editor",35 SubjectType: "team", SubjectID: "eng",36 CreatedAt: now,37 })38 39 "text-fd-muted-foreground/60 italic">// Can alice edit project:alpha?40 "text-fd-muted-foreground/60 italic">// Traverses: alice → team:eng → project:alpha41 result, _ := eng.Check(ctx, &warden.CheckRequest{42 Subject: warden.Subject{Kind: "user", ID: "alice"},43 Action: "write",44 ResourceType: "project",45 ResourceID: "alpha",46 })47 fmt.Printf("allowed=%v\n", result.Allowed)48 "text-fd-muted-foreground/60 italic">// allowed=true (via transitive relation)49}Start building with Warden
Add RBAC, ABAC, and ReBAC authorization to your Go service in minutes. Warden handles role hierarchies, policy evaluation, graph traversal, and audit trails out of the box.
go get github.com/xraph/warden