Skip to content

About

Openbox temporal SDK in type script

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

OpenBox Temporal SDK — TypeScript

TypeScript SDK for integrating OpenBox AI governance into Temporal workflows. Direct port of the Python SDK.

What it does

  • Intercepts every workflow and activity execution and sends governance events to OpenBox Core
  • Evaluates HTTP and database operations mid-activity via OpenTelemetry hooks
  • Enforces governance verdicts: ALLOW, BLOCK, HALT, REQUIRE_APPROVAL
  • Signs all requests with Ed25519 (AIP DID protocol) for tamper-proof audit trails

Installation

npm install openbox-temporal-sdk

Required peer dependencies (if not already in your project):

npm install @temporalio/worker @temporalio/workflow @temporalio/activity

Quick start

1. Set up credentials

Copy .env.example to .env and fill in your values:

cp .env.example .env
OPENBOX_API_KEY=obx_live_your_api_key_here
OPENBOX_AGENT_DID=did:aip:your-agent-did-here
OPENBOX_AGENT_PRIVATE_KEY=your_base64_private_key_seed_here
OPENBOX_API_URL=https://core.openbox.ai

Never commit .env — it is git-ignored. Commit .env.example instead.

2. Attach the plugin to your Temporal Worker

import * as dotenv from 'dotenv';
dotenv.config();

import { Worker } from '@temporalio/worker';
import { OpenBoxPlugin } from 'openbox-temporal-sdk';

const worker = await Worker.create({
  taskQueue: 'my-task-queue',
  workflowsPath: require.resolve('./workflows'),
  activities: myActivities,
  plugins: [
    new OpenBoxPlugin({
      openboxUrl:       process.env.OPENBOX_API_URL!,
      openboxApiKey:    process.env.OPENBOX_API_KEY!,
      agentDid:         process.env.OPENBOX_AGENT_DID,
      agentPrivateKey:  process.env.OPENBOX_AGENT_PRIVATE_KEY,
    }),
  ],
});

await worker.run();

That's it. Every workflow and activity that runs through this worker will automatically have governance events sent to your OpenBox dashboard.


Configuration options

Option Type Default Description
openboxUrl string — OpenBox Core API URL (required)
openboxApiKey string — API key (obx_live_... or obx_test_...)
agentDid string null Agent DID for request signing (did:aip:...)
agentPrivateKey string null Base64 Ed25519 private key seed
onApiError 'fail_open' | 'fail_closed' 'fail_open' What to do if OpenBox Core is unreachable
apiTimeout number 30 Governance API timeout in seconds
instrumentHttp boolean true Intercept outbound HTTP calls
instrumentDatabases boolean true Intercept database queries
instrumentFileIo boolean false Intercept file I/O operations
skipWorkflowTypes string[] [] Workflow types to skip governance for
skipActivityTypes string[] [] Activity types to skip
sendActivityStartEvent boolean true Emit ActivityStarted events

Alternative: createOpenBoxWorker

If you want OpenBox to create the Temporal Worker for you:

import { createOpenBoxWorker } from 'openbox-temporal-sdk';

const worker = await createOpenBoxWorker({
  temporalAddress:  'localhost:7233',
  taskQueue:        'my-task-queue',
  workflowsPath:    require.resolve('./workflows'),
  activities:       myActivities,
  openboxUrl:       process.env.OPENBOX_API_URL!,
  openboxApiKey:    process.env.OPENBOX_API_KEY!,
  agentDid:         process.env.OPENBOX_AGENT_DID,
  agentPrivateKey:  process.env.OPENBOX_AGENT_PRIVATE_KEY,
});

await worker.run();

Supported instrumentation

HTTP clients (auto-patched via OTel)

  • fetch (Node.js built-in)
  • axios
  • got
  • undici
  • node-fetch

Databases (auto-patched via OTel)

  • PostgreSQL (pg)
  • MySQL (mysql2)
  • MongoDB
  • Redis (redis, ioredis)
  • TypeORM / Knex (via query hooks)

Governance verdicts

When OpenBox evaluates an operation, it returns one of:

Verdict Behaviour
allow Execution continues normally
block Throws GovernanceBlockedError — stops the current activity
halt Throws GovernanceBlockedError — signals workflow to terminate
require_approval Pauses execution pending human approval (HITL)

Catch these in your activities:

import { GovernanceBlockedError } from 'openbox-temporal-sdk';

try {
  const result = await fetch('https://api.example.com/data');
} catch (e) {
  if (e instanceof GovernanceBlockedError) {
    console.log(`Blocked: ${e.verdict.value} — ${e.reason}`);
    throw e; // re-throw to surface to Temporal
  }
}

Debug mode

Set OPENBOX_DEBUG=1 to enable verbose SDK logging:

OPENBOX_DEBUG=1 npx ts-node your-worker.ts

Running the test scripts

# Full lifecycle test — sends all 9 event types to OpenBox dashboard
npx ts-node --project tsconfig.json test-lifecycle.ts

# Quick smoke test — single WorkflowStarted event
npx ts-node --project tsconfig.json test-run.ts

Verify results in your OpenBox dashboard.


Building

npm run build          # compile to dist/
npm run build:watch    # watch mode
npm test               # run jest tests
npm run lint           # eslint

Project structure

src/
  index.ts                  # Public API surface
  plugin.ts                 # OpenBoxPlugin (Temporal SimplePlugin)
  worker.ts                 # createOpenBoxWorker()
  config.ts                 # GovernanceConfig, initialize(), Ed25519Signer
  activity_interceptor.ts   # ActivityGovernanceInterceptor
  workflow_interceptor.ts   # WorkflowGovernanceInterceptor
  hook_governance.ts        # Per-operation governance evaluation (HTTP/DB hooks)
  http_governance_hooks.ts  # OTel HTTP instrumentation hooks
  db_governance_hooks.ts    # OTel database instrumentation hooks
  span_processor.ts         # WorkflowSpanProcessor (bounded LRU maps)
  request_signing.ts        # AIP Ed25519 signed-request construction + retry
  activities.ts             # GovernanceActivities (sendGovernanceEvent)
  errors.ts                 # Full error hierarchy
  types.ts                  # WorkflowEventType, Verdict, etc.
  otel_setup.ts             # OpenTelemetry setup
  tracing.ts                # @traced decorator, createSpan
  client.ts                 # GovernanceClient
  hitl.ts                   # Human-in-the-loop helpers
  verdict_handler.ts        # enforceVerdict()
  context_propagation.ts    # AsyncLocalStorage context helpers

Security

  • All requests to OpenBox Core are signed with Ed25519 using the AIP DID protocol
  • The agentPrivateKey never leaves your process — only the signature is transmitted
  • Store credentials in .env (never commit them — see .gitignore)
  • Use obx_test_... keys in development, obx_live_... in production

About

Openbox temporal SDK in type script

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages