Documentation

Node.js SDK

The official TigerIdentity SDK for Node.js and TypeScript. Full type safety, promise-based APIs, and seamless Express/Fastify integration.

Installation

Install the SDK using npm:

npm install @tigeridentity/sdk

Or using yarn:

yarn add @tigeridentity/sdk

Or using pnpm:

pnpm add @tigeridentity/sdk

Requirements: Node.js 16.x or higher

Quick Start

Initialize the client with TypeScript and make your first access decision:

import { TigerClient } from '@tigeridentity/sdk';

// Initialize client
const client = new TigerClient({
  apiKey: 'your-api-key',
  baseURL: 'https://api.tigeridentity.com',
});

// Evaluate access
const result = await client.decisions.evaluate({
  principalId: 'user-123',
  action: 'read',
  resource: 'document:sensitive-report',
  context: {
    ipAddress: '203.0.113.42',
    deviceTrust: 'high',
    mfaVerified: true,
  },
});

if (result.allowed) {
  console.log(`Access granted: ${result.reason}`);
} else {
  console.log(`Access denied: ${result.reason}`);
}

// List principals
const principals = await client.principals.list({
  type: 'user',
  limit: 50,
});

principals.items.forEach((principal) => {
  console.log(`Principal: ${principal.id} (${principal.type})`);
});

Key Classes

TigerClient

Main client class with automatic retries, connection pooling, and built-in caching.

new TigerClient(options)

DecisionClient

Real-time access decisions with context evaluation and caching support.

client.decisions.evaluate()

PrincipalClient

Identity management for users, services, and AI agents with full CRUD operations.

client.principals.get()

PolicyClient

Create, update, and simulate access policies with versioning and rollback.

client.policies.create()

EventClient

Subscribe to CAEP events for real-time security notifications.

client.events.subscribe()

WebhookClient

Manage webhooks and verify webhook signatures for security.

client.webhooks.verify()

Usage Examples

Creating a Policy

import { PolicyEffect, ConditionOperator } from '@tigeridentity/sdk';

// Create a geo-fencing policy
const policy = await client.policies.create({
  name: 'geo-restricted-access',
  description: 'Restrict access based on geographic location',
  rules: [
    {
      effect: PolicyEffect.Allow,
      conditions: [
        {
          field: 'context.location.country',
          operator: ConditionOperator.In,
          value: ['US', 'CA', 'GB'],
        },
        {
          field: 'context.vpn',
          operator: ConditionOperator.Equals,
          value: false,
        },
      ],
    },
  ],
  resources: ['customer:*', 'order:*'],
  actions: ['read', 'write'],
});

console.log(`Created policy: ${policy.id}`);

Express Middleware

import express from 'express';
import { TigerClient } from '@tigeridentity/sdk';

const app = express();
const tiger = new TigerClient({ apiKey: process.env.TIGER_API_KEY });

// Middleware to check access
function requireAccess(action: string, resourceFn: (req: any) => string) {
  return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    const resource = resourceFn(req);
    const principalId = `user-${req.user?.id}`;

    try {
      const result = await tiger.decisions.evaluate({
        principalId,
        action,
        resource,
        context: {
          ipAddress: req.ip,
          userAgent: req.get('user-agent'),
          path: req.path,
        },
      });

      if (!result.allowed) {
        return res.status(403).json({
          error: 'Access denied',
          reason: result.reason,
        });
      }

      next();
    } catch (error) {
      console.error('Access check failed:', error);
      res.status(500).json({ error: 'Internal server error' });
    }
  };
}

// Protected routes
app.get(
  '/projects/:id',
  requireAccess('read', (req) => `project:${req.params.id}`)
);

app.delete(
  '/projects/:id',
  requireAccess('delete', (req) => `project:${req.params.id}`)
);

app.listen(3000);

Webhook Handler

import { TigerClient, WebhookEvent, WebhookEventType } from '@tigeridentity/sdk';

const tiger = new TigerClient({ apiKey: process.env.TIGER_API_KEY });

