Embeddable Policy Decision Points (PDPs) are changing how teams implement authorization. By running the PDP as a library within your application’s runtime (often powered by WebAssembly), you can achieve sub-millisecond authorization checks, minimal infrastructure overhead, and a smoother developer experience.
In this post, we’ll break down insights from a conversation between Alex Olivier, CPO and Co-Founder of Cerbos, and Mike Schwartz, host of Identerati Office Hours and the CEO of Gluu, on why embeddable PDPs matter, their benefits and trade-offs, and how you can start experimenting with this approach. You don’t need to have watched the livestream to follow along – but if you’re curious, you can check out the recording below.
A Policy Decision Point (PDP) is the component in an authorization system that evaluates policies and returns allow/deny decisions. If you've worked with traditional authorization tools, you’ve probably dealt with PDPs that live outside your application — separate services or sidecar processes that applications communicate with, for example, via a JSON/REST API. These setups can work, but they come with network latency, deployment complexity, and scaling headaches.
An embeddable PDP, by contrast, is one that a developer can load into their application runtime and use like a library – initialized in-process and invoked via simple function calls. In other words, the PDP runs within the same process as your application code rather than as an external service. It's fast. It's self-contained. And it’s especially useful when you’re dealing with UI rendering, edge deployments, or distributed systems.
Cerbos itself supports both models: a traditional PDP server and a build that compiles your policies down to an embeddable module.
The ePDP idea might sound obvious in hindsight, but it took the convergence of new tech (namely WebAssembly) and developer expectations for this pattern to hit its stride. We’ll dive into why WASM is such a game-changer for embeddable PDPs shortly, but first, let’s explore the benefits this approach brings.
Speed is the headline benefit. Since an embedded PDP runs within your application, authorization checks become as fast as a function call – no network hops, no IPC overhead. Every external call, even a local REST API, carries millisecond-level latency costs, which can add up if a page or operation requires dozens of permission checks. In contrast, an in-process check can typically be done in nanoseconds.
Once the PDP is embedded and initialized, there’s no further network involved – it feels just like calling a native function in your code. In fact, the response is usually synchronous and immediate. Even on a fast network, a call out to a service would be multiple milliseconds, plus it introduces a point of failure if the network is down. By eliminating that round-trip, you get not only low latency but also improved reliability - fewer things can go wrong when you’re not depending on an external service for every decision.
Mike asked about typical decision times with Cerbos’s embedded PDP (often called the “ePDP”). Alex explained it’s tricky to benchmark across environments (browsers, mobile devices, etc.), but the execution is definitely sub-millisecond for the policy logic itself. Most of any overhead tends to come from JSON marshalling or data handling, not the decision computation.
The bottom line: Embeddable PDPs can make authorization essentially instantaneous from the app’s perspective, which is crucial for use cases like dynamic UI rendering and high-throughput microservices. Users won’t tolerate a sluggish UI that waits hundreds of milliseconds just to decide what menu to show – and with an embedded PDP, they don’t have to.
Another major benefit is the drastic reduction in infrastructure complexity. Because the PDP is just a library, there’s no need to deploy a separate service or maintain a sidecar container for authorization decisions. This has several implications:
Instead of a fleet of sidecar containers or a cluster of PDP microservices, with an ePDP, you just distribute a WASM module or library with your app. This makes edge deployments much more feasible. Indeed, one motivation for embeddable PDPs is to push authz logic to the edge or client side (closer to users). Cerbos calls this “bringing authorization closer to user interactions” – e.g., running in a user’s browser or in a globally distributed worker – which further reduces latency and offloads work from your backend.
From a developer’s standpoint, working with an embeddable PDP can be far more straightforward than calling out to a service. You can use native language imports and function calls instead of constructing HTTP requests. Developer experience is key: integrating an authz engine as an in-app function call is simple, and there’s no need to learn how to deploy or configure an external system for it.
Consider the example of Cerbos’s embedded PDP JavaScript SDK. A developer can install it with npm install @cerbos/embedded
, import the module, and instantiate a local PDP with a URL to download policy bundles from Cerbos Hub, or a local policy bundle for a fully offline experience. Checking permissions then becomes as easy as calling a method like cerbos.isAllowed(principal, resource, action)
and getting a boolean result. There’s no context switch to a different service or format – it’s all in the same codebase and type system.
This local integration also makes testing and development easier. You can unit-test authorization logic without spinning up extra services. Avoiding the need to install agents or daemons on every developer’s machine (as some legacy systems required) is a huge relief. Embeddable PDPs basically act like any other code library, which is a familiar model for developers.
Finally, bringing authorization logic client-side opens up new possibilities that developers have wanted. One big use case that drove Cerbos to build an embeddable PDP was UI-level permissions – e.g. deciding in a single-page app which menu items to show, which buttons to enable, etc., based on the user’s role/permissions. In a complex web UI, you might have hundreds of these checks on one page. It’s not practical to call a server for each of them. With an in-browser PDP, the front-end can directly evaluate the policies and render the UI accordingly, resulting in a snappier interface. This improves the developer experience of building secure UIs – they can rely on a consistent policy engine on the client, rather than duplicating logic or hard-coding visibility rules. As Alex said, an embedded decision point lets you make “very quick presentational permission checks at the UI layer” without lots of network hops.
A recurring theme in the discussion was how WebAssembly (WASM) has enabled the rise of embeddable PDPs now, whereas this would have been hard to do a few years ago. WebAssembly is a portable binary format with near-native execution speed, originally designed for the web but now usable in many environments. There are a few reasons WASM is a perfect fit for authorization engines:
.wasm
module can then run in any WASM runtime – in a browser, in Node.js, in a Go program, or in edge runtimes like Cloudflare Workers. All major browser vendors support WebAssembly, and it’s not just for the browser; serverless platforms use it too. This means an authorization engine compiled to WASM truly achieves the “write once, run anywhere” dream – without requiring each target environment to have a custom build. The WASM runtime is already present in many places (browsers, for example), so you just supply the module and load it.In short, WASM is the technical enabler that has made embeddable PDPs viable at scale. It provides the speed, small size, and portability that authorization engines need to run anywhere, from a backend service to a user’s browser, without heavy rewriting. This is why you’re seeing projects like Cerbos compile policy engines to WASM and even others in the industry experimenting similarly. We’re essentially leveraging the billions of devices with WASM runtimes already available.
For those interested in the technical deep-dive, the Identerati episode goes into analogies of WASM vs. things like Java applets or ActiveX, and why this time the technology is sticking. But the key takeaway is: WASM has unlocked a new distribution model for authz logic.
No architectural approach is without trade-offs. Alex and Mike also candidly discussed some of the challenges and common objections associated with pushing PDPs out to the “edge” - whether that edge is the front-end, mobile device, or just many distributed instances. Let’s examine those concerns and how to address them.
The objection: “We can’t run an authorization decision in the browser (or at the edge) because it might need to query our database or another API to get additional context (e.g., is user X on call right now?)”. In other words, some policies depend on dynamic data that the PDP would traditionally fetch from an internal source. How can an isolated PDP, running on a user’s device, perhaps, evaluate those?
The insight: This is essentially the debate of stateless vs. stateful PDPs. Alex’s position (and Cerbos’s design philosophy) is that a PDP should be stateless – it should not itself reach out to databases or external APIs during policy evaluation. Instead, any external information needed should be provided to the PDP as input (context). In practice, this means the responsibility shifts to either the calling application or the identity/token layer to supply necessary attributes.
For example, if the policy needs to know “is user X on call?”, the application could call the relevant service or database itself, since the app likely has network access to do so, then include that information in the request to the PDP. Mike phrased it well: “Nothing stops the application from calling an API to find out… and then submitting that into the policy check”. The key is that you don’t want the PDP module itself making arbitrary network calls at decision time – that could introduce unpredictable latencies and loads on other systems, and it complicates scaling - every PDP instance would need connectivity and credentials to query those systems.
By keeping the PDP stateless, the system remains predictable and efficient. As Alex noted, if your authorization service was calling out for data on each decision, a “small policy change” could accidentally hammer another service with a load it wasn’t prepared for. And if authorization is in the critical path, any delay in fetching that state externally delays the whole request. A stateless PDP avoids this by requiring all needed context up front – it either has what it needs in the input or it returns a decision based on the given data, nothing more.
The trade-off: Of course, making the application gather data adds some work for developers. It means you need to plan what info to pass to the PDP. In many cases this is not too bad – often the necessary data is already at hand (e.g., the user’s role or plan tier is in their JWT, the resource’s owner is known from the database because the app had to fetch the resource to act on it anyway). Token-based architectures can help here: you can enrich JWT tokens with custom claims so that they carry things like roles, tenant, or other attributes needed for authz decisions. Indeed, one point raised was that we as an industry might need to get better at token enrichment so that edge decision points have rich context. (If your current identity provider makes it hard to add claims to tokens, you might consider more flexible options or use a middleware to inject claims.)
There will be corner cases where truly no single component has all the info readily. For instance, in a strict microservices domain separation, Service A might need info owned by Service B to make a decision. In such cases, you might choose to handle authorization differently (maybe Service B has its own PDP). The speakers pointed out that not all policies need to be centralized in one PDP. You could have different PDPs for different domains, each with policies relevant to that domain. This way, each PDP has local access to the data it needs. It’s a shift from thinking “one huge PDP to rule them all” toward a more distributed or modular policy evaluation approach – which aligns well with microservices design.
Best practice: Keep your embeddable PDP logic focused on evaluating rules with given inputs. Do heavy data fetching outside the PDP. Use tokens or caching at the application layer to supply attributes. This yields a more deterministic and performant system. Yes, it requires careful architecture, and possibly cooperation from your identity provider to include more claims, but for the majority of authorization checks, it’s very feasible. In fact, Mike estimated that most policies apps need can be decided with info the app already has in the request context. Don’t let the few edge-case policies dictate an overly complex design for all policies.
This is related to the above point but worth singling out. Tokens, like JWTs, are often the vehicle to carry user information to a distributed PDP. One concern raised is: “What if my current IAM/SSO system doesn’t give me all the info I need in the token? I feel stuck having to call backend APIs then.” In the livestream, someone specifically said “we can’t change how our IdP emits tokens”, referring to a well-known cloud IdP that might limit custom claims.
The response was essentially: we as architects can push for tokens to be richer, because that makes the whole system more powerful. If your IdP or authentication layer can be configured or extended, invest the effort to include roles, group memberships, or other key attributes in the token at login time. Even if the token becomes a bit larger, it can be worth it, because it travels with the user and spares many lookup calls later. However, deciding what information to add to a token requires careful consideration. Overloading tokens with too much data can lead to issues such as increased token size and difficulties in managing stale information.
In practice, if your IdP is inflexible, you could have an identity orchestration layer or use hooks in your authentication flow to enrich tokens - for example, using a custom API call at login to add claims, or moving to an IdP that supports more customization. This allows you to ensure that tokens carry just enough information for the PDP to function effectively, without becoming bloated. The benefit for an embeddable PDP scenario is huge: with a well-enriched JWT, a front-end or edge PDP can make decisions immediately based on token claims and local context, with no further calls.
Perhaps the most novel challenge with embeddable PDPs is how to manage many PDP instances running out in the field. With a central PDP service, you had one, or a few, places to update policy and collect logs. Now, if you have an embedded PDP in every browser, mobile app, or edge node, how do you ensure they all have the latest policy and how do you aggregate their decision logs?
Policy updates: The conversation acknowledged this is non-trivial, but solvable. If your embedded PDP is compiled to a module (e.g., a WASM binary that includes the policy bundle), distributing updates might mean shipping a new module. Approaches to manage this include using a CDN or cloud service to host the latest bundle and having clients download it when updated. In fact, Cerbos provides an enterprise authorization management solution - Cerbos Hub, that automates this: every time you update your policy repo, it builds a new WASM bundle and pushes it to a CDN. The embeddable PDP SDK can be configured with that bundle URL and even set to auto-fetch updates. Under the hood, the CDN URL redirects to the newest version, so apps can periodically check the same URL and get new policies when available. For example, Cerbos’s JS AutoUpdatingLoader
will poll Cerbos Hub for updates and swap in the latest bundle seamlessly.
If a device is offline, it obviously can’t get updates until it reconnects. This is similar to how browsers handle updates to scripts or how mobile apps might fetch new config – you might cache the last known good policy and update when possible. Content addressing, cache-busting techniques, and robust delivery networks exist to make sure that once online, an embedded PDP can sync up to current policy.
Audit logs: Each PDP instance might produce logs of decisions for compliance or debugging. How to gather them? One approach is to have the PDP call back to a logging endpoint whenever it makes a decision. Cerbos’s embedded PDP, for instance, allows the host application to provide a callback or “transport” to handle log events. In a browser, that might queue them to send in batches; in a mobile app, maybe store and upload later when connected. It does put more onus on the application or supporting infrastructure to collect these distributed logs. There isn’t a one-size solution yet, but vendors like Cerbos are building tooling for this. Mike noted that this is an area where enterprise features will differentiate – e.g., how well a solution can securely and reliably gather those distributed audit trails.
Operational mindset: Running “millions of mini-PDPs” sounds daunting, but remember, each one is fairly simple and self-contained. Think of it like how content delivery works – you might have thousands of caches but you manage them through automation. Similarly, you will want an automated way to publish policy updates and ingest logs. Using a management hub like Cerbos Hub can centralize the control-plane aspects while decentralizing the enforcement. If done right, you get the best of both: centralized policy authoring and visibility, with decentralized, ultra-fast enforcement at the edges of your system.
One point Alex made is that adopting embeddable PDPs doesn’t mean you must abandon all centralized authorization services. Hybrid models are perfectly valid. You might decide that for your core domain data on the backend, a traditional PDP service is fine, but for front-end UI controls or certain edge microservices, you use an embeddable PDP. You could even use multiple PDP implementations if needed (though you’d want them to share a common policy language or definitions to avoid confusion).
For example, an enterprise might have a legacy PDP for some older apps, a new embeddable PDP for a greenfield front-end project, and maybe another open-source engine in a specific component – all coexisting. While consolidation has its benefits, Mike quipped that large enterprises “have one of everything” and a heterogeneous environment is realistic. The key is to manage your policies and rules in a sane way across these. Using a flexible policy language and toolset that can target both service and embedded deployments, as Cerbos does, helps share at least the policy definitions across different enforcement points.
The takeaway here is: use the right tool for the job. If 90% of your authorization needs can be met with an embeddable PDP, but 10% truly require server-side aggregation of data, you might run a central PDP for that 10%. This isn’t all-or-nothing. Over time, as technology improves, the pendulum may swing more toward fully distributed authz, but you can adopt it gradually.
If you’re wondering whether embeddable PDPs are worth the effort, here are a few ideal use cases.
Use Case | Description |
---|---|
Rich client-side apps | Imagine a complex single-page application (SPA) like an admin dashboard where what a user can see and do depends on their permissions. Embeddable PDPs allow the front-end to enforce those rules instantly. As Alex recounted, use cases like showing/hiding menu items or enabling buttons based on roles were a big driver. Rather than hard-code those rules or make the client call the server for each check, the client can carry a policy bundle and evaluate it locally. This makes the UI more responsive and ensures consistency with backend enforcement (since the same policies can be evaluated on the server for API calls as well). |
Mobile and offline applications | Mobile apps (iOS/Android) often need to function with intermittent connectivity. An embeddable PDP, running in a React Native context, for example, lets the app make authorization decisions even when offline, using the last-known policies. For instance, a field sales app could enforce which records a rep can view or edit while offline and properly enable/disable UI elements. Once connectivity is back, logs of those decisions could sync up. Without an embedded PDP, offline authz would be impossible or insecure - you’d have to either allow everything or risk hard-coding stale rules. |
Edge computing and CDNs | Modern architectures deploy code at edge locations (CDN workers, serverless edge functions) to be as close to users as possible. Think about an edge API gateway that needs to do authz before forwarding a request, or a personalization service at the edge showing content based on user role. Embedding a PDP in those edge functions means they don’t all have to call back to a central authz service, which would defeat the purpose of being at the edge. Cerbos has showcased using their WASM PDP in a Cloudflare Worker to authorize requests right at the CDN level. This pattern can reduce load on the core services and ensure that even if the connection to the core is down, edge locations enforce the last known policies. |
High-throughput microservices | In microservice architectures, services often call each other. If each call requires an authz check and that check goes over the network to a PDP, you add a lot of latency and potential failure points in the chain. By embedding the PDP in each service, you localize those checks. This can be especially helpful for real-time systems or internal services where even tens of milliseconds matter. |
In all these cases, the common thread is bringing the decision engine closer to where the action is happening – whether that’s the user’s device or the edge of the network or simply within the same process as a calling service. By doing so, you remove latency, reduce dependency on central infrastructure, and often simplify the logic of the calling application, since it just asks the local PDP and proceeds.
If you’re intrigued and want to try an embeddable PDP in action, you can sign up for a free Cerbos Hub account to start experimenting. Cerbos provides a full-featured authorization engine that can run as a service or be compiled to an embedded WASM module. Here’s how you can get your hands dirty:
admin
can delete
a document
resource, others cannot.”@cerbos/embedded
on npm). In other languages, you can interface with the WASM runtime directly. Using the JavaScript SDK as an example, you instantiate the PDP by pointing it to the bundle URL provided by Cerbos Hub. The SDK will fetch the WASM module (and keep it updated if you use the auto-loader). Then your code can perform checks by calling methods on this PDP instance.if (user.role === 'admin') { ... }
, you might do:const allowed = await cerbos.isAllowed({
principal: { id: user.id, roles: user.roles, attr: user.attributes },
resource: { kind: "document", id: doc.id, attr: doc.attributes },
action: "delete"
});
if (!allowed) {
return res.status(403).send("Forbidden");
}
// proceed with deletion
This check will be evaluated by the embedded PDP using the policies you wrote. The call is local – no network – so it returns almost instantly with an allow/deny answer.
Cerbos also has documentation and quick-start guides for various frameworks. Those resources are helpful to get familiar with writing policies and using the API. When you’re ready, deploying an embedded PDP is just a matter of including that module with your app.
For a hands-on tutorial, check out our blog post “Authorize on the edge with Cerbos Hub and Embedded PDP bundles”. It walks through setting up Cerbos Hub and adding an embedded PDP to a sample Node.js application, very similar to the steps above. Following such a guide will give you a concrete feel for the developer experience – which, as we emphasized, is designed to be friendly and requires no complex infrastructure.
Embeddable PDPs represent a significant shift in how we think about authorization architecture. Instead of a monolithic, central decision service, we now have the option to distribute the decision making out to the edges of our systems – whether that’s a user’s browser, a mobile app, or a globally deployed serverless function. This shift is made possible by technologies like WebAssembly and by rethinking old assumptions (for instance, that an authz service must always call back to a central database).
From the conversation with Alex Olivier and Mike Schwartz, it’s clear that the motivation for this shift is rooted in very practical needs: performance, reliability, and simplicity. Users demand lightning-fast interfaces; developers crave simpler integrations and less ops burden; architects aim for resiliency and scalability. Embeddable PDPs check all those boxes by eliminating network latency, requiring virtually no extra infrastructure, and fitting naturally into modern deployment environments.
Of course, adopting this model requires careful consideration of trade-offs: you’ll need to design your app to supply the necessary context to the PDP (favoring stateless design), invest in token enrichment and caching strategies, and use tooling to manage the distribution of policy artifacts and collection of logs. The good news is that the ecosystem is responding – projects like Cerbos are actively building support to make these aspects easier - for example, Cerbos Hub automating policy distribution and providing the same API for checks whether in service or embedded mode. As Alex noted, it’s all about flexibility: once you have an embedded PDP, “it can run essentially anywhere”, giving you the freedom to place authorization logic where it makes the most sense.
For developers and architects, now is a great time to experiment with embeddable PDPs. Even if you start by using it just for front-end permissioning or a specific microservice, you can gain confidence in the approach. Many organizations might end up with a hybrid approach, and that’s okay – you don’t have to flip a switch on everything overnight. But the trend is clear: as we distribute our applications and push functionality to the edge for speed, authorization is following suit. Embeddable PDPs are rising because they align authorization with the distributed, cloud-native world we’re in.
In the words of Mike Schwartz’s summary of the session: “Embeddable PDPs offer sub-millisecond response, less infrastructure, and a developer-friendly model. They bring authorization closer to where interactions happen.” For a tech leader, the value proposition is compelling – better performance and user experience, with potentially lower cost of ownership, since there’s no dedicated authz service to maintain. As you plan the evolution of your access control systems, consider giving embeddable PDPs like Cerbos a try. They just might become a fundamental part of your architecture going forward.
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.