Aggregated Policy in Keycloak: Combining Rules Without Rebuilding Them

Aggregated Policy in Keycloak: Combining Rules Without Rebuilding Them

Fine-grained authorization often needs several conditions checked together — a role, a location, a time window. Keycloak's Aggregated Policy lets you reuse existing policies as building blocks instead of writing one giant rule from scratch, every single time.

Picture a nightclub with three separate checks at the door: an ID scanner that confirms you’re over 18, a guest-list scanner that confirms you’re invited, and a dress-code check done visually by the bouncer. Nobody builds a single machine that does all three at once — instead, each check already exists on its own, and the club simply decides how the results of all three combine into one “let them in” decision. Keycloak’s Aggregated Policy is exactly that bouncer’s rulebook: it doesn’t invent new checks, it combines checks that already exist into a single, reusable decision.

1What Is an Aggregated Policy?

To understand an aggregated policy, you first need to understand what a plain “policy” is inside Keycloak’s authorization system.

A quick refresher: what is a policy?

Inside Keycloak’s Authorization Services, a policy is a single, named condition — for example “user has the manager role,” “request comes from a specific IP range,” or “current time is within business hours.” A policy by itself doesn’t grant or deny access to anything; it’s just a reusable rule that says whether a condition is true or false for a given request.

What an aggregated policy adds

An aggregated policy is a special kind of policy whose only job is to combine other, already-existing policies into one. Instead of checking a role or an IP address directly, it says “evaluate policy A, policy B, and policy C, then combine their individual results using this rule.” The output is still just one true/false decision, but it’s built entirely out of pieces you’ve already defined elsewhere.

Simple Analogy

Think of individual policies as separate light switches — one for the porch light, one for the garden light, one for the garage light. An aggregated policy is a single “outdoor lights” switch on your wall that doesn’t have its own bulb; flipping it just triggers the other three switches according to a rule you set, such as “turn everything on if at least one of these is flipped.”

Why not just write one big policy?

You technically could combine several conditions inside a single custom or JavaScript-based policy. But then that combined logic lives in exactly one place, tied to exactly one use case. The moment a second permission needs “role is manager OR role is admin,” you’d have to copy that logic again. Aggregation keeps each condition as an independent, testable, reusable unit, and lets combinations be built and rebuilt without touching the original policies at all.

i
Key Point

An aggregated policy never contains logic like “role equals X” directly. It only ever references other policies by name and defines how their individual results should be merged.

2Where It Fits: Keycloak’s Authorization Architecture

Aggregated policies don’t operate in isolation — they sit inside a larger pipeline of resources, scopes, policies, and permissions that make up Keycloak’s fine-grained authorization model.

Building Block

Resource

Something being protected — a document, an API endpoint, or an entire application feature.

Building Block

Scope

An action that can be performed on a resource, such as view, edit, or delete.

Building Block

Policy

A named, reusable condition — role-based, group-based, time-based, client-based, user-based, or custom-logic-based — including aggregated policies themselves.

Building Block

Permission

The final rule that ties resources and scopes to one or more policies, deciding whether a specific action on a specific resource is allowed.

Policy types available for aggregation

Keycloak ships with several native policy types — role, user, group, client, time, and JavaScript-based (rule) policies — plus, importantly, the aggregated type itself. Because an aggregated policy is itself a policy, it can reference other aggregated policies too, letting you build layered combinations: a mid-level aggregation of two simple policies can itself become one ingredient inside a larger aggregation.

Simple Analogy

This is like nesting recipes in a cookbook. “Tomato sauce” is a recipe on its own. “Lasagna” is a separate recipe that says “use one batch of tomato sauce” without re-explaining how to make it. An aggregated policy referencing another aggregated policy works the same way — one combination becomes an ingredient inside a bigger combination.

Decision strategy — the setting that makes aggregation meaningful

Every aggregated policy carries its own decision strategy, which decides how the results of its child policies are merged into one outcome. Keycloak offers three strategies:

StrategyMeaning
UnanimousEvery associated policy must grant access for the aggregated result to be a grant.
AffirmativeAt least one associated policy granting access is enough for the aggregated result to be a grant.
ConsensusThe aggregated result follows whichever side — grant or deny — has more votes among the associated policies.

3Internal Working: How Evaluation Actually Happens

Understanding the evaluation order helps explain some behavior that otherwise looks confusing, especially around the Affirmative strategy.

