Dieser Blogpost ist Teil einer Reihe.

  • Teil 1: What’s Wrong with the Current OWASP Microservice Security Cheat Sheet?
  • Teil 2: Updating OWASP’s Microservice Security Cheat Sheet: Core Concepts
  • Teil 3: Updating OWASP’s Microservice Security Cheat Sheet: Authentication Patterns
  • Teil 4: Updating OWASP’s Microservice Security Cheat Sheet: Identity Propagation Patterns
  • Teil 5: Updating OWASP’s Microservice Security Cheat Sheet: Authorization Patterns
  • Teil 6: Updating OWASP’s Microservice Security Cheat Sheet: Decision Dimensions for Authorization Patterns (dieser Blogpost)

In my previous post, I introduced various authorization patterns, but I completely skipped the question of which one to actually use in practice. That’s despite explicitly stating at the beginning:

Choosing the right patterns is critical, as it directly impacts the system’s security posture, performance, scalability, and maintainability.

While the discussion may have hinted that certain patterns are preferable or best avoided, the reality is more complex. There are multiple dimensions to consider when selecting the right pattern — or rather, the right patterns — for a given context. Only by examining these dimensions can we make a well-founded decision. And that’s exactly the goal of this post: to explain those decision factors and, based on them, offer a kind of framework for choosing appropriate authorization patterns.

Although I have already discussed identity propagation patterns and authentication in earlier posts, I have purposefully refrained from making specific recommendations. That’s because those choices should be informed by and not drive the authorization approach. Starting with authorization ensures we don’t end up constrained by earlier decisions that could limit our ability to build a secure, scalable, and maintainable system. So, in case you were wondering why I haven’t shared specific guidance on authentication and identity propagation yet — this is exactly the reason. I’ll come to that later — promise.

One quick note: I deliberately used the plural patterns, both in the quote from the previous post and in the paragraphs above. That’s because relying on a single pattern is rarely sufficient in real-world scenarios.

