Default Policy vs. Fallback Policy

▶ Watch (18:22)

Out of the box, the default policy only checks authentication. The fallback policy does nothing. Michele recommends making the default policy match the fallback policy for secure-by-default design, requiring endpoints to opt into anonymous access. She demonstrated this by adding a fallback policy that requires both an API scope and a user role. Any endpoint without its own policy inherits this baseline. The demo also showed how to allow anonymous on the index page using the new minimal API approach with AddRazorPages options, replacing old reflection-based attributes.

Reusable Policies and the Requirement Handler Pattern

▶ Watch (31:10)

Michele demonstrated creating named policies like ‘admin’ using AddPolicy with RequireRole or RequireClaim. For flexibility, she separates the requirement from its handler, allowing DI injection of loggers and other dependencies. The requirement implements IAuthorizationRequirement; the handler checks the condition. She showed the same effect using inline RequireClaim or AddRequirements. The policy is then applied to specific minimal API endpoints via the map method, overriding the default. This pattern enables declarative, discoverable authorization across all routes.

Centralizing Authorization with External Policy Engines

▶ Watch (36:00)

Michele moved beyond hardcoded roles to an external policy loaded from JSON. The policy maps identity roles from the identity provider to application-specific roles and assigns permissions like ‘read’ and ‘list’. She then integrated PolicyServer, a centralized system, to manage policies per feature area. The demo showed how a policy can be updated in the UI and take effect immediately for the next API call. This approach supports auditing and dynamic permission changes without redeploying code. Minimal API metadata decorates endpoints with required permissions, read at runtime by the policy handler.

UI Authorization: Step-Up and Tag Helpers

▶ Watch (56:45)

Michele brought authorization to the UI layer. She added a ‘recent login’ policy that prompts for MFA after a session exceeds one minute. A tag helper on Razor pages evaluates a feature policy and hides buttons the user does not have permission for. The helper reads a policy name and resource from the HTML attributes, calls the authorization infrastructure, and suppresses output if denied. This avoids hardcoding visibility logic. The same metadata used for API endpoints can generate UI tags via CI/CD, keeping backend and frontend in sync.

Designing Authorization Architecture Up Front

▶ Watch (1:04:16)

Michele stressed that authorization design must happen before coding. The hardest part is modeling roles, permissions, attributes, and context (tenant, time, location). She outlined layers: per-feature CRUD permissions, role-to-permission mapping, and assignments (birthright or conditional). At enterprise scale with hundreds of micro UIs and APIs, a centralized system becomes essential. She recommends starting with a clear plan for features and sub-features, then overlaying the authorization model. The code patterns she demonstrated support that architecture, but the design drives it.

Notable Quotes

uh authorization is hard probably harder than your typical identity problem to solve Michele Leroux Bustamante · ▶ Watch (0:21)

role explosion where you suddenly are adding more and more roles Michele Leroux Bustamante · ▶ Watch (6:51)

token bloat is the bigger problem Michele Leroux Bustamante · ▶ Watch (7:08)

we don’t want to couple authentication and authorization Michele Leroux Bustamante · ▶ Watch (8:29)

the design is kind of like the first thing and pretty important Michele Leroux Bustamante · ▶ Watch (1:06:24)

Key Takeaways

  • Decouple authentication from authorization to avoid token bloat and role explosion.
  • Use policies and requirements for reusable, declarative authorization in endpoints.
  • Centralize authorization logic in external systems like PolicyServer for dynamic updates.

About the Speaker(s)

Michele Leroux Bustamante is Cofounder and CEO at Solliance (solliance.net), Founder of PolicyServer (policyserver.com), in addition to being a Cloud / Security architect, and a Microsoft Regional Director since 2003. Michele is recognized in many fields including software architecture and design, identity and access management, cloud and microservices architectures, security and compliance, and DevOps. During the past 25 years, Michele has held senior executive positions at several organizations, assembled and led high performing teams, and drove delivery and customer success at scale. Michele provides technical and business leadership at Solliance - and shares learnings through workshops, presentations and keynotes. Michele has been published regularly during her entire career including the best-selling book “Learning WCF” (O’Reilly 2007) and Developing Microsoft Azure Solutions 2nd Ed. (MS Press 2017).