Step by step

When a permission tied to an aggregated policy needs to be evaluated, Keycloak’s policy evaluation engine runs through the aggregated policy’s associated policies one at a time, computing a grant or deny for each. It then applies the aggregated policy’s own decision strategy to those individual results to produce a single combined outcome, which is treated exactly like the result of any other policy type by whatever permission or higher-level aggregation is using it.

flowchart TD
    A[Permission evaluates Aggregated Policy] --> B[Policy 1: Role Check]
    A --> C[Policy 2: Time Window Check]
    A --> D[Policy 3: Group Check]
    B --> E{Decision Strategy}
    C --> E
    D --> E
    E -->|Unanimous: all must grant| F[Combined Result]
    E -->|Affirmative: any one grants| F
    E -->|Consensus: majority wins| F
        
FIG 1 — An aggregated policy collects results from its associated policies and merges them using one decision strategy

A subtlety worth knowing: each associated policy has its own decision strategy too

Here’s a detail that catches many administrators off guard. Every policy in Keycloak — including each individual policy referenced inside an aggregated policy — already has its own resource-server-level default logic and can itself be composed of multiple conditions with its own “affirmative” or “unanimous” behavior internally. This nesting means that a confusing Affirmative-strategy outcome is often not a bug in the aggregated policy layer at all, but a mismatch between what you expect a child policy’s own internal logic to mean versus what it’s actually configured to do. When troubleshooting, it’s worth checking each associated policy’s own individual evaluation result in isolation before assuming the aggregation logic is at fault.

!
Common Misconception

“Affirmative” at the aggregated-policy level and “Affirmative” at the resource-server level (which governs how multiple permissions combine) are two different settings that happen to share a name. Getting an unexpected deny is often a sign that these two separate layers are interacting in a way the administrator didn’t anticipate, not that aggregation itself is broken.

Logic negation

Like any Keycloak policy, an aggregated policy also supports a “Negate Logic” toggle. When enabled, the final combined outcome — after the decision strategy has already been applied — is flipped. This is useful for expressing “NOT (role is contractor AND after-hours)” style conditions without inventing a fourth decision strategy.

4Data Flow & Lifecycle of an Aggregated Policy

Building an aggregated policy follows a predictable sequence, and skipping steps is the most common source of setup confusion.

1

Create the Building-Block Policies First

Every simple policy the aggregation will reference — role, group, time, client, or custom logic — must already exist in the client’s Authorization tab before it can be selected.

2

Create the Aggregated Policy

Under Authorization → Policies, a new policy of type “Aggregated” is created, given a name, and populated with the “Apply Policy” list — the set of previously created policies it will combine.

3

Choose a Decision Strategy

Unanimous, Affirmative, or Consensus is selected, defining exactly how the associated policies’ individual results will be merged.

4

Attach It to a Permission

The aggregated policy is applied to one or more resource- or scope-based permissions, just like any other policy would be.

5

Runtime Evaluation

Every authorization request against that permission now triggers evaluation of all associated policies and the merge step, live, on every request — there’s no caching of “combined” results across policy versions.

!
Common Mistake

Deleting or renaming a policy that an aggregated policy depends on breaks the aggregation silently in some Keycloak versions, or removes the reference — always check every aggregated policy’s “Apply Policy” list before retiring a building-block policy.

5Advantages and Trade-offs

Advantages

  • Reuses existing policies instead of duplicating condition logic across many permissions.
  • Keeps individual conditions simple and independently testable, since each one still evaluates in isolation.
  • Supports nesting, so complex, multi-layered rules can be built up gradually from small, well-understood pieces.
  • Centralizes a change: updating one building-block policy automatically updates every aggregated policy that references it, without editing each one by hand.
  • Keeps the admin console’s policy list readable, since combination logic lives in named aggregated policies rather than sprawling custom scripts.

Disadvantages / Trade-offs

  • Adds an indirection layer: understanding “why was this denied” now means checking several policies plus a decision strategy, instead of reading one rule.
  • Deep nesting of aggregated policies inside aggregated policies can become genuinely hard to reason about during an audit.
  • Consensus and Unanimous strategies can produce surprising denials if an administrator adds a new, unrelated policy to an existing aggregation without re-checking the combined outcome.
  • Requires the building-block policies to already exist, which adds an extra setup step compared to writing one self-contained custom policy.

6Security Considerations

