Implementing Attribute-Based Access Control (ABAC) with Keycloak

Learn how to implement Attribute-Based Access Control using Keycloak, with backend integration in FastAPI and frontend enforcement in React.


Introduction

Modern applications often require more flexible access control systems than traditional role-based models can provide. Attribute-Based Access Control (ABAC) enhances security by evaluating user attributes like department, region, or clearance level. When paired with a powerful identity provider like Keycloak, ABAC enables fine-grained, contextual authorization for both backend and frontend systems. This post walks through implementing ABAC with Keycloak, using FastAPI on the backend and React on the frontend.

Table of Contents

What is ABAC and How Is It Different from RBAC?

Role-Based Access Control (RBAC) uses predefined roles assigned to users to determine access. It’s simple and works well for small to medium systems. However, ABAC (Attribute-Based Access Control) introduces flexibility by basing access decisions on user attributes (e.g., department, location), resource attributes, and environmental context.

For example, with ABAC, a policy might state: “Only users from the ‘engineering’ department and located in ‘EU’ can access the system after 9AM.” This allows granular and dynamic control based on real-world scenarios. RBAC is role-centric, while ABAC is context-aware.

ABAC is ideal for complex environments where user roles alone do not provide sufficient control. Combining both can yield hybrid models for robust security.

Using Keycloak’s Fine-Grained Authorization Features

Keycloak includes a powerful Authorization tab when using Authorization Services in client settings. This feature must be enabled manually for each client. Once active, it lets you define:

  • Resources: What you want to protect (e.g., endpoints, data scopes).
  • Scopes: Actions or permissions (e.g., read, write).
  • Policies: Rules that determine whether access is granted.
  • Permissions: Link policies and resources together.

Navigate to your client, enable “Authorization”, and use the GUI or admin REST API to manage ABAC configurations. You can configure attribute-based policies directly from the Keycloak admin console using JavaScript or role-based constraints.

Defining Attributes and Policies

User attributes can be created in the User Attributes section of a Keycloak user profile. These attributes (e.g., department, region, clearance) can then be referenced inside policies.

To create an attribute-based policy:

  1. Go to your client > Authorization > Policies.
  2. Choose JavaScript-based policy.
  3. Use code like:
var department = user.getAttribute("department")[0];
if (department === "engineering") {
    $evaluation.grant();
}

You can also create policies using Keycloak’s admin REST API for automation. Avoid hardcoding values and use dynamic user attributes for better scalability.

Enforcing ABAC in the Backend (FastAPI)

In FastAPI, use Keycloak-issued JWT tokens that contain user claims or query Keycloak’s /userinfo endpoint.

Here’s a minimal example using fastapi and python-jose:

from fastapi import Depends, FastAPI, HTTPException, Request
from jose import jwt
from starlette.status import HTTP_403_FORBIDDEN

app = FastAPI()
KEYCLOAK_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----..."
ALGORITHM = "RS256"

def get_current_user(request: Request):
    token = request.headers.get("Authorization").split(" ")[1]
    payload = jwt.decode(token, KEYCLOAK_PUBLIC_KEY, algorithms=[ALGORITHM])
    if payload.get("department") != "engineering":
        raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Not authorized")
    return payload

@app.get("/protected")
def protected_route(user=Depends(get_current_user)):
    return {"message": "Access granted", "user": user}

This ensures backend logic enforces attribute-based restrictions at runtime.

Integrating ABAC in the Frontend (React)

In the frontend, secure UI elements by conditionally rendering based on user attributes.

Use libraries like keycloak-js or @react-keycloak/web:

const user = keycloak.tokenParsed;

if (user?.department === "engineering") {
  return <AdminDashboard />;
}

Never rely solely on frontend logic for access control; it’s for usability only. The backend must remain the source of truth.

Store tokens securely (in memory or httpOnly cookies) and avoid storing sensitive attributes in localStorage or exposing them in URLs.

Combining RBAC and ABAC for Hybrid Access Control

Hybrid models use roles for coarse-grained control and attributes for fine-grained decisions.

For example, you can define:

  • RBAC: Only users with role admin can access /admin.
  • ABAC: Among admins, only those in the EU region can perform critical operations.

In Keycloak, you can combine both in a policy using logical constraints. This approach keeps policies modular, readable, and adaptable.

Best Practices for ABAC with Keycloak

  • Keep policies manageable: Avoid overly nested or complex conditions.
  • Secure attributes: Use trusted sources and avoid client-side injection.
  • Standardize attribute names: Maintain naming consistency across services.
  • Use decision caching: When appropriate, cache Keycloak decisions to reduce API calls.
  • Audit logs: Enable audit logging in Keycloak for tracking policy evaluations.

These practices ensure performance and maintainability in real-world systems.

Conclusion

ABAC adds powerful flexibility to access control by leveraging user attributes, context, and policy logic. Keycloak’s built-in tools, combined with a secure backend (FastAPI) and smart frontend integration (React), allow developers to implement robust and scalable authorization models. Blending ABAC and RBAC enables hybrid systems tailored to real-world business needs.

References

What’s Next?

  • Implementing Policy Decision Points (PDP) and Enforcement Points (PEP) with OPA
  • Managing Dynamic Attributes via Keycloak Mappers and User Federation
  • Fine-grained Audit Logging with Keycloak Events API
  • Distributed Authorization for Microservices with Keycloak and Envoy
  • Role Engineering: Designing Scalable Role/Attribute Hierarchies