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.
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.
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.
Resource
Something being protected — a document, an API endpoint, or an entire application feature.
Scope
An action that can be performed on a resource, such as view, edit, or delete.
Policy
A named, reusable condition — role-based, group-based, time-based, client-based, user-based, or custom-logic-based — including aggregated policies themselves.
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.
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:
| Strategy | Meaning |
|---|---|
| Unanimous | Every associated policy must grant access for the aggregated result to be a grant. |
| Affirmative | At least one associated policy granting access is enough for the aggregated result to be a grant. |
| Consensus | The 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
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.
“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.
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.
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.
Choose a Decision Strategy
Unanimous, Affirmative, or Consensus is selected, defining exactly how the associated policies’ individual results will be merged.
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.
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.
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.
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.
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.
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.
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.
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.
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.
9Best Practices & Common Mistakes
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.”
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.
Test with the Evaluate tool before shipping
Simulate representative users and resources against the aggregated policy before attaching it to a live permission.
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.
| Scenario | Combined Policies | Typical Strategy |
|---|---|---|
| Any qualifying role grants access | Role A, Role B, Role C | Affirmative |
| Domain-restricted confidential resource | Domain policy, Network policy | Unanimous |
| Shared trust rule across many endpoints | Client policy, Network policy | Unanimous |
11Frequently Asked Questions
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.
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.
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.
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.
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.