Combining policies changes the shape of your access-control surface, which is worth reasoning about deliberately rather than by trial and error.

Choosing the wrong decision strategy is a real security risk

An Affirmative strategy applied to a set of policies that were designed independently, without considering how they’d interact, can accidentally grant access whenever any single one of several loosely related conditions is met — which is often far more permissive than intended. Conversely, a Unanimous strategy applied to policies that were never meant to all apply simultaneously can produce unexpected denials that look like a bug but are actually the aggregation doing exactly what it was told.

Simple Analogy

Choosing Affirmative when you meant Unanimous is like a building with three separate keys — front door, back door, side door — where “Affirmative” means having any single key gets you in anywhere, not just through that one door. If the side-door key was only ever meant for the cleaning staff, that’s a security hole hiding inside a configuration choice.

Review aggregations whenever a building-block policy changes

Because a single underlying policy can be referenced by several aggregated policies, tightening or loosening one shared building block silently changes the behavior of every combination that uses it. A role policy that’s broadened to include a new role, for instance, widens access everywhere that role policy is aggregated into, not just in the one place someone was thinking about when they made the change.

i
Key Point

Before editing a shared policy, search for every aggregated policy that references it. Keycloak’s admin console lets you inspect an aggregated policy’s “Apply Policy” list, but it doesn’t proactively warn you when you edit a policy that other aggregations depend on.

Auditing combined outcomes

Because the combined result is what ultimately governs access, security reviews should test the aggregated policy’s actual output under representative scenarios — not just read the configuration and assume the intended meaning matches the configured decision strategy.

7Monitoring, Logging & Metrics

Authorization decisions that quietly deny legitimate users, or quietly grant more than intended, tend to surface as support tickets long before anyone notices in a dashboard — unless you watch for them directly.

Evaluate
tool in the admin console for dry-run testing
Decision
strategy to log per permission
Deny rate
to trend per aggregated policy over time

Use the built-in policy evaluation tool

Keycloak’s admin console includes an “Evaluate” feature under a client’s Authorization tab that lets an administrator simulate a request — a specific user, resource, and scope — and see exactly which policies fired and how the aggregated result was reached. This should be the first stop whenever an aggregated policy’s real-world behavior needs verifying, rather than reasoning about it purely from the configuration screen.

What’s worth tracking over time

For permissions backed by an aggregated policy, it’s worth trending the overall grant/deny rate over time. A sudden shift after a routine change to a building-block policy — even one that seemed unrelated — is a strong signal that the aggregation’s real-world behavior has changed in a way nobody intended.

!
Common Mistake

Relying only on end-user complaints to catch an authorization regression. By the time users are reporting “I can’t access X anymore,” a Unanimous-strategy aggregation has likely been silently broken by an unrelated policy change for some time already.

8Design Patterns & Anti-Patterns

The Shared-Condition Pattern

A condition that legitimately applies to many different permissions — such as “request originates from an approved corporate network” — is built once as its own policy, then aggregated alongside a different role or group policy for each individual permission that needs it, rather than being re-created from scratch each time.

The Layered-Aggregation Pattern

Two or three simple policies are combined into a mid-level aggregated policy representing a meaningful business concept (for example, “trusted internal reviewer”), which is then itself aggregated into higher-level permissions across multiple resources — keeping each layer readable on its own.

ANTI-PATTERN-01 Avoid
Problem

Building a single aggregated policy that mixes unrelated business conditions together purely because they happen to apply to the same permission today.

Why It’s Harmful

When one of those unrelated conditions needs to change later, the administrator has to re-verify the entire combined outcome, because the aggregation doesn’t reflect any coherent real-world concept — it just reflects yesterday’s convenience.

Correct Approach

Group conditions that represent one genuine concept together, and keep genuinely unrelated conditions in separate aggregated policies even if they currently apply to the same permission.

ANTI-PATTERN-02 Avoid
Problem

Choosing Affirmative as a default decision strategy for every aggregated policy without considering whether the combined conditions were designed to be alternatives or requirements.

Why It’s Harmful

Conditions that were meant to all hold together — such as “correct role AND within business hours” — silently become “any one of these is enough,” quietly widening access.

Correct Approach

Choose the decision strategy based on the actual relationship between the conditions: Unanimous for requirements that must all hold, Affirmative for genuine alternatives, Consensus only when a majority-vote model truly matches the business rule.

