npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

guardian-safety-sdk

v1.0.0

Published

Guardian SDK - Safe execution of irreversible actions with policy enforcement and approvals

Readme

@guardian/sdk

Guardian SDK for safe execution of irreversible actions with policy enforcement and approvals.

Installation

npm install @guardian/sdk

Quick Start

import { Guardian } from '@guardian/sdk';

const guardian = new Guardian({
  apiKey: 'gk_your_api_key',
  baseUrl: 'http://localhost:3001',
});

const result = await guardian.run({
  actionType: 'payment.send',
  payload: { amount: 1000, recipient: '[email protected]' },
});

console.log(result.status); // 'EXECUTED'

API

new Guardian(config)

Create a new Guardian client.

const guardian = new Guardian({
  apiKey: string,        // Required: Your Guardian API key
  baseUrl: string,       // Required: Guardian API URL
  timeoutMs?: number,    // Optional: Request timeout (default: 30000)
  pollIntervalMs?: number, // Optional: Approval poll interval (default: 2000)
  maxWaitMs?: number,    // Optional: Max wait for approval (default: 900000)
});

guardian.run(input)

Execute an action through Guardian.

const result = await guardian.run({
  actionType: string,           // Required: Action type identifier
  payload: Record<string, any>, // Required: Action payload
  idempotencyKey?: string,      // Optional: Idempotency key (auto-generated if not provided)
  waitForApproval?: boolean,    // Optional: Wait for approval (default: true)
});

// Returns:
{
  intentRunId: string,
  status: 'ALLOW' | 'REQUIRE_APPROVAL' | 'DENY' | 'EXECUTED',
  decision?: string,
  reason?: string,
}

Examples

Hello World (5 lines)

import { Guardian } from '@guardian/sdk';

const guardian = new Guardian({ apiKey: 'gk_xxx', baseUrl: 'http://localhost:3001' });
const result = await guardian.run({ actionType: 'hello.world', payload: { message: 'Hello!' } });
console.log(result.status);

Retry-Safe Execution

The SDK automatically generates idempotency keys, making retries safe:

import { Guardian, GuardianNetworkError } from '@guardian/sdk';

const guardian = new Guardian({
  apiKey: 'gk_your_api_key',
  baseUrl: 'http://localhost:3001',
});

// Use a fixed idempotency key for retry safety
const idempotencyKey = `payment-${orderId}`;

async function sendPaymentWithRetry(orderId: string, amount: number) {
  for (let attempt = 1; attempt <= 3; attempt++) {
    try {
      const result = await guardian.run({
        actionType: 'payment.send',
        payload: { orderId, amount },
        idempotencyKey: `payment-${orderId}`,
      });
      return result;
    } catch (error) {
      if (error instanceof GuardianNetworkError && attempt < 3) {
        console.log(`Attempt ${attempt} failed, retrying...`);
        await new Promise(r => setTimeout(r, 1000 * attempt));
        continue;
      }
      throw error;
    }
  }
}

Approval-Required Action

import { Guardian, GuardianApprovalRejectedError } from '@guardian/sdk';

const guardian = new Guardian({
  apiKey: 'gk_your_api_key',
  baseUrl: 'http://localhost:3001',
  maxWaitMs: 300000, // Wait up to 5 minutes for approval
});

try {
  // This will block until approved (or rejected/timeout)
  const result = await guardian.run({
    actionType: 'payment.send',
    payload: { amount: 50000, recipient: '[email protected]' },
  });
  
  console.log('Payment executed:', result.intentRunId);
} catch (error) {
  if (error instanceof GuardianApprovalRejectedError) {
    console.log('Payment rejected by:', error.rejectedBy);
    console.log('Reason:', error.rejectionReason);
  }
  throw error;
}

Non-Blocking Approval

import { Guardian } from '@guardian/sdk';

const guardian = new Guardian({
  apiKey: 'gk_your_api_key',
  baseUrl: 'http://localhost:3001',
});

// Don't wait for approval - return immediately
const result = await guardian.run({
  actionType: 'payment.send',
  payload: { amount: 50000, recipient: '[email protected]' },
  waitForApproval: false,
});

if (result.status === 'REQUIRE_APPROVAL') {
  console.log('Approval required. Intent ID:', result.intentRunId);
  // Store intentRunId and handle approval asynchronously
}

Error Handling

The SDK exports typed errors for precise error handling:

import {
  Guardian,
  GuardianDeniedError,
  GuardianApprovalRejectedError,
  GuardianIntegrityError,
  GuardianNetworkError,
  GuardianTimeoutError,
} from '@guardian/sdk';

try {
  await guardian.run({ actionType: 'payment.send', payload: { amount: 1000000 } });
} catch (error) {
  if (error instanceof GuardianDeniedError) {
    // Action denied by policy
    console.log('Denied:', error.reason);
  } else if (error instanceof GuardianApprovalRejectedError) {
    // Human reviewer rejected the action
    console.log('Rejected by:', error.rejectedBy);
  } else if (error instanceof GuardianIntegrityError) {
    // Payload was modified after approval (tampering detected)
    console.log('Integrity error - possible tampering');
  } else if (error instanceof GuardianTimeoutError) {
    // Approval timed out
    console.log('Approval timed out');
  } else if (error instanceof GuardianNetworkError) {
    // Network/API error
    console.log('Network error:', error.statusCode);
  }
}

How It Works

  1. Intent Check: SDK calls Guardian's /v1/intents/check endpoint with your action
  2. Policy Evaluation: Guardian evaluates the action against configured policies
  3. Decision Handling:
    • ALLOW: SDK immediately executes the action
    • DENY: SDK throws GuardianDeniedError
    • REQUIRE_APPROVAL: SDK waits for human approval (if waitForApproval: true)
  4. Execution: Once approved, SDK calls /v1/intents/:id/execute
  5. Safety: SDK handles idempotency, payload integrity, and replay protection

Requirements

  • Node.js 18+ (uses native fetch)
  • Guardian backend running and accessible

License

MIT