Skip to main content
Use these patterns to integrate Oso Cloud securely and scale authorization across your application. For vendor-agnostic authorization guidance, see the Authorization Academy.

Quick Path — Which API to Use at Each Layer

LayerPurposeCommon ChecksRecommended Oso API
Service (request-level)Coarse-grained access for incoming HTTP requestsAdmin-only routes, tenant isolationauthorize
Business logic (resource-level)Fine-grained checks inside handlersOwnership, action-specific permsauthorize
Data access (query-level)Return only authorized results from DB/searchMulti-tenant filters, search boundarieslist
Presentation (client-side)Conditional UI renderingShow/hide buttons, enable/disable fieldsactions

Start Small: Initial Adoption

  • Begin with one endpoint. Incremental rollout makes testing easier.
  • Pick an authorization data strategy early:
    • Local Authorization: Query your own database.
    • Centralized facts: Store facts in Oso Cloud for complex relationship models.
    • Context facts: Send facts inline with each request (useful during development).
  • Deploy behind feature flags. Run Oso in parallel with your current system, monitor and reconcile differences before wider deployment.
  • Audit coverage. Track unprotected endpoints with middleware:
// Track authorization coverage per request
function authAuditMiddleware(req, res, next) {
  req.authChecks = 0;
  // increment req.authChecks for each authz check
  if (req.authChecks === 0) {
    console.error(`Unprotected endpoint: ${req.path}`);
  }
}

Layer-by-Layer Enforcement

Secure your application at multiple layers using different authorization approaches. Each layer serves distinct security purposes.

Service Layer: Request-Level Authorization

  • Purpose: Coarse-grained access control for HTTP requests.
  • Checks: Admin endpoints, tenant separation, route-level permissions.
  • Implementation: Use middleware for scalability across routes.
@app.middleware('http')
async def authorize_request(request, call_next):
    if not await oso.authorize(request.user, "access", request.path):
        raise HTTPException(403, "Forbidden")
    return await call_next(request)

Business Logic: Resource-Level Authorization

  • Purpose: Fine-grained permissions on specific resources.
  • Checks: “edit” permission, ownership, action-specific permissions.
  • Implementation: Use reusable patterns like decorators or higher-order functions.
@require_permission("edit")
def update_document(user, document_id, data):
    # Business logic here
    pass
Use Oso Cloud’s authorization API for these checks.

Data Access: Query-Level Authorization

  • Purpose: Filter data queries to return only authorized results.
  • **Checks: ** database queries return only accessible records, search results filtered by permissions, and list operations constrained by permission boundaries.
  • Implementation: Modify queries with authorization constraints.
-- Add WHERE clauses based on user permissions
SELECT * FROM documents 
WHERE tenant_id = $user_tenant_id 
  AND (visibility = 'public' OR owner_id = $user_id)
Use Oso Cloud’s list API to generate these filters.

Presentation: Client-Side Authorization

  • Purpose: Conditionally render UI elements based on user permissions.
  • Checks: show/hide actions, disable inputs.
  • Implementation: Create server endpoints for authorization data.
Never enforce in the frontend alone.
// Server endpoint
app.get('/api/user-permissions/:resourceId', async (req, res) => {
  const actions = await oso.listUserActions(req.user, req.params.resourceId);
  res.json({ actions });
});

// Frontend usage
const permissions = await fetch(`/api/user-permissions/${docId}`);
const canEdit = permissions.actions.includes('edit');
Use Oso Cloud’s actions API for efficient permission queries.

Key Principles

  • Defense in depth. Use multiple layers per endpoint.
  • Fail securely. Deny on missing/failed checks.
  • Optimize performance. Batch checks, cache with TTL.
  • Audit and monitor. Log decisions, review failed attempts.

Need help enforcing authorization in your application? Schedule a call with an Oso engineer.