Skip to main content

Policy Engine Overview

Summary

The Policy Engine is the central service for managing authorization policies in Keymate. It provides APIs for creating, updating, and deleting policies across six authorization models (RBAC, ABAC, ReBAC, PBAC, RADAC, Dynamic), validates policy definitions before storage, and sends audit events for compliance tracking.

Why It Exists

Authorization systems require a dedicated service to manage the lifecycle of policies separate from runtime evaluation. This separation enables:

  • Independent scaling — Policy management traffic patterns differ from evaluation traffic
  • Clear ownership — A single service owns policy storage and validation
  • Audit isolation — Policy changes are tracked independently from access decisions
  • Multi-model support — Different authorization approaches coexist under unified management

Where It Fits in Keymate

The Policy Engine sits between policy authors (Admin Console, external systems) and runtime evaluation components (Access Gateway, Permission Gateway). It does not evaluate access requests — that responsibility belongs to the gateways.

Boundaries

This component covers:

  • Policy CRUD operations via REST API
  • Policy validation and business rules
  • Multi-tenant policy isolation
  • Policy templates for reusable patterns
  • Audit event emission for policy changes
  • Integration Hub webhook handling for attribute synchronization

This component does not cover:

How It Works

Policy Types

The Policy Engine supports six authorization models:

TypeDescription
RBACRole-Based Access Control — grants access based on user roles and groups
ABACAttribute-Based Access Control — evaluates conditions on user, resource, and environment attributes
ReBACRelationship-Based Access Control — queries relationship graphs via OpenFGA
PBACPolicy-Based Access Control — composes multiple policies into a single decision
RADACRisk-Adaptive Dynamic Access Control — adjusts decisions based on risk scores
DynamicCustom evaluation logic for specialized scenarios

Policy Structure

Every policy shares a common structure:

{
"id": 1,
"tenant": "acme-corp",
"name": "document-editor-access",
"description": "Allows editors to modify documents",
"enabled": true,
"policyType": "RBAC",
"status": "ENABLED",
"strategy": "AFFIRMATIVE",
"logic": "POSITIVE",
"isShared": false,
"version": "1.0.0",
"policy": {
// Type-specific content
},
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}

Decision Strategy

The strategy field determines how multiple conditions combine:

StrategyBehavior
AFFIRMATIVEAny single "allow" permits access (logical OR)
UNANIMOUSAll conditions must "allow" (logical AND)
CONSENSUSMajority of conditions decides

Policy Logic

The logic field controls how the evaluation result is interpreted:

LogicBehavior
POSITIVEResult used as-is: true = allow, false = deny
NEGATIVEResult inverted: true = deny, false = allow (for exception rules)

Policy Modes

Policies can be authored in two modes:

ModeDescription
CONDITIONSStructured condition builder (UI-friendly)
EXPRESSIONFree-form DSL expression (power users)

Multi-Tenancy

Every policy belongs to a tenant. The tenant field provides automatic isolation — queries return only policies for the requesting tenant. The isShared flag allows policies to be visible across tenants while maintaining ownership.

API Surface

The Policy Engine exposes a REST API for policy CRUD operations:

  • List and retrieve policies with pagination and filtering
  • Create policies for each authorization model (RBAC, ABAC, ReBAC, PBAC, RADAC, Dynamic)
  • Update and delete existing policies
  • Manage templates for reusable policy patterns

Diagram

Example Scenario

Scenario

A platform administrator creates an RBAC policy that grants document editing access to users with the "editor" role.

Input

  • Actor: Platform administrator via Admin Console
  • Resource: Policy Engine REST API
  • Action: Create RBAC policy
  • Context:
    {
    "tenant": "acme-corp",
    "name": "document-editor-access",
    "description": "Grants edit access to editors",
    "enabled": true,
    "status": "ENABLED",
    "strategy": "AFFIRMATIVE",
    "logic": "POSITIVE",
    "policy": {
    "roles": [
    {
    "id": "editor-role-id",
    "name": "editor",
    "client": "content-management",
    "required": true
    }
    ],
    "groups": [],
    "fetchRoles": false,
    "generic": false,
    "mode": "CONDITIONS"
    }
    }

Expected Outcome

  • Result: Policy created with assigned ID and timestamps
  • Why: The Policy Engine validates the request structure, checks tenant authorization, persists the policy, sends an audit event to the Audit Collector, and returns the created policy

Common Misunderstandings

  • "The Policy Engine evaluates access requests" — The Policy Engine manages policy definitions. Runtime evaluation happens in the Access Gateway and Permission Gateway, which fetch policies from the Policy Engine.

  • "PBAC and ReBAC are the same" — PBAC (Policy-Based) composes multiple policies into a single decision using strategies. ReBAC (Relationship-Based) evaluates graph relationships. They serve different purposes and can be combined.

  • "Disabling a policy deletes it" — Setting enabled: false or status: DISABLED keeps the policy in storage but excludes it from active evaluation. Deletion requires a separate DELETE request.

warning

The isShared field controls cross-tenant visibility. A shared policy can be referenced by other tenants but is still owned by the creating tenant. Use with caution in multi-tenant deployments.

Design Notes / Best Practices

  • Use policy templates for common authorization patterns. Templates reduce duplication and ensure consistency across tenants.

  • Prefer AFFIRMATIVE strategy for additive permission models where any matching role grants access. Use UNANIMOUS when all conditions must be satisfied (defense in depth).

  • Leverage NEGATIVE logic for exception rules. Instead of duplicating allow rules with exclusions, create a deny policy with logic: NEGATIVE that triggers on specific conditions.

  • Version your policies using the version field. Versioning helps track policy evolution and supports rollback decisions.

tip

When combining RBAC and ABAC in a PBAC composite policy, place the RBAC check first. Role checks are faster than attribute evaluations, enabling early rejection.

  • Managing role-based permissions for enterprise applications
  • Creating attribute-based policies for data classification
  • Composing multiple authorization models for complex access control
  • Sharing policy templates across tenants

FAQ

Does the Policy Engine support real-time policy updates?

Yes. Policy changes made via the REST API take effect immediately. Consuming components (Access Gateway, Permission Gateway) implement caching strategies with appropriate TTLs to balance performance and freshness.

How does multi-tenancy work in the Policy Engine?

Every policy has a tenant field that isolates it to a specific tenant. Queries automatically filter by tenant. The isShared flag allows policies to be visible across tenants while maintaining ownership.

Can I combine multiple authorization models in one policy?

Yes, using PBAC (Policy-Based Access Control). A PBAC policy references other policies by ID and combines their results using the configured decision strategy (AFFIRMATIVE, UNANIMOUS, or CONSENSUS).

What happens if a policy validation fails?

The Policy Engine returns a 400 Bad Request with details about the validation error. Common issues include missing required fields, invalid enum values, or referencing non-existent policies in PBAC compositions.