By NHI Mgmt Group Editorial TeamPublished 2025-08-13Domain: Best PracticesSource: Cerbos

TL;DR: Scattered role checks in Spring controllers and services become hard to maintain as authorization rules grow, and Cerbos’ annotation-driven approach externalises decisions into policy, according to Cerbos. Separating authentication from authorization makes access control easier to audit, change, and test without redeploying application code.


At a glance

What this is: This guide shows how to move Spring authorization logic out of controllers and into Cerbos policies using annotations and AOP.

Why it matters: It matters because teams managing IAM, NHI, and application access need authorization that can change with policy instead of code redeploys.

👉 Read Cerbos' guide to policy-driven authorization in Spring Security


Context

Spring applications often start with role checks embedded in controllers and services, but that pattern breaks down once access rules depend on attributes, resource state, or business context. For IAM teams, the problem is not authentication. It is the growing gap between stable application code and changing authorization policy.

This tutorial frames authorization as an external decision layer rather than a hard-coded part of the business service. That matters to identity programmes because the same drift shows up in human access rules, service account permissions, and workload access decisions whenever policy is trapped in code.


Key questions

Q: How should teams avoid scattering authorization logic across Spring services?

A: Teams should move access rules out of controllers and into a policy engine, then trigger checks with annotations or interceptors. That keeps business code focused on application behaviour while authorization remains centrally managed, testable, and easier to update when rules change.

Q: When does policy-driven authorization make more sense than hard-coded role checks?

A: It makes more sense when access depends on attributes, ownership, or changing business rules. Hard-coded roles are fast to start with, but they become brittle when managers, departments, or resource context affect decisions and the policy needs to change without a redeploy.

Q: What do security teams get wrong about separating authentication and authorization?

A: They often treat them as interchangeable, but authentication proves identity while authorization governs permitted actions. When those controls are blended together, access logic becomes harder to audit and much harder to change safely as application complexity grows.

Q: How should organisations test policy-based access control before production?

A: They should test policies with representative principals, resources, and actions, then confirm that the policy engine returns the expected allow or deny result. Good testing also includes negative cases, ownership conditions, and role changes so exceptions do not slip into production unnoticed.


Technical breakdown

Externalised authorization decisions in Spring Security

Cerbos acts as a policy decision point that evaluates a principal, resource, and action against policies written outside the application. In this model, Spring Security still handles authentication and session context, while the authorization decision is delegated to an engine that can evaluate roles and attributes at request time. That separation lets developers keep business services focused on application logic while security rules move into a policy layer that is easier to test and update.

Practical implication: keep authentication in Spring Security, but route authorization decisions through a separate policy engine.

Annotation-driven access control with AOP

Aspect-Oriented Programming intercepts annotated methods before execution, extracts the relevant method parameters, and sends them to the policy engine. The annotation becomes the contract for what resource, action, and attributes should be checked, which avoids scattering permission logic across controllers. This pattern is especially useful when the same authorization rule must apply consistently across multiple endpoints or service methods without repeating code.

Practical implication: use an aspect to centralise authorization checks instead of duplicating conditionals in every endpoint.

Policy and derived role design for business-context access

Cerbos policies can express rules such as role-based read access, owner-only updates, or admin-only deletion, and derived roles can add contextual conditions like resource ownership. That is the key design shift: policy becomes a readable governance layer, and the application passes the attributes needed to make decisions. For teams with changing business rules, this reduces code churn and makes access logic more auditable.

Practical implication: model ownership and contextual rules in policy, not in controller-level branches.


NHI Mgmt Group analysis

Hard-coded authorization is a governance problem before it is a development problem. Once permission logic is scattered across controllers and services, policy changes become code changes, and code changes become release cycles. That creates a slow, error-prone control plane for access decisions. The practical conclusion is that authorization must be treated as a governed policy surface, not an implementation detail.

Annotation-driven authorization is strongest when it makes access rules visible without making them fragile. The Cerbos plus AOP pattern does that by keeping method signatures clean while still binding actions, resources, and attributes to a policy decision. That improves auditability because the check is explicit, but it also increases the importance of attribute quality and consistent resource modelling. The practical conclusion is that governance depends on clean input data as much as on the policy itself.

Policy drift debt: hard-coded business rules create hidden authorization debt that compounds as applications grow. The more endpoint-specific exceptions a team adds, the more likely it is that access behaviour will diverge from the intended policy model. That is a lifecycle problem as much as an application design problem. The practical conclusion is that teams should treat authorization refactoring as part of identity governance maturity, not just code hygiene.

