Architecture and deployment

PBAC is delivered by pbac-manager, a dedicated Spring Boot microservice that owns policy storage, compilation and evaluation. Isolating it means policy-decision availability and latency are insulated from load on the rest of the platform.

webconsole UI ── REST ──> webconsole backend
RabbitMQ (vhost: openiam_pbac)
pbac-manager ──> Cedar engine (embedded, native)
│ │
│ ├── pbac database (policies, versions,
│ │ simulations, usage counters)
│ ├── Redis (policy + entity caches)
│ └── auth-manager (entitlement graph)
└── audit log (decision log entries)

The Cedar engine

Policies are compiled and evaluated by the embedded Cedar engine (cedar-java 4.10.x), which bridges into Cedar's formally verified Rust evaluator through JNI. Consequences for operators:

  • The pbac-manager container image is glibc-based (unlike the Alpine/musl base used by most OpenIAM services), because Cedar's native library cannot load on musl. Use the image shipped for the release; do not rebase it onto the standard base image.
  • All applicable policies for a request are merged and evaluated in a single engine call, so Cedar's own forbid wins semantics apply across the whole policy set.

Infrastructure dependencies

DependencyUse
MariaDB/MySQL (or PostgreSQL, MSSQL, Oracle)A dedicated pbac database/schema with its own connection pool, so evaluation availability is isolated from the shared openiam database. Schema migrations ship with the standard Flyway tooling (FLYWAY_PBAC_* settings in the installer).
RabbitMQA dedicated vhost openiam_pbac carrying three queues: policy management, authorization decisions and simulations. Decision traffic is isolated from authoring and simulation traffic so a heavy simulation cannot delay live decisions. The vhost is created by the standard RabbitMQ init scripts (rabbitmqctl add_vhost openiam_pbac).
RedisDistributed caches for compiled policies and Cedar entity snapshots.
VaultDatabase credentials (SECRET_PBAC_JDBC_USERNAME / SECRET_PBAC_JDBC_PASSWORD).
OpenSearchUsed indirectly: decision-log queries go to the audit index, and random simulation subjects are drawn via user search.

For docker-compose deployments the service is defined in docker/deploy/services/pbac-manager.yaml (default heap 512M). For Kubernetes a pbac-manager helm chart ships with the release (StatefulSet, anti-affinity across nodes, default requests of 100m CPU / 1Gi memory).

Caching and propagation

pbac-manager keeps active policies and entity snapshots in layered caches:

CacheContentsRefresh
Policy write sweepACTIVE policies with their current version, database → Redisevery org.openiam.pbac.policy.cache.sweep.time ms (default 300000 = 5 min)
Policy read sweepRedis → per-node memoryevery org.openiam.pbac.policy.cache.read.sweep.time ms (default 60000 = 60 s)
Principal entitiesCedar snapshot of a user and their entitlementslocal TTL 5 min, Redis TTL 15 min (configurable)
Resource entitiesCedar snapshots of groups, roles, organizations, resourceslocal TTL 5 min, Redis TTL 15 min (configurable)

Practical consequences:

  • A policy status or enforcement-mode change is visible to every node after at most write sweep + read sweep6 minutes with defaults.
  • Changes to a user's attributes or entitlements may take up to the entity-cache TTL (≈ 15 minutes by default) to be reflected in decisions.
  • A policy version that fails to compile during a sweep is skipped (and logged), not fatal; it is picked up again once fixed.

Key configuration properties (defaults shown; set in the pbac-manager property source):

org.openiam.pbac.policy.cache.sweep.time=300000
org.openiam.pbac.policy.cache.read.sweep.time=60000
org.openiam.pbac.usage.counter.flush.time=30000
org.openiam.pbac.cedar.principal.cache.local.ttl.minutes=5
org.openiam.pbac.cedar.principal.cache.redis.ttl.minutes=15
org.openiam.pbac.cedar.principal.cache.max.size=100000
org.openiam.pbac.cedar.resource.cache.local.ttl.minutes=5
org.openiam.pbac.cedar.resource.cache.redis.ttl.minutes=15
org.openiam.pbac.cedar.resource.cache.max.size=200000
org.openiam.pbac.cedar.adhoc.policy.cache.ttl.minutes=60
org.openiam.pbac.cedar.adhoc.policy.cache.max.size=200

Usage metering

Decision volume is metered per policy into hourly buckets (PBAC_USAGE_COUNTER in the pbac schema), flushed asynchronously off the decision path. Shadow evaluations are counted — the per-policy count is the exposure figure used to judge a rollout — while users skipped by a partial rollout are not.

REST API

The webconsole exposes PBAC administration under its own context (/webconsole/rest/api/...). All endpoints require an authenticated webconsole session with administrative rights.

Policies — /rest/api/pbac/policies

VerbPathDescription
GET/Search policies (name, status, from, size).
GET/{id}Read one policy including its version history.
POST/Create or update a policy header.
POST/versionAppend a new version (body must not carry an id; the author is taken from the session).
POST/{id}/current-version/{versionId}Make a version current (activate / roll back).
DELETE/{id}Delete the policy and its versions.

Simulations — /rest/api/pbac/simulations

VerbPathDescription
GET/Search runs (policyVersionId, mode, status, paging).
GET/{id}Read one run (used for polling).
GET/{id}/subjectsPage through per-subject results (decision, errored, paging; page size capped at 200).
POST/Launch a run; returns the run id immediately.
POST/{id}/cancelCancel a running run (results so far are kept).
DELETE/{id}Delete a run and its subject rows.

Decisions — /rest/api/pbac/decisions

VerbPathDescription
GET/Search decisions (principalId, resourceId, decision, from, to, paging; page size capped at 200).
GET/{id}Read one decision entry.

Page metadata — /rest/api/ui/metadata/pbac

Returns the vocabulary the editor builds policies from: principal and resource entity types with their attributes, the context attributes supplied at decision time (with locale-aware value labels), and the deployment's access rights with their Cedar action identifiers.

Cedar policy text is validated by compilation at the API boundary; a version that does not compile is rejected with the compiler's error message.