Practice

Name policies for what they check, not for their use

A policy named “Business Hours” is far more reusable across aggregations than one named “Campaign Report Access Rule.”

Practice

Document the intended relationship

Record, alongside each aggregated policy, whether its child conditions were meant as alternatives (Affirmative) or requirements (Unanimous), so future changes don’t accidentally flip the intent.

Practice

Test with the Evaluate tool before shipping

Simulate representative users and resources against the aggregated policy before attaching it to a live permission.

Practice

Limit nesting depth

Keep aggregation-of-aggregations to two or three levels at most, so an auditor can still trace a decision by hand in a reasonable amount of time.

Common mistakes to avoid

Beyond choosing the wrong decision strategy, three mistakes recur in practice: forgetting that a building-block policy is shared across several aggregations before editing it; assuming the aggregated policy’s decision strategy also governs how multiple different permissions interact (that’s a separate, resource-server-level setting); and building a large aggregation for a condition that’s only ever going to be used once, where a simpler direct policy attached to the permission would have been easier to read and maintain.

10Real-World & Industry Examples

Role-Based Access with Multiple Eligible Roles

A common real-world setup grants access to a resource if a user holds any one of several roles — for example, admin, advertiser, or analyst — by aggregating one role policy per role and combining them with the Affirmative strategy, so holding any single qualifying role is sufficient.

Location-Restricted Confidential Resources

A resource that should only be reachable by users from a specific organizational domain and from an approved network range combines a domain-based user policy with a network-range policy under a Unanimous strategy, so both conditions must hold together.

Microservice API Gateways

Organizations exposing several internal APIs through Keycloak-protected gateways often build one aggregated “trusted service” policy — combining a client policy and a network policy — and reuse it across dozens of individual endpoint permissions, so tightening trust rules in one place tightens every protected endpoint at once.

ScenarioCombined PoliciesTypical Strategy
Any qualifying role grants accessRole A, Role B, Role CAffirmative
Domain-restricted confidential resourceDomain policy, Network policyUnanimous
Shared trust rule across many endpointsClient policy, Network policyUnanimous

11Frequently Asked Questions

Q1Can an aggregated policy reference another aggregated policy?

Yes. Because an aggregated policy is itself a policy, it can be added to the “Apply Policy” list of a larger aggregated policy, allowing layered, nested combinations.

Q2What’s the difference between Unanimous, Affirmative, and Consensus?

Unanimous requires every associated policy to grant access. Affirmative requires only one to grant. Consensus follows whichever side — grant or deny — has more votes among the associated policies.

Q3Does an aggregated policy need its own resource or scope?

No. An aggregated policy, like any policy, is not tied to a specific resource or scope on its own — it becomes relevant to a resource or scope only once it’s attached to a permission.

Q4If I edit a policy used inside an aggregation, does the aggregation update automatically?

Yes — the aggregated policy always references the current version of each associated policy at evaluation time, so any edit to a building-block policy immediately affects every aggregation that uses it.

Q5Is there a limit to how many policies can be aggregated together?

Keycloak doesn’t impose a hard limit, but readability and auditability suffer well before any technical limit would be reached — a handful of well-named conditions is usually more maintainable than a very long list.

12Summary and Key Takeaways

An Aggregated Policy in Keycloak is a policy whose entire purpose is to combine other, already-existing policies into a single decision, using one of three decision strategies — Unanimous, Affirmative, or Consensus — to merge their individual results. It doesn’t check roles, groups, or networks directly; it orchestrates other policies that already do. This makes complex, multi-condition access rules reusable, auditable, and easier to reason about than one large custom rule, provided the decision strategy genuinely matches the real relationship between the conditions being combined.

Key Takeaways

  • An aggregated policy combines policies, not conditions — it references other named policies rather than checking roles or attributes itself.
  • The decision strategy is the whole design decision — Unanimous for requirements, Affirmative for alternatives, Consensus for majority-based rules.
  • Aggregated policies can nest — an aggregation can itself be one ingredient inside a larger aggregation, supporting layered, business-meaningful rules.
  • Shared building blocks mean shared risk — editing one policy silently changes every aggregation that references it.
  • Test with the Evaluate tool, not just the configuration screen — the real combined outcome should always be verified against representative scenarios.
  • Keep aggregations conceptually coherent — group conditions that represent one real business idea, rather than combining unrelated checks purely by convenience.