Skip to content

Restful Authorization

DodaTech 2 min read

title: "RESTful Authorization — Scopes, Roles, and Resource Permissions" description: "RESTful authorization controls access to resources using scopes (fine-grained) or roles (coarse-grained), enforced through middleware on each endpoint." date: 2026-06-28 lastmod: 2026-06-28 weight: 21 tags: [apis, restful] }

RESTful authorization enforces access control through OAuth 2.0 scopes for fine-grained permissions or role-based access control for user-level authorization.

What You'll Learn

  • Scope-based authorization
  • Role-based access control
  • Resource-level permissions

Why It Matters

Authentication proves who you are. Authorization proves what you can do. Both are essential for API security.

Code Examples

# Scope-based authorization
from functools import wraps

def require_scope(scope):
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            if scope not in getattr(request, 'token_scopes', []):
                return jsonify({"error": "Insufficient permissions"}), 403
            return f(*args, **kwargs)
        return wrapper
    return decorator

SCOPES = {
    'users:read': 'View user information',
    'users:write': 'Create and update users',
    'users:delete': 'Delete users',
    'orders:read': 'View orders',
    'orders:write': 'Create orders',
}

@app.route('/users')
@require_scope('users:read')
def list_users():
    return jsonify([u.to_dict() for u in db.get_users()])

@app.route('/users', methods=['POST'])
@require_scope('users:write')
def create_user():
    return jsonify(db.create_user(request.json)), 201

# Role-based access control
class RBAC:
    ROLES = {
        'admin': ['users:read', 'users:write', 'users:delete', 'orders:read', 'orders:write'],
        'manager': ['users:read', 'orders:read', 'orders:write'],
        'user': ['orders:read', 'orders:write'],
    }

    @staticmethod
    def check_permission(role, permission):
        return permission in RBAC.ROLES.get(role, [])

# Resource-level authorization
@app.route('/orders/<int:id>')
def get_order(id):
    order = db.get_order(id)
    if not order:
        return jsonify({"error": "Order not found"}), 404

    # Check resource ownership
    user_id = getattr(request, 'user_id', None)
    if order.user_id != user_id and not RBAC.check_permission(request.user_role, 'orders:read'):
        return jsonify({"error": "Access denied"}), 403

    return jsonify(order.to_dict())
// Scope middleware
function requireScope(scope) {
  return (req, res, next) => {
    if (!req.user || !req.user.scopes.includes(scope)) {
      return res.status(403).json({
        error: 'Insufficient permissions',
        required: scope
      });
    }
    next();
  };
}

app.get('/api/users', requireScope('users:read'), (req, res) => {
  res.json(db.getUsers());
});

app.post('/api/users', requireScope('users:write'), (req, res) => {
  res.status(201).json(db.createUser(req.body));
});

Common Mistakes

1. Skipping Authorization After Authentication

Authentication alone doesn't grant access. Always check permissions.

2. Hard-Coded Roles

Roles and permissions should be configurable, not hard-coded.

3. No Resource Ownership Check

Users can access other users' data without ownership validation.

4. Overly Broad Scopes

A scope that grants read/write/delete to all resources is too broad.

5. Inconsistent Authorization Across Endpoints

Some endpoints check authorization, others skip it.

Practice Questions

  1. What is the difference between scopes and roles?
  2. What HTTP status code for insufficient permissions?
  3. What is resource-level authorization?
  4. How do you implement scope checking in middleware?
  5. What is the principle of least privilege?

Answers:

  1. Scopes are fine-grained permissions; roles are collections of permissions.
  2. 403 Forbidden.
  3. Checking if the authenticated user owns or has access to a specific resource.
  4. Extract scope from token and compare against required scope.
  5. Grant only the minimum permissions needed for the task.

Challenge: Implement RBAC for a REST API with admin, manager, and user roles. Add resource ownership checks for order endpoints.

FAQ

Should I use scopes or roles?

: Scopes for granular control in OAuth 2.0; roles for simpler user management.

Can I use both scopes and roles together?

: Yes. Scopes on the token, roles mapped to users in the database.

What is a 403 vs 401?

: 401 = unauthenticated; 403 = authenticated but not authorized.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro