--- published: true layout: post title: 'Who Decides? Policy-Based Authorization for Government APIs' image: https://kinlane-images.s3.amazonaws.com/apievangelist/api-evangelist-images/who-decides-policy-based-authorization-for-government-apis.png date: 2026-07-30 author: Kin Lane tags: - API Authorization - Policy Based Access Control - AuthZEN - Digital Government - Germany - API Governance - Zero Trust --- This is the fifth post in my series on [Germany's federal API authorization blueprint](https://apievangelist.com/2026/07/16/germany-built-the-api-authorization-blueprint-the-rest-of-government-needs/). The last four posts got a verified, sender-constrained client all the way up to the door of an API. Today is about the question that starts the moment it arrives: *who decides what it is allowed to do* — and where that decision lives. This is the layer where most homegrown API security quietly falls apart, and it is the layer where Germany's design is at its most disciplined. Let me start with the anti-patterns, because Germany's own deck names them and they are painfully familiar. Each service doing its own authorization. Coarse-grained roles baked into the application code. If-then-else permission spaghetti threaded through every endpoint. Misusing OAuth scopes as if they were permissions. Missing or inconsistent authorization logs. If you have worked inside any large API estate, public or private, you have seen every one of these, and you know how they end: nobody can answer the question "who can access this, and why?" without reading source code across a dozen repositories. The modern answer, and Germany's answer, is to stop scattering authorization logic and instead build it as a purpose-built, policy-based capability with a clean separation of concerns. That separation has a well-established vocabulary, drawn from XACML and from [NIST's own guidance on attribute-based access control (SP 800-162)](https://doi.org/10.6028/NIST.SP.800-162), and it is worth knowing cold because it is the skeleton of the whole thing. There is a **Policy Enforcement Point**, the PEP, which intercepts a request and enforces whatever it is told — and, critically, contains no clever logic of its own. There is a **Policy Decision Point**, the PDP, which evaluates the request against the policies and the available attributes, returns a permit or deny, and owns the audit log; this is the critical component. There is a **Policy Administration Point**, the PAP, the single authorized way to write and distribute policy. And there is a **Policy Information Point**, the PIP, which feeds the decision point the extra attributes it needs from authoritative sources. Enforce, decide, administer, inform — four roles, cleanly split, so that the thing guarding the door is dumb and the thing making the decision is centralized, consistent, and auditable. The model Germany runs on top of those roles is a hybrid of policy-based and attribute-based access control, and the shape of it is very practical. Each target API gets its own policy rules. A rule defines conditions and exceptions, an effect — permit or deny — and, on permit, the API scopes it grants. The criteria that drive the decision are *characteristics of the client*: attributes like the type of agency it represents, or its regulatory function, expressed as things like "the subject's regulatory function is one of this set." A single rule can target one specific client or thousands at once, filtered by business process, authority, sector, or stage. When multiple rules match, the combining algorithm is deny-overrides, and the default when nothing matches is implicit deny — you are not authorized unless a policy affirmatively says so. This is least privilege expressed as executable policy instead of as tribal knowledge, and every decision traces back to specific policy identifiers and the exact scopes it granted, which is what makes it auditable in the way the anti-pattern list is not. Now the part I found most thoughtful, because it is where government reality usually breaks clean architectures: *where* do these decisions get made, centrally or locally? Germany's answer is a deliberate split. **Coarse-grained** permissions — the platform-wide questions of whether an actor or a system is even allowed to operate on the platform and reach a given API — are governed centrally, so the federation has consistent framework rules. **Fine-grained** permissions — the domain-specific, object-level decisions that require real subject-matter knowledge — are pushed down to the domain federations that own the data and the context. Their reasoning is that fine-grained authorization is a *business* decision, and the platform has no business centralizing logic it does not understand. They even left the question of whether a given service centralizes or decentralizes its authorization check up to the responsible domain, because they concluded it is not a purely technical decision to make from the center. That restraint — knowing what *not* to centralize — is the mark of people who have built federated systems before. Two more choices make this real rather than theoretical. First, the decision points are designed to keep working even when the central plane is unavailable: policies and attributes are cached locally and synchronized by polling, so a PDP can keep authorizing through an outage of the components that feed it, with no inbound network dependencies — a resilience property, and one that any agency security reviewer will demand. Second, and this is the interoperability keystone, the interface between the enforcement point and the decision point is standardized on [OpenID AuthZEN](https://openid.net/wg/authzen/), which they describe as "the OAuth for authorization." That single choice is what stops twenty agencies from each buying an incompatible policy engine and welding it in. A standard PEP-to-PDP protocol gives you platform compatibility, reusability, a clean building block for Zero Trust, and freedom from vendor lock-in in the one place lock-in hurts most. For US and European agencies, the encouraging news is that you are already most of the way here. The role model is straight out of NIST. [Open Policy Agent](https://www.openpolicyagent.org/) is already the de facto policy engine across a lot of government, and Germany's polling-based synchronization is literally how OPA bundles work, so their decision-point pattern is implementable on tools you may already run. AuthZEN gives that engine a standard front door. The move to make is to stop treating authorization as something each service improvises, and start treating it as shared infrastructure with these four roles, a policy-based model, a coarse-central/fine-local split, and a standardized decision interface. Next in the series I turn to how Germany makes all of this *trustworthy* to people who do not, and should not have to, trust the operators — through transparency logs and security signals.