DEV Community

Alex Spinov
Alex Spinov

Posted on

Permit.io Has a Free API — Heres How to Add Fine-Grained Authorization to Any App

Permit.io provides fine-grained authorization — RBAC, ABAC, ReBAC — through a simple API. Define who can do what, check permissions with one API call.

Why Permit.io?

  • RBAC + ABAC + ReBAC: All authorization models
  • Policy as code: OPA/Cedar policies
  • Real-time: Changes propagate instantly
  • SDKs: Every major language
  • No-code UI: Non-developers manage permissions
  • Audit logs: Track every permission check
  • Free tier: 1,000 MAUs

Install SDK

npm install permitio
Enter fullscreen mode Exit fullscreen mode

Setup

import { Permit } from 'permitio';

const permit = new Permit({
  pdp: 'https://cloudpdp.api.permit.io',
  token: 'permit_key_xxx',
});
Enter fullscreen mode Exit fullscreen mode

Check Permission

const allowed = await permit.check('user-123', 'read', 'document');
if (allowed) {
  // User can read documents
} else {
  // Access denied
}
Enter fullscreen mode Exit fullscreen mode

Express Middleware

function authorize(action: string, resource: string) {
  return async (req, res, next) => {
    const allowed = await permit.check(req.user.id, action, resource);
    if (!allowed) return res.status(403).json({ error: 'Forbidden' });
    next();
  };
}

app.get('/api/documents', authorize('read', 'document'), getDocuments);
app.post('/api/documents', authorize('create', 'document'), createDocument);
app.delete('/api/documents/:id', authorize('delete', 'document'), deleteDocument);
Enter fullscreen mode Exit fullscreen mode

API: Assign Role

curl -X POST https://api.permit.io/v2/facts/users/user-123/roles \
  -H 'Authorization: Bearer permit_key_xxx' \
  -H 'Content-Type: application/json' \
  -d '{"role": "editor", "tenant": "org-1"}'
Enter fullscreen mode Exit fullscreen mode

API: Create Resource

curl -X POST https://api.permit.io/v2/schema/resources \
  -H 'Authorization: Bearer permit_key_xxx' \
  -H 'Content-Type: application/json' \
  -d '{
    "key": "document",
    "name": "Document",
    "actions": {
      "read": {},
      "create": {},
      "update": {},
      "delete": {}
    }
  }'
Enter fullscreen mode Exit fullscreen mode

API: Create Role

curl -X POST https://api.permit.io/v2/schema/roles \
  -H 'Authorization: Bearer permit_key_xxx' \
  -H 'Content-Type: application/json' \
  -d '{
    "key": "editor",
    "name": "Editor",
    "permissions": ["document:read", "document:create", "document:update"]
  }'
Enter fullscreen mode Exit fullscreen mode

ABAC (Attribute-Based)

const allowed = await permit.check(
  { key: 'user-123', attributes: { department: 'engineering', level: 'senior' } },
  'approve',
  { type: 'expense', attributes: { amount: 5000, department: 'engineering' } }
);
// Seniors can approve expenses up to $10K in their department
Enter fullscreen mode Exit fullscreen mode

ReBAC (Relationship-Based)

// Create relationship
await permit.api.relationshipTuples.create({
  subject: 'user:alice',
  relation: 'owner',
  object: 'document:doc-1',
});

// Check: can Alice edit doc-1? (owners can edit)
const allowed = await permit.check('alice', 'edit', { type: 'document', key: 'doc-1' });
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A SaaS app had authorization logic scattered across 200 if-statements. After moving to Permit.io, all rules are in one place. When a customer asked for custom roles, the PM configured it in the UI without a developer — shipped in 5 minutes instead of a sprint.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)