Backstage Permission Policy Returns Unexpected Deny
In this tutorial, you'll learn about Backstage Permission Policy Returns Unexpected Deny. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
A permissions policy you wrote in Backstage returns unexpected DENY results or is never evaluated.
Wrong ❌
// packages/backend/src/permissions/policy.ts
class CustomPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery,
user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
// Always denies if user has no defined role
if (!user?.identity?.ownershipEntityRefs) {
return { result: AuthorizeResult.DENY };
}
return { result: AuthorizeResult.ALLOW };
}
}
Wrong Output
GET /api/catalog/entities 403 Forbidden
Permission denied: catalog.entity.read
User has no ownershipEntityRefs set even though user exists in the system
Right ✅
class CustomPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery,
user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
if (!user?.identity?.ownershipEntityRefs?.length) {
// User not logged in or incomplete identity - allow basic read
if (request.permission.name === 'catalog.entity.read') {
return { result: AuthorizeResult.ALLOW };
}
return { result: AuthorizeResult.DENY };
}
// Check permissions based on user roles
return this.evaluatePermission(request, user);
}
private evaluatePermission(
request: PolicyQuery,
user: BackstageIdentityResponse,
): PolicyDecision {
return { result: AuthorizeResult.ALLOW };
}
}
Right Output
GET /api/catalog/entities 200 OK
Permission granted: catalog.entity.read for user@example.com
Prevention
- Never use blanket DENY for unauthenticated users for read operations; return ALLOW for public data.
- Log permission policy evaluations in development to debug unexpected DENY results.
- Use the permission testing utility: backstage-cli permissions:verify.
- Define permission rules with clear criteria rather than generic conditions.
- Add unit tests for each policy evaluation path.
DodaTech applies similar defensive patterns across Doda Browser, DodaZIP, and Durga Antivirus Pro infrastructure for production reliability.
Common Mistakes with permission policy
- Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
These mistakes appear frequently in real-world BACKSTAGE code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
This quick fix is part of the DodaTech infrastructure engineering series. Learn more at DodaTech tutorials.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro