Warden

Check Engine

The core authorization engine that evaluates RBAC, ABAC, ReBAC, and PBAC.

The Engine is the central component of Warden. It coordinates all four authorization models and returns a unified decision.

No DSL counterpart. The .warden language describes configuration (roles, permissions, policies, resource types, relations) — it doesn't describe runtime calls. The Check / Enforce / CanI APIs on this page are how you ask "is this allowed?" once your config is in place.

Creating an Engine

import (
    "github.com/xraph/warden"
    "github.com/xraph/warden/store/memory"
)

st := memory.New()
eng, err := warden.NewEngine(
    warden.WithStore(st),
)

Check

Check() evaluates all enabled authorization models and returns a result:

result, err := eng.Check(ctx, &warden.CheckRequest{
    Subject:  warden.Subject{Kind: warden.SubjectUser, ID: "user-42"},
    Action:   warden.Action{Name: "read"},
    Resource: warden.Resource{Type: "document", ID: "doc-123"},
    Context: map[string]any{
        "ip_address": "10.0.1.5",
        "department": "engineering",
    },
})

fmt.Println(result.Allowed)     // true or false
fmt.Println(result.Decision)    // "allow" / "deny_explicit" / "deny_no_perms" / ...
fmt.Println(result.Reason)      // "denied by policy 'incident-freeze'"
fmt.Println(result.MatchedBy)   // []MatchInfo — which rule matched
fmt.Println(result.Obligations) // []string — PBAC side-effect signals

CheckRequest Fields

FieldTypeRequiredDescription
SubjectSubjectYesWho is requesting access
ActionActionYesWhat action (Action{Name: "read"})
ResourceResourceYesWhat resource (Resource{Type, ID, Attributes})
Contextmap[string]anyNoAttributes for ABAC/PBAC evaluation
TenantIDstringNoOverride the context-derived tenant
NamespacePathstringNoOverride the context-derived namespace

CheckResult Fields

FieldTypeDescription
AllowedboolDecision shorthand
DecisionDecisionallow / deny_explicit / deny_no_roles / deny_no_perms / deny_condition / deny_relation / deny_default
ReasonstringHuman-readable explanation
MatchedBy[]MatchInfoEvery rule that matched (RBAC role IDs, ABAC policy IDs, ReBAC paths)
Obligations[]stringPBAC side-effect actions — audit-log, require-mfa, etc.
EvalTimeNsint64Evaluation latency

Enforce

Enforce() is like Check() but returns an error when access is denied:

err := eng.Enforce(ctx, &warden.CheckRequest{
    Subject:  warden.Subject{Kind: warden.SubjectUser, ID: "user-42"},
    Action:   warden.Action{Name: "delete"},
    Resource: warden.Resource{Type: "document", ID: "doc-123"},
})
if err != nil {
    // wrapped with the decision reason
    return err
}

CanI (Boolean Check)

CanI() returns a simple bool — handy for templating and quick checks:

allowed, err := eng.CanI(
    ctx,
    warden.SubjectUser, "user-42",
    "read",
    "document", "doc-123",
)

Configuration Options

eng, _ := warden.NewEngine(
    warden.WithStore(store),
    warden.WithConfig(warden.Config{
        EnableRBAC:    true,            // Enable role-based checks
        EnableABAC:    true,            // Enable policy-based checks
        EnableReBAC:   true,            // Enable relationship-based checks
        MaxGraphDepth: 10,              // ReBAC traversal limit
        CacheTTL:      5 * time.Minute, // Cache positive decisions
    }),
    warden.WithEvaluator(customEval),         // Custom ABAC/PBAC evaluator
    warden.WithGraphWalker(customGW),         // Custom ReBAC graph walker
    warden.WithCache(redisCache),             // Shared cache (Redis-backed, etc.)
    warden.WithExpressionEvaluator(dslEval),  // Resource-type permission expressions
    warden.WithPlugin(auditPlugin),           // Lifecycle hooks
)

Subject Types

The subject in a check request can be any kind of identity:

// Human user (from Authsome)
warden.Subject{Kind: warden.SubjectUser, ID: "user-42"}

// API key (from Keysmith)
warden.Subject{Kind: warden.SubjectAPIKey, ID: "key-abc"}

// Service-to-service caller
warden.Subject{Kind: warden.SubjectService, ID: "billing-svc"}

// Service account
warden.Subject{Kind: warden.SubjectServiceAcct, ID: "acct-foo"}

// Custom — any string is allowed; "anonymous" by convention
warden.Subject{Kind: "anonymous", ID: ""}

Each subject can carry attributes that ABAC/PBAC conditions can match on:

warden.Subject{
    Kind: warden.SubjectUser,
    ID:   "user-42",
    Attributes: map[string]any{
        "department": "engineering",
        "role_label": "staff-engineer",
    },
}

A condition like subject.attributes.department == "engineering" resolves against this map at check time. See Policies & Conditions for the full operator table.

On this page