Decoupling authentication from authorization aligns application design with modern identity governance. Authentication proves who the user is, but authorization determines what they can do in context, and those are different control problems. When the policy engine owns the decision, teams can version, test, and review access rules independently of application releases. The practical conclusion is that external policy evaluation is the cleaner operating model for applications that need frequent access-rule change.

The same pattern that reduces controller complexity also helps bridge human access policy and workload access governance. A resource, principal, and action model is familiar across human IAM, service-to-service permissions, and broader NHI governance. That makes policy-driven authorization easier to extend into environments where static roles are too blunt and manual reviews are too slow. The practical conclusion is that policy-as-code should be treated as a cross-domain identity control, not just an application convenience.

From our research:

  • Only 44% of developers are reported to follow security best practices for secrets management, exposing a significant developer behaviour gap, according to The State of Secrets in AppSec.
  • From our research: Companies are dedicating an average of 32.4% of their security budgets to secrets management and code security, with US organisations leading at 40.8%, according to The State of Secrets in AppSec.
  • If authorization rules live in code, teams inherit the same maintainability pressure that secrets programmes face, so Ultimate Guide to NHIs , Key Challenges and Risks is a useful next step for understanding sprawl and control drift.

What this signals

Authorization policy is moving toward a policy-as-code operating model because static application logic cannot keep pace with changing access rules. The practical signal for IAM and application teams is that controller-level checks will increasingly look like technical debt, especially where owner, department, or time-based conditions shape decisions.

Policy drift debt: once authorization rules are embedded in endpoints, every exception increases the distance between intended policy and actual enforcement. Teams should expect more demand for external policy engines, better policy testing, and clearer separation between identity proofing and access decisions.

For teams managing broader identity programmes, the lesson extends beyond Spring. The same governance pattern appears in human IAM, machine identity, and workload access control, which is why aligning application policy checks with NIST Cybersecurity Framework 2.0 access governance and OWASP Non-Human Identity Top 10 controls matters now.


For practitioners

  • Externalise authorization from controllers Move access rules out of endpoint code and into policy so updates do not require application redeploys.
  • Standardise the principal-resource-action model Pass consistent attributes for the subject, the target resource, and the requested action so policy checks remain predictable across services.
  • Use annotations only as decision triggers Keep annotations as the marker for where a check must happen, but make the policy engine own the actual allow or deny decision.
  • Version and review policies like code Store policies in source control, test them with representative identities, and review them whenever business rules or ownership models change.

Key takeaways

  • Scattered authorization checks create governance debt because every new rule forces more code changes, more testing, and more release coordination.
  • External policy evaluation makes access decisions easier to audit and change because the application supplies context while the policy engine owns the decision.
  • Teams that centralise authorization now will find it easier to extend consistent access governance across applications, workloads, and non-human identities.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10 address the attack and risk surface, while NIST CSF 2.0 and NIST Zero Trust (SP 800-207) set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
NIST CSF 2.0PR.AC-4Policy-based authorization maps to least-privilege access decisions in applications.
OWASP Non-Human Identity Top 10NHI-08Policy drift and scattered checks mirror non-human identity control drift patterns.
NIST Zero Trust (SP 800-207)PR.AC-1Context-aware access decisions fit zero-trust verification at request time.

Centralise access decisions and review whether application permissions align to least-privilege intent.


Key terms

  • Policy Decision Point: A policy decision point is the component that evaluates access requests against defined rules and returns allow or deny. In a modern identity architecture, it separates decision logic from application code so permissions can change without rewriting business services.
  • Derived Role: A derived role is a context-sensitive role created from conditions such as resource ownership, department, or relationship to the target object. It lets policy express business logic cleanly without hard-coding exceptions into controllers or service methods.
  • Policy As Code: Policy as code means access rules are stored, versioned, and tested in a machine-readable format rather than embedded in application logic. That makes authorization easier to audit, safer to change, and more consistent across teams and environments.
  • Aspect-Oriented Programming: Aspect-oriented programming is a software technique that separates cross-cutting concerns, such as authorization checks, from core business logic. In this pattern, an aspect intercepts execution and applies a rule before the target method runs.

Deepen your knowledge

NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are responsible for identity security strategy or NHI governance in your organisation, it is worth exploring.

This post draws on content published by Cerbos: policy-driven authorization in Spring Security with Cerbos and AOP. Read the original.

NHIMG Editorial Note
Published by the NHIMG editorial team on 2025-08-13.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org