Authorization Guide

This guide provides an in-depth look at how authorization works within our APIs, ensuring that users and applications only access resources they are permitted to. We will cover the core concepts, common patterns, and best practices for implementing secure authorization in your applications.

Understanding Authorization

Authorization is the process of determining whether a user or application has the necessary permissions to perform a specific action or access a particular resource. This is distinct from authentication, which verifies the identity of the user or application.

Key Concepts

Common Authorization Models

Role-Based Access Control (RBAC)

RBAC is a widely adopted model where access decisions are based on the roles assigned to users. Each role has a set of permissions. This simplifies management by grouping permissions into roles rather than assigning them individually to users.

Example: Checking user role for resource access

Imagine an API endpoint that allows administrators to delete users. The server would check if the authenticated user has the 'Administrator' role before proceeding.


if (user.hasRole('Administrator')) {
    // Allow deletion
    deleteUser(userId);
} else {
    // Deny access
    throw new ForbiddenError('Insufficient permissions');
}
                

Attribute-Based Access Control (ABAC)

ABAC offers a more granular approach where access is granted based on a set of attributes associated with the user, the resource, the action, and the environment. Policies are defined using these attributes.

Example: ABAC policy for sensitive data access

A user can only access sensitive financial data if they are in the "Finance" department AND the current time is within business hours.


policy: {
    description: "Access to sensitive financial data",
    rules: [
        {
            effect: "allow",
            conditions: {
                AND: [
                    {"attribute": "user.department", "operator": "equals", "value": "Finance"},
                    {"attribute": "environment.currentTime", "operator": "between", "value": ["09:00", "17:00"]}
                ]
            }
        }
    ]
}
                

Implementing Authorization with OAuth 2.0 Scopes

When integrating with our APIs using OAuth 2.0, applications request specific scopes during the authorization flow. These scopes define the granular permissions the application is granted for the user's account.

Common Scopes:

When an API request is made, the token will contain the granted scopes. The API endpoint must validate that the token includes the necessary scope for the requested operation.

Example: Verifying scopes in an API request


function handleApiRequest(request) {
    const token = request.headers.get('Authorization');
    const requiredScope = 'data.read.all';

    if (!token) {
        throw new UnauthorizedError('No token provided.');
    }

    const claims = decodeToken(token); // Assume decodeToken extracts claims from JWT

    if (!claims.scopes || !claims.scopes.includes(requiredScope)) {
        throw new ForbiddenError(`Required scope '${requiredScope}' not granted.`);
    }

    // Proceed with accessing the data
    return fetchData();
}
                

Best Practices