Skip to content

Authentication

Fabric resolves authentication in priority order. The first matching mechanism is used.

API keys are the primary authentication mechanism for service-to-service communication.

import { FabricClient } from "@fabric-platform/sdk";
const fabric = new FabricClient({ apiKey: "fab_your_api_key_here" });
const me = await fabric.getMe();

How it works:

  • Keys use the fab_ prefix for identification
  • The prefix is used for fast lookup, then the full key hash is verified
  • Keys are hashed at rest (never stored in plaintext)
  • Keys are org-scoped with configurable expiry and permission scopes

JWT tokens issued by Supabase are validated using HS256.

const fabric = new FabricClient({
apiKey: "eyJhbGciOiJIUzI1NiIs...", // JWT token
});

Configure with: JWT_SECRET=<supabase_jwt_secret>

For development only. Allows setting an arbitrary principal ID without authentication.

const fabric = new FabricClient({
principalId: "550e8400-e29b-41d4-a716-446655440000",
});

Blocked in production. Set FABRIC_ENV=production to disable.

Requests without credentials are treated as anonymous. Only public endpoints are accessible:

  • GET /healthz
  • GET /readyz
  • GET /openapi.json
const key = await fabric.createApiKey({
name: "my-service-key",
organizationId: "<org-id>",
scopes: ["jobs:write", "providers:execute"],
});
console.log("Store this key:", key.raw_key); // shown only once

The raw key (fab_...) is returned only once in the response. Store it securely.

API keys can be scoped to specific permissions:

ScopeDescription
jobs:writeCreate and manage jobs
jobs:readRead job status and history
providers:executeExecute provider requests
workflows:writeCreate and manage workflows
workflows:readRead workflow definitions and runs
(empty list)Full access (no restrictions)

An empty scope list grants full access. Scopes are enforced at the route level.

// List keys
const keys = await fabric.listApiKeys();
// Revoke a key
await fabric.deleteApiKey("<key-id>");

After authentication, Fabric enforces role-based access control:

RoleLevelCapabilities
OwnerHighestFull access, can manage other owners
AdminHighManage teams, invitations, most resources
MemberStandardCreate and manage own resources
ViewerLowestRead-only access

Roles are scoped to organizations and optionally to teams. The effective permission is the highest role across all scopes for a given principal.

// Single check
const allowed = await fabric.checkPermission({
resourceType: "organization",
resourceId: "<org-id>",
action: "team.create",
});
// Batch check
const results = await fabric.checkPermissions([
{ action: "organization.read" },
{ action: "team.create" },
]);

Clients must not compute permissions themselves. Fabric is the enforcement authority.