// Express webhook endpoint
app.post('/webhooks/tiger', async (req, res) => {
  const signature = req.get('x-tiger-signature');
  const timestamp = req.get('x-tiger-timestamp');

  try {
    // Verify webhook signature
    const isValid = tiger.webhooks.verify({
      payload: JSON.stringify(req.body),
      signature: signature!,
      timestamp: timestamp!,
      secret: process.env.TIGER_WEBHOOK_SECRET!,
    });

    if (!isValid) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    const event: WebhookEvent = req.body;

    // Handle different event types
    switch (event.type) {
      case WebhookEventType.SessionRevoked:
        console.log(`Session revoked: ${event.data.sessionId}`);
        // Invalidate local session cache
        await invalidateSession(event.data.sessionId);
        break;

      case WebhookEventType.RiskScoreChanged:
        console.log(`Risk score changed: ${event.data.principalId}`);
        // Re-evaluate active sessions
        await reevaluateUserSessions(event.data.principalId);
        break;

      case WebhookEventType.PrincipalDisabled:
        console.log(`Principal disabled: ${event.data.principalId}`);
        // Terminate all sessions
        await terminateAllSessions(event.data.principalId);
        break;

      case WebhookEventType.PolicyUpdated:
        console.log(`Policy updated: ${event.data.policyId}`);
        // Clear policy cache
        await clearPolicyCache();
        break;
    }

    res.json({ received: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

Batch Operations

// Evaluate multiple access requests in parallel
const requests = [
  {
    principalId: 'user-alice',
    action: 'read',
    resource: 'project:alpha',
  },
  {
    principalId: 'user-alice',
    action: 'write',
    resource: 'project:alpha',
  },
  {
    principalId: 'user-alice',
    action: 'delete',
    resource: 'project:alpha',
  },
];

const results = await client.decisions.batchEvaluate({
  requests,
});

results.results.forEach((result, index) => {
  const action = requests[index].action;
  console.log(`${action}: ${result.allowed ? '✓' : '✗'}`);
  if (!result.allowed) {
    console.log(`  Reason: ${result.reason}`);
  }
});

// Create multiple principals at once
const principals = await Promise.all([
  client.principals.create({
    type: 'user',
    id: 'user-new-hire-1',
    attributes: {
      email: '[email protected]',
      department: 'engineering',
    },
  }),
  client.principals.create({
    type: 'user',
    id: 'user-new-hire-2',
    attributes: {
      email: '[email protected]',
      department: 'engineering',
    },
  }),
]);

console.log(`Created ${principals.length} principals`);

TypeScript Support

The SDK includes full TypeScript definitions for type-safe development:

import {
  TigerClient,
  EvaluateRequest,
  EvaluateResult,
  Principal,
  PrincipalType,
  Policy,
  PolicyEffect,
  ConditionOperator,
} from '@tigeridentity/sdk';

// Type-safe request
const request: EvaluateRequest = {
  principalId: 'user-123',
  action: 'read',
  resource: 'document:123',
  context: {
    ipAddress: '192.168.1.1',
    // TypeScript ensures correct types
  },
};

// Type-safe response
const result: EvaluateResult = await client.decisions.evaluate(request);

// Strongly typed enums
const userType: PrincipalType = PrincipalType.User;
const effect: PolicyEffect = PolicyEffect.Allow;
const operator: ConditionOperator = ConditionOperator.Equals;

Error Handling

import {
  TigerIdentityError,
  APIError,
  NotFoundError,
  RateLimitError,
  UnauthorizedError,
} from '@tigeridentity/sdk';

try {
  const result = await client.decisions.evaluate(request);
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error(`Principal not found: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}s`);
    await new Promise((resolve) => setTimeout(resolve, error.retryAfter * 1000));
  } else if (error instanceof UnauthorizedError) {
    console.error('Invalid API key');
  } else if (error instanceof APIError) {
    console.error(`API error: ${error.message} (code: ${error.code})`);
  } else if (error instanceof TigerIdentityError) {
    console.error(`SDK error: ${error.message}`);
  } else {
    console.error('Unexpected error:', error);
  }
}

Start building with Node.js

Get your API key and integrate TigerIdentity in minutes.