ZuploZuplo
LoginSign Up
  • Documentation
  • API Reference
Introduction
Getting Started
    Develop using the Portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingMCP - Quick start
    Develop Locally
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth
Concepts
Development
Policies
    Policy Catalog
    Authentication
    Authorization
      AuthZEN Authorization PolicyOkta FGA Authorization PolicyOpenFGA Authorization PolicyAxiomatics Authorization PolicyJWT Scope Validation PolicyAccess Control List PolicyRBAC Authorization PolicyGeo-location filtering PolicyIP Restriction Policy
    Security & Validation
    Metrics, Billing & Quotas
    Testing
    Request Modification
    Response Modification
    Upstream Authentication
    Archival
    GraphQL
    Other
    Guides
Handlers
API Keys
MCP Server
MCP Gateway
AI Gateway
Developer Portal
Monetization
Deploying & Source Control
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsSecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Authorization

OpenFGA Authorization Policy

Implement fine-grained authorization for your API using OpenFGA, a high-performance system based on Google's Zanzibar model. This policy verifies access permissions by checking relationships between users, objects, and actions.

With this policy, you'll benefit from:

  • Fine-Grained Access Control: Define precise permissions based on complex relationships
  • Scalable Authorization: Leverage OpenFGA's high-performance design for enterprise workloads
  • Flexible Implementation: Adapt authorization checks dynamically based on request context
  • Consistent Security: Apply standardized access control across your entire API
  • Relationship-Based Model: Express complex authorization scenarios using intuitive object relationships

Beta

This policy is in beta. You can use it today, but it may change in non-backward compatible ways before the final release.

Enterprise Feature

This policy is only available as part of our enterprise plans. It's free to try only any plan for development only purposes. If you would like to use this in production reach out to us: sales@zuplo.com

Configuration

The configuration shows how to configure the policy in the 'policies.json' document.

config/policies.json
{ "name": "my-openfga-authz-inbound-policy", "policyType": "openfga-authz-inbound", "handler": { "export": "OpenFGAAuthZInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiUrl": "https://api.us1.fga.dev", "authorizationModelId": "$env(FGA_MODEL_ID)", "credentials": { "method": "client-credentials", "clientId": "$env(FGA_CLIENT_ID)", "clientSecret": "$env(FGA_CLIENT_SECRET)", "apiAudience": "https://api.us1.fga.dev/", "oauthTokenEndpointUrl": "https://fga.us.auth0.com/oauth/token" }, "storeId": "$env(FGA_STORE_ID)" } } }

Policy Configuration

  • name <string> - The name of your policy instance. This is used as a reference in your routes.
  • policyType <string> - The identifier of the policy. This is used by the Zuplo UI. Value should be openfga-authz-inbound.
  • handler.export <string> - The name of the exported type. Value should be OpenFGAAuthZInboundPolicy.
  • handler.module <string> - The module containing the policy. Value should be $import(@zuplo/runtime).
  • handler.options <object> - The options for this policy. See Policy Options below.

Policy Options

The options for this policy are specified below. All properties are optional unless specifically marked as required.

  • apiUrl (required) <string> - The URL of the OpenFGA service.
  • storeId (required) <string> - The ID of the store.
  • authorizationModelId (required) <string> - The ID of the authorization model.
  • allowUnauthorizedRequests <boolean> - Indicates whether the request should continue if authorization fails. Default is false which means unauthorized users will automatically receive a 403 response. Defaults to false.
  • credentials (required) <undefined> - No description available.

Using the Policy

This policy integrates with OpenFGA to provide fine-grained authorization for your API endpoints. OpenFGA implements Google's Zanzibar authorization model, allowing you to define and check complex permission relationships between users and resources.

Usage

To use this policy, you must programmatically set the relationship checks to be performed against your OpenFGA store. This is done using the static setContextChecks method.

The most common way to set the authorization checks are:

  1. Creating custom inbound policies for each authorization scenario
  2. Creating a custom inbound policy that reads data from the OpenAPI operation and sets the authorization checks dynamically

Example: Custom Authorization Policies

