Warden

Decision Model

How Warden merges decisions from RBAC, ABAC, and ReBAC evaluators.

Decision Types

Every evaluator returns one of three decisions:

DecisionMeaning
AllowThe evaluator grants access
DenyThe evaluator explicitly denies access
NoOpinionThe evaluator has no matching rules

Merging Algorithm

When multiple evaluators return decisions, Warden merges them with this priority:

1. If ANY evaluator returns explicit DENY  → DENIED
2. If ANY evaluator returns ALLOW          → ALLOWED
3. If all return NoOpinion                 → DENIED (default deny)

This is a "deny-overrides" strategy: explicit denies always win.

Examples

Example 1: RBAC allows, no policies

RBACABACReBACResult
AllowNoOpinionNoOpinionAllowed

The user has the right role/permission. No ABAC policies or ReBAC tuples apply.

Example 2: RBAC allows, ABAC denies

RBACABACReBACResult
AllowDenyNoOpinionDenied

The user has the right role, but an ABAC policy (e.g., "deny after business hours") blocks access.

Example 3: No RBAC match, ReBAC allows

RBACABACReBACResult
NoOpinionNoOpinionAllowAllowed

No role assignment exists, but a relation tuple grants access through the relationship graph.

Example 4: Nothing matches

RBACABACReBACResult
NoOpinionNoOpinionNoOpinionDenied

Default deny: if no evaluator grants access, the request is denied.

CheckResult

The Check() call returns a CheckResult with details:

type CheckResult struct {
    Allowed  bool        // Final decision
    Decision Decision    // Allow, Deny, or NoOpinion
    Reason   string      // Human-readable explanation
    Sources  []string    // Which evaluators contributed ("rbac", "abac", "rebac")
    Duration time.Duration // Evaluation time
}

Policy Priority

When multiple ABAC policies match, they are evaluated by priority (lower number = higher priority). The first matching deny policy short-circuits evaluation.

// High priority deny (evaluated first)
&policy.Policy{Priority: 10, Effect: policy.EffectDeny, ...}

// Lower priority allow (evaluated second)
&policy.Policy{Priority: 100, Effect: policy.EffectAllow, ...}

On this page