Course contentsShow
← Node.js
Lesson 1053 of 1,9809. Authentication and Identity ManagementFree lesson

Building Custom Scopes for Resource Access

Develop a logic layer to restrict access to specific resource IDs based on scopes.

In this lesson, you will learn how to design a logic layer that restricts user access to specific resource IDs based on custom-defined authorization scopes.

While standard OAuth2 scopes like read or write are useful, they are often too broad. In complex applications, you frequently need to restrict a user to a specific subset of data, such as read:invoice:123. To implement this, we move beyond simple role checks and introduce a Scope Evaluator—a logic layer that parses requested scopes against the specific resource ID being accessed.

The Logic Layer Approach

Instead of hardcoding checks in your controllers, create a middleware or service that verifies if the user’s token contains a scope that matches both the action and the resource ID.

Consider this implementation pattern:

// A simple scope evaluator
const hasResourceAccess = (userScopes, action, resourceId) => {
  // Check for granular scope: "read:invoice:123"
  const granularScope = `${action}:invoice:${resourceId}`;
  
  // Or check for a broad admin scope
  return userScopes.includes(granularScope) || userScopes.includes('admin:all');
};

// Usage in a route
app.get('/invoices/:id', (req, res) => {
  const { id } = req.params;
  if (!hasResourceAccess(req.user.scopes, 'read', id)) {
    return res.status(403).send('Forbidden: Insufficient Scope');
  }
  // Proceed to fetch the invoice...
});

Why This Matters

By building this layer, you decouple your business logic from security rules. When a request comes in, the logic layer acts as a gatekeeper. If the user only has permission for invoice:123, the system rejects any attempt to fetch invoice:456, even if the user is authenticated and has the generic read permission.

This approach prevents Insecure Direct Object Reference (IDOR) vulnerabilities by ensuring that identity-based scoping is enforced at the earliest possible stage of the request lifecycle. It allows your system to scale security policies dynamically without altering your underlying database queries.

Key Takeaway: Restrict access by mapping custom scopes to specific resource IDs within a dedicated logic layer to ensure fine-grained authorization.