Create a file like modules/openfga-checks.ts to define your custom authorization policies:

Code
import { ZuploRequest, ZuploContext, RuntimeError, HttpProblems, OpenFGAAuthZInboundPolicy, } from "@zuplo/runtime"; export async function canReadFolder( request: ZuploRequest, context: ZuploContext, ) { if (!request.params?.folderId) { throw new RuntimeError("Folder ID not found in request"); } context.log.info("Setting OpenFGA context checks"); if (!request.user?.sub) { return HttpProblems.forbidden(request, context, { detail: "User not found", }); } // Set the authorization check to verify if the user has viewer access to the folder OpenFGAAuthZInboundPolicy.setContextChecks(context, { user: `user:${request.user.sub}`, relation: "viewer", object: `folder:${request.params.folderId}`, }); return request; } export async function canEditDocument( request: ZuploRequest, context: ZuploContext, ) { if (!request.params?.documentId) { throw new RuntimeError("Document ID not found in request"); } if (!request.user?.sub) { return HttpProblems.forbidden(request, context, { detail: "User not found", }); } // Set the authorization check to verify if the user has editor access to the document OpenFGAAuthZInboundPolicy.setContextChecks(context, { user: `user:${request.user.sub}`, relation: "editor", object: `document:${request.params.documentId}`, }); return request; }

Applying to Routes

In your route configuration, apply both the custom authorization policy and the OpenFGA policy:

Code
{ "path": "/folders/:folderId", "methods": ["GET"], "policies": { "inbound": ["jwt-auth", "authz-can-read-folder", "openfga-authz"] } }

Then in your policies.json:

Code
{ "name": "authz-can-read-folder", "export": "canReadFolder", "module": "$import(./modules/openfga-checks)" }, { "name": "openfga-authz", "export": "OpenFGAAuthZInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { // OpenFGA configuration... } }

Example: Dynamic Authorization Checks

You can make your authorization checks more dynamic by reading data from your OpenAPI specification or other sources. This allows you to define authorization rules that adapt based on the route, method, or other request properties.

For example, you could access custom data defined in your route:

Code
export async function dynamicAuthCheck( request: ZuploRequest, context: ZuploContext, ) { // Access custom data from the route configuration const data = context.route.raw<{ "x-authz": { resourceType: string; permission: string; resourceIdParam: string; }; }>(); const authzData = data["x-authz"]; if (!authzData?.resourceType || !authzData?.permission) { throw new RuntimeError( "Missing resource type or permission in route config", ); } if (!request.user?.sub) { return HttpProblems.forbidden(request, context); } // Extract resource ID from request parameters const resourceId = request.params?.[authzData.resourceIdParam]; if (!resourceId) { throw new RuntimeError( `Resource ID parameter '${authzData.resourceIdParam}' not found`, ); } // Set dynamic authorization check OpenFGAAuthZInboundPolicy.setContextChecks(context, { user: `user:${request.user.sub}`, relation: authzData.permission, object: `${authzData.resourceType}:${resourceId}`, }); return request; }

Then in your OpenAPI document, you would set the custom data on the x-authz property:

Code
{ "paths": { "/custom-data": { "post": { "x-authz": { "resourceType": "document", "resourceIdParam": "documentId", "permission": "editor" } } } } } ### Policy Configuration To configure the OpenFGA policy, you need to provide connection details to your OpenFGA instance: ```json { "name": "openfga-authz", "export": "OpenFGAAuthZInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "apiScheme": "https", "apiHost": "api.openfga.example.com", "storeId": "YOUR_STORE_ID", "authorizationModelId": "YOUR_MODEL_ID", "credentials": { "method": "api-token", "token": "$env(OPENFGA_API_TOKEN)" } } }

Read more about how policies work

Edit this page
Last modified on May 29, 2026
Okta FGA Authorization PolicyAxiomatics Authorization Policy
On this page
  • Configuration
    • Policy Configuration
    • Policy Options
  • Using the Policy
    • Usage
    • Example: Custom Authorization Policies
    • Example: Dynamic Authorization Checks
JSON
TypeScript
JSON
JSON
TypeScript
JSON