@bulwark/core

The foundational Bulwark SDK for Node.js. Provides full API access for server-side use.

Installation

npm install @bulwark/core
# or
pnpm add @bulwark/core

Quick Start

import { BulwarkClient } from "@bulwark/core";

const bulwark = new BulwarkClient({
  tenantId: process.env.BULWARK_TENANT_ID!,
  apiKey: process.env.BULWARK_API_KEY!,
  baseUrl: "https://api.bulwarkauth.io", // or your self-hosted URL
});

API Reference

BulwarkClient

Constructor Options

interface BulwarkClientOptions {
  tenantId: string;
  apiKey: string;
  baseUrl?: string;          // defaults to https://api.bulwarkauth.io
  timeout?: number;          // request timeout in ms (default: 10000)
  retries?: number;          // number of retries on 5xx (default: 2)
}

bulwark.auth

// Register user
const { user, accessToken, refreshToken } = await bulwark.auth.register({
  email: string;
  password: string;
  name: string;
});

// Login
const { accessToken, refreshToken } = await bulwark.auth.login({
  email: string;
  password: string;
});

// Refresh token
const { accessToken } = await bulwark.auth.refresh(refreshToken);

// Logout
await bulwark.auth.logout(accessToken, refreshToken);

bulwark.agents

// Register agent
const agent = await bulwark.agents.register({
  name: string;
  description?: string;
  scopes: string[];
  trustLevel: "low" | "medium" | "high" | "critical";
  metadata?: Record<string, unknown>;
});

// List agents
const { data, pagination } = await bulwark.agents.list({
  limit?: number;
  cursor?: string;
  trustLevel?: string;
  status?: "active" | "revoked";
});

// Get agent
const agent = await bulwark.agents.get(agentId);

// Revoke agent
await bulwark.agents.revoke(agentId);

// Rotate key
const { apiKey } = await bulwark.agents.rotateKey(agentId);

bulwark.sessions

// Create session
const session = await bulwark.sessions.create({
  agentId: string;
  userId?: string;
  requestedScopes: string[];
  ttl?: number;
  context?: Record<string, unknown>;
});

// Proxy a request
const response = await bulwark.sessions.proxy(sessionId, {
  credentialId: string;
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
  url: string;
  headers?: Record<string, string>;
  body?: unknown;
});

// Complete session
await bulwark.sessions.complete(sessionId);

// Attenuate token
const { token } = await bulwark.sessions.attenuate(sessionId, {
  scopes: string[];
  ttl?: number;
  caveats?: Array<{ type: string; value: string }>;
});

bulwark.vault

// Store token
const { tokenId } = await bulwark.vault.storeToken({
  provider: string;
  userId: string;
  accessToken: string;
  refreshToken?: string;
  expiresAt?: string;
  scopes?: string[];
});

// List tokens for user
const tokens = await bulwark.vault.listTokens(userId);

// Revoke token
await bulwark.vault.revokeToken(tokenId);

bulwark.fga

// Write tuples
await bulwark.fga.write({
  writes: Array<{ user: string; relation: string; object: string }>;
});

// Check access
const { allowed } = await bulwark.fga.check({
  user: string;
  relation: string;
  object: string;
});

// List objects
const { objects } = await bulwark.fga.listObjects({
  user: string;
  relation: string;
  type: string;
});

Error Handling

import { BulwarkError } from "@bulwark/core";

try {
  await bulwark.agents.get("agent_invalid");
} catch (err) {
  if (err instanceof BulwarkError) {
    console.error(err.code);    // "NOT_FOUND"
    console.error(err.message); // "Agent not found"
    console.error(err.status);  // 404
  }
}