🙏 As with the previous posts in this series, the following content is meant as a direct contribution to the official cheat sheet. So please help me make it better (share you feedback either on the corresponding post on my LinkedIn account, or in heimdall’s Discord (#off-topic channel))! 😃

Towards a Framework for Selecting Authorization Patterns

Difference to the current cheat sheet

The current cheat sheet does include some recommendations, but in my opinion, the topic isn’t adequately covered because the content remains too superficial and scattered. As a result, I find these recommendations to be rather unsatisfactory.

In terms of practicality, the cheat sheet references several Netflix blog posts describing how Netflix addressed certain challenges. These processes are then presented schematically within the context of an authorization pattern. While interesting, this approach is not broadly helpful.

Don’t get me wrong: the content isn’t wrong, but it relies on too many implicit assumptions that reduce its usefulness in real-world scenarios. I’m deliberately taking a different approach: seeking to expose those hidden assumptions by making the relevant decision dimensions explicit.

The discussion of Authorization Patterns might suggest that Decentralized Service-Level Authorization should be avoided due to drawbacks such as scattered logic and limited auditability. However, this is not always the case. The suitability of an authorization pattern depends on the system context. This context can be analyzed along several key dimensions that guide the choice of appropriate patterns and help keep the system secure, manageable, and responsive, as outlined in this section.

What about the cost factor?

You might be wondering whether cost should be treated as a separate dimension — and I completely agree. After all, we don’t do security for its own sake, but to support (or even enable) the business. That’s why cost is always present in the background. Throughout this series, I’ve tried to reflect that — whether by discussing operational overhead, maintenance effort, or other practical trade-offs.

Policy Characteristics

Policy characteristics define how policies are authored, maintained, and updated, influencing their management and distribution. Two key dimensions, ownership and change latency, guide these processes, which are critical for operationalizing authorization systems.

Policy Ownership

This dimension identifies who owns and maintains a particular policy. Ownership matters in two ways: it often correlates with how composable or layered the policies need to be, and it also defines governance[1] boundaries, determining who is authorized to create, modify, and deploy policies.

  • Microservice Team: Policies authored and maintained by the team responsible for a specific microservice. These are typically focused on local enforcement logic and closely tied to internal service semantics. For example, a recommendation service defines request filters that exclude certain products based on internal scoring thresholds or active experiments.
  • Domain Level: Policies shared across services within a business domain, often requiring coordination between teams. These policies may be abstracted and reused across multiple services, like a subscription domain enforces business rules about grace periods, usage limits, or billing thresholds that are referenced by billing, customer portal, and notification services.
  • Central (Organization Level): Policies governed by a central security, compliance, or platform team. These typically apply across domains or services and provide the foundation upon which more granular policies are built, like an organizational policy that defines acceptable data residency constraints or standard access conditions for administrative APIs.

Policy Change Latency

This dimension describes how quickly a policy change must be reflected in the system once introduced. It should not be confused with the frequency of policy changes (how often they occur), or with input data freshness (how quickly attribute updates must be reflected in policy decisions). While policy change frequency influences governance and authoring processes, the latency dimension defines how fast policies must be deployed and propagated across services to take effect.

  • Immediate: Policies must take effect as soon as they are changed (seconds to minutes). Example: A financial system introduces a temporary block on a specific payment method due to detected processing errors. The rule itself (block this method) must be enforced immediately across all services to prevent further transactions.
  • Fast: Policies should be applied within hours to days. Example: A sales team requests an update to discount eligibility rules for enterprise customers. Once approved and authored, the new policy should be effective by the next business day.
  • Delayed: Policies can be applied on a longer timescale (weeks or more). Example: A data retention policy update mandated by new legislation is scheduled for enforcement with the next release.

Policy Distribution Strategies

The policy change latency dimension, described in the previous section, defines how quickly policy changes must take effect once introduced. These latency requirements directly influence how policies are delivered to PDPs to ensure they are available for evaluation in the system, which is what this section addresses. Here, we discuss the two primary strategies along with their respective trade-offs.

Out-of-Band Delivered Policies

Policies are proactively sent to the PDP and stored locally for evaluation. This strategy suits policies that tend to have immediate to fast change latencies, requiring agile, incremental updates without disrupting service availability.

PAP sends policy to the PDP
PAP sends policy to the PDP

Pros:

  • Enables applying policy changes dynamically without redeploying PDPs, supporting high availability.

Cons:

  • Requires robust synchronization mechanisms to deploy the correct versions of required policies to each PDP instance.
  • Demands governance mechanisms to ensure that policy deployment aligns with ownership boundaries. E.g., microservice teams should only be able to update their own policies, while domain or central teams retain control over shared or organizational policies.

This is where policy ownership becomes a critical factor, as it directly shapes the enforcement and governance model for policies and who is allowed to deploy which one.

Embedded Policies

Policies are embedded directly within the PDP (e.g. as code, or as static configuration) and cannot be updated without restarting or redeploying the PDP. This approach is best suited for policies that have delayed change latencies. Stability and operational simplicity are typically prioritized over agility in such cases.

Embedded policy
Embedded policy

Pros:

  • Simplifies policy management, as policies are bundled with the PDP.

Cons:

  • Increases deployment overhead, as changes involve rebuilding and/or redeploying the PDP.
  • Limits scalability for needs with frequent policy adjustments.
  • Introduces governance challenges, since the team deploying the PDP effectively decides which policies get bundled and activated, even if those policies are owned by different teams or organizational units.

Data Characteristics

Data characteristics define how information used during policies evaluation is sourced and managed. The first subsections focus on the input side and introduce three key dimensions: input data locality, input data cardinality, and input data freshness. The last subsection covers the characteristics of the output data — the output data cardinality.

Locality describes the scope within which data is relevant and shared, cardinality determines how much data must be managed, and freshness defines how often that data must be refreshed or fetched in real time. Taken together, these dimensions shape the feasibility and efficiency of authorization system design.

Input Data Locality

Locality defines the boundaries of data relevance and reuse, from tightly scoped to broadly shared:

  • Service-Local Data: Data relevant only within a single service, not reused elsewhere. For example, service-specific configuration flags affecting authorization decisions only inside that service, or ephemeral session attributes used exclusively by the service’s internal logic.
  • Domain-Level Data: Data shared across multiple services within the same bounded context or domain. Examples include ownership metadata of documents in a document management domain, customer account status (e.g., frozen, active, under review) used by both billing and support services, or time-based availability windows for booking or scheduling services.
  • Organization-Level Data: Relevant across domains or the entire system, such as regulatory classification of data (e.g., «EU personal data»), tenant-level subscription tier or plan.

Input Data Cardinality

Cardinality refers to the number of distinct attributes across all subjects or resources. It determines how easily data can be cached or distributed in an access control systems.

  • High: Many distinct data items, often tied to individual requests or users (e.g., a real-time risk score or geoip information).
  • Medium: Moderate number of distinct data items typically shared across sets of subjects or resources (e.g., project IDs).
  • Low: Few distinct data items. For example, environment labels (e.g., «production», «staging»), or business unit identifiers (e.g., «HR», «Finance», «R&D»).

Input Data Freshness

This measures the maximum acceptable delay between an attribute value changing, and that change being reflected in authorization decisions.

  • High: Changes must be reflected immediately or within seconds to maintain accurate authorization (e.g., real-time risk scores, breach detection flags).
  • Medium: Changes should be reflected within minutes to hours, balancing freshness and performance (e.g., feature toggles, subscription tiers).
  • Low: Changes can be reflected with delays of hours to days without significant impact.

Output Data Cardinality

As written in the story section, policy decisions often include more than just simple "permit" or "deny" responses. They may carry structured outputs that shape the final data set accessible to a subject — such as lists of permitted object IDs, query filters, or advices.

These outputs fall into two broad categories:

  • Metadata: Optional guidance or instructions to the PEP (e.g., log this access, display a warning).
  • Decision Data: The core result of policy evaluation — potentially including constraints, and similar information describing what access is allowed.

While the PDP returns the decision, its structure and size — the output cardinality — are defined by the policy logic, which reflects the needs of the consuming application. For example, if an application must render only the documents a user is allowed to see, the policy may be implemented to return a list of permitted document IDs, increasing output cardinality.

That way, the output cardinality can be grouped into three levels:

  • Low: Simple decisions with minimal metadata, such as { "result": true } or { "decision": "permit" }.
  • Medium: Decisions include multiple structured attributes or small lists. Example: { "allowed_projects": ["A", "B"] }.
  • High: Large or complex result sets, such as thousands of object IDs. These often require pagination or streaming. Example: { "resources": ["doc1", "doc2", ..., "doc5000"] }.

Policy Input Data Distribution Strategies

While the input data freshness dimension defines how quickly data changes must be reflected in access control decisions, input data cardinality can, depending on the PDP type, limit how much information can be stored or cached in practice, and with that also the ability to fully achieve that reflection. This challenge is especially relevant in PBAC systems.

This tension highlights a broader challenge for all approaches relying on embedded or external PDPs: how to make the right data available at evaluation time without overwhelming the system. To address this challenge, different strategies for distributing input data to PDPs have emerged. Each comes with distinct trade-offs, and their suitability depends on the PDP type (e.g., PBAC, ReBAC, NGAC) as well as on system requirements for performance, scalability, and freshness.

Each strategy addresses different operational concerns, and no single approach works universally. Mature systems often combine them, guided by data characteristics, performance targets, and architectural constraints.

On-Demand Data Pull

The PDP fetches data from PIPs at the time of policy evaluation, typically via APIs or database queries. PDPs supporting this option typically allow for configurable caching of the pulled data.

On-Demand Data Pull
On-Demand Data Pull

Pros

  • Ensures data freshness by retrieving the latest attributes values from PIPs at evaluation time.
  • Enables handling of high-cardinality data without preloading large datasets into the PDP.
  • No need for data synchronization mechanisms, since the PDP always queries the source directly.
  • Since the PDP does not need to maintain a local copy of data, the memory or storage demand of the PDP is low.
  • Governance responsibility is at the policy author — the policy defines where the data is retrieved from.

Cons

  • Increases latency due to network calls to PIPs during evaluation, which negatively impacts performance, especially for high-throughput systems.
  • Introduces dependencies on external systems, reducing resilience if PIPs are slow or unavailable, potentially leading to cascading failures, degraded service or fallback decisions.
  • Limits the usable PDP types, as ReBAC and NGAC implementations typically don’t support this strategy.
  • Degrades system performance when attributes are accessed repeatedly, especially for high-throughput systems.

While caching (if supported by the PDP) can mitigate some of these drawbacks, it undermines the freshness guarantee, potentially leading to incorrect authorization decisions. Moreover, caching also negates the low-storage advantage listed above — especially for high cardinality data.

Out-of-Band Data Push

Data is proactively sent to the PDP in advance, and stored in memory or a local data store for faster access during evaluation.

Out-of-Band Data Push
Out-of-Band Data Push

Pros

  • Improves performance by storing data locally (e.g., in memory or a local database), enabling faster policy evaluation.
  • Enhances resilience, as the PDP can operate independently of PIP availability, allowing PDP instances to remain lightweight and focused on evaluation, which improves their scalability.
  • ReBAC/NGAC PDP types typically require access to complete relationship graphs or contextual data sets, which are infeasible to retrieve on-demand or pass inline. This strategy enables those models.
  • Reduces load on the PDP by shifting data synchronization to other system components, allowing PDP instances to remain lightweight and focused on evaluation, which improves their scalability.

Cons

  • Requires robust data synchronization mechanisms to push updates to the PDP instances in real-time or near-real-time, especially for data with high-freshness requirements.
  • Increases memory or storage demands on the PDP, which is usually problematic for high-cardinality data.
  • Introduces governance complexity, as mechanisms, who can write to the event/topic the PDP listens to, or who can invoke the PDP’s API for updates, and which specific data each party is allowed to send, must be established.

Request-Time Data Injection

Required data is passed directly in the request from the PEP to the PDP — an approach often referred to as inline data passing. Early-stage standardization efforts (OpenID AuthZEN Initiative) aim to make this interaction more consistent and interoperable.

Request-Time Data Injection
Request-Time Data Injection

Pros

  • Ensures data freshness by providing the latest attributes values from PIPs.
  • Enables handling of high-cardinality data without preloading large datasets into the PDP.
  • Reduces load on the PDP by shifting data synchronization to other system components (the PEP), allowing PDP instances to remain lightweight and focused on evaluation, which improves their scalability.
  • Since the PDP does not need to maintain a local copy of data, the memory or storage demand of the PDP is low.
  • Typically, the only option for ReBAC and NGAC systems to provide attributes which are not stored in their databases.

Cons

  • Increases request size, as additional data is included in the decision request, potentially impacting network performance.
  • Places the burden on the PEP (e.g., microservice or edge component) to collect and validate data from PIPs, increasing complexity in the calling component.
  • Risks inconsistent data if the PEP fails to provide all required attributes or if data collection is misconfigured, potentially leading to incorrect decisions.
  • Can degrade system performance when attributes are accessed repeatedly by the PEPs.
  • Introduces governance complexity, as PEP configuration becomes a concern — it determines which attributes are fetched and sent to the PDP, as changes directly impact authorization decisions.

While caching (if supported by the PEP) can mitigate some of these cons, it introduces the risk of stale data, potentially leading to incorrect authorization decisions.

Embedded Data

Data is baked directly into the PDP’s configuration, rather than being pulled or pushed dynamically.

Embedded Data
Embedded Data

Pros

  • Zero runtime dependencies on external PIPs — the PDP is fully self-contained, which simplifies deployments.
  • No synchronization concerns; the data is always available and consistent.

Cons

  • Useful for static or rarely changing information only (e.g., «environment»: «prod», «region»: «EU»), and impractical for medium- or high-freshness data.
  • Introduces governance challenges similar to those described in embedded policies, as the team deploying the PDP effectively decides which data get bundled and used, even if those data elements are owned by different teams or organizational units.

Policy Output Data Handling Patterns

As stated earlier, access control requirements often go beyond simple cases like «can subject X read object Y?». In practice, most requests hitting a PEP involve multiple, context-sensitive decisions. This is especially true for read operations, such as deciding whether to render «edit» or «delete» buttons based on a user’s permissions.

These decisions can often be handled via batch requests, where the PEP sends multiple access queries in a single call, and the PDP evaluates them at once, returning one simple decision per item. However, access requests involving larger output data sets, such as for rendering a list of articles Alice is allowed to see, can, depending on the chosen approach, significantly affect output data cardinality and directly influence the choice of the possible authorization patterns.

The following subsections describe the typical patterns used in such cases.

PDP as Filter, aka Brute-Force Lookup

In this pattern, the PEP retrieves all potentially relevant data from a PIP (e.g., a database or API) and iterates over each item, querying the PDP to check whether access is permitted. If allowed, the item is included in the final result (e.g., rendered HTML or returned JSON).

PDP as Filter, aka Brute-Force Lookup
PDP as Filter, aka Brute-Force Lookup

Pros

  • Simple to implement.
  • Works with any PDP.
  • Easy to debug and monitor.

Cons

  • High latency and poor scalability for high-cardinality queries due to repeated PDP calls.
  • Increases resource consumption by retrieving more data than needed.
  • Tightly couples the PEP with the service’s business logic and makes externalizing the PEP (e.g., into a proxy) impossible.
  • Changes to access policies typically require service redeployments or even refactorings.

The first two cons might be partially resolved by making use of batch queries if the PDP supports that.

Authorized Data Set

In this pattern, the PEP makes a single request, and the PDP returns a complete set of allowed resources (e.g., object IDs). The PDP constructs this result based on policy logic and available attributes.

Authorized Data Set
Authorized Data Set

Pros

  • Reduces round-trips by returning all results at once.
  • Simplifies PEP logic, as the PDP handles the complexity of determining the authorized dataset.
  • Well-suited for ReBAC or NGAC PDPs, which can leverage internal data models to compute permitted resources.
  • Externalizing the PEP to e.g., an external proxy is only feasible for low to medium cardinality output data sets.

Cons

  • Might complicate error handling and monitoring of data access.
  • Require pagination or streaming for bigger output data sets.
  • Results in complex policies for PDPs implementing PBAC approaches.
  • Not supported by every PBAC PDP implementation.

Authorization Filter

In this pattern, the PEP calls the PDP, which returns a filter expression (e.g., a SQL WHERE clause, query predicate, or attribute-based condition). The PEP then applies this filter during data retrieval (e.g., in a database query) to fetch only the authorized data.

Authorization Filter
Authorization Filter

Pros

  • Highly efficient for large datasets — filtering happens at the PIP (data source).
  • Scales well with high output cardinality.
  • Reduces PDP load.
  • PDP does not need to not know all data sets.
  • Enables flexible PEP placement — as part of the service, or as an external proxy.

Cons

  • Not supported by every PDP (ReBAC und NGAC PDPs do not support that at all).
  • Might complicate error handling, monitoring of data access, and diagnosing related issues.

Performance

Last but not least, performance plays a critical role in the design of authorization systems — especially in latency-sensitive environments. From the end-user’s perspective, Time to First Byte (TTFB) is one of the most influential metrics, as described in Phil Walton’s article on user-centric performance metrics.

TTFB represents the time it takes for the first byte of a response to reach the client and reflects the perceived responsiveness of a system. It implicitly defines the latency budget available for upstream processes — including authorization decisions. This concept is further reinforced by the speed and human perception thresholds discussed in High Performance Browser Networking.

The following factors strongly influence architecture decisions — such as PDP placement and data handling — and directly impact whether the system can meet that latency budget:

  • Policy evaluation latency: The time a PDP takes to compute a decision depends on the number and complexity of policies and the input data cardinality — i.e., how many attributes must be evaluated.

  • Data retrieval latency: When attributes are fetched on-demand (see Policy Input Data Distribution Strategies), latency depends on the number of PIPs involved, the volume of data (input data cardinality), and its locality. This can add significant variability to response time.

  • Policy output handling: The output data cardinality and the selected output handling pattern affect the time required to process and apply the result.

  • PDP integration overhead: Overheads include network latency (ranging from ca. 300µs on loopback to >200ms for cross-region communication), DNS resolution, TLS handshake, and data serialization/deserialization. Protocol choices (e.g., HTTP/1.1 vs. HTTP/2 vs. gRPC) can further influence this. For in-process PDPs, these costs are minimized, though serialization costs may still apply.

  • Runtime resource contention: («Busy Neighbor» effect) PDPs are typically CPU- and memory-intensive. Co-located resource-hungry processes can significantly degrade performance if compute and memory isolation aren’t enforced. This is especially relevant when integrating a PDP into an edge component (either embedded or as a sidecar), which is often optimized for high IOPS throughput. In such cases, embedding a PDP introduces trade-offs between CPU-bound policy evaluation and I/O-heavy request processing.

  • Caching and memoization: Many PDPs implement decision caching or partial evaluation to avoid repeated computation for deterministic inputs. These optimizations can reduce latency but can lead to outdated decisions and require robust cache invalidation logic.

Additional considerations include:

  • Connection reuse and pooling: Using persistent connections, connection pooling, or multiplexed protocols (like gRPC or HTTP/2) helps amortize integration overhead and reduce connection setup time.

  • Fallback strategies and timeouts: Systems must decide how to behave when the PDP is slow or unavailable. Strategies such as fail-closed, fail-open, or graceful degradation are architectural decisions that directly impact perceived performance and security posture.

What’s next

I know, this was a pretty heavy article. But it laid the groundwork needed to answer the big question: Which authorization patterns are actually right for you?

All the pieces are already here, but to make the answer more tangible, in the next post I’ll bring them together into a visual guide — a kind of map or decision tree that makes the connections clearer. From there, we’ll build a broader pattern language that connects authentication, authorization, and identity propagation patterns to show how they influence each other. Finally, we’ll turn to the practical side: what these choices mean for real-world implementations and which open-source tools can help put them into practice.

  1. The term governance refers to a set of responsibilities and processes that keep authorization reliable. It defines who can create, change, or deploy policies, configurations, and the data those policies rely on. It also includes practical concerns — such as who owns a policy, who can update the PDP or its inputs, which attributes PEPs may send, and how changes are reviewed or audited. Put simply, governance is about keeping policies and data consistent so deployed rules don’t break and the system remains reliable and robust. In this article, whenever governance is mentioned, it refers to some or all of these aspects, depending on the context.  ↩