@kapable/ops-sdk (0.1.1)

Published 2026-06-09 22:32:32 +00:00 by kapable

Installation

@kapable:registry=
npm install @kapable/ops-sdk@0.1.1
"@kapable/ops-sdk": "0.1.1"

About this package

@kapable/ops-sdk

Operator-tier TypeScript SDK for the Kapable v2 platform — the trust-perimeter twin of @kapable/sdk.

New here? Start at the SDK suite front door: ../docs/sdk.md — which package, which token, the module catalog, and coverage at a glance.

Version 0.1.0 — 10 operator modules, 122 TS methods (TS↔Rust parity: 122 Rust methods), operator coverage 57.6% (98/170 ops-eligible endpoints; the denominator includes Berth's full 85-endpoint operator surface — see Coverage). See CHANGELOG.md. Not published to any registry.

It wraps the operator / admin / service-token endpoints the customer SDK deliberately excludes — Berth, Foreman, kapable-host, kapable-gateway, harbor-admin, the kapable-data query proxy, Burrow tunnels, kapable-auth admin, and the billing/comms internal routes — mirroring the kapable (customer) vs kapable-ops (operator) CLI trust split.

The operator vs customer perimeter (the load-bearing invariant)

The OpsClient constructor classifies the supplied token by prefix and throws an OperatorPerimeterError if it is a customer API key (sk_live_/sk_test_/sk_org_). The operator/customer boundary is therefore a physical, fail-fast fact: an operator wrapper cannot even be instantiated with a customer credential, so a customer dependency tree literally cannot drive operator endpoints with its own key.

Token prefixes
Accepted kses_ (platform_staff session), sk_admin_ (platform superkey), st_/st_ci_/st_deploy_/st_wh_/st_svc_ (service tokens), unrecognized/JWT-shaped (server gates)
Rejected sk_live_ / sk_test_ / sk_org_ (customer API keys)

The SDK never enforces authorization — the server (require_permission + per-service scope checks) is the sole authority. This perimeter only ensures the right class of credential reaches the operator surface. Some modules layer an additional per-call header credential (Berth deploy-sync's Ed25519 X-Signature; the billing/comms X-Internal-Token; the auth admin x-api-key).

Quick start

bun add @kapable/ops-sdk      # not published — use the file: workspace dependency
import { OpsClient } from '@kapable/ops-sdk';

const ops = new OpsClient({
  baseUrl: 'https://data.kapable.ai',
  token: 'st_ci_...', // or sk_admin_..., or a platform_staff kses_...
});

// data query proxy — POST /v1/query/{database} (PlatformAdmin + db:read/db:write)
const r = await ops.data.query(
  'kapable_platform',
  'SELECT id FROM orgs WHERE slug = $1',
  { params: ['acme'] },
);
console.log(r.row_count, r.rows);

// Berth deploy control-plane — GET /api/v1/binaries
const berth = new OpsClient({ baseUrl: 'http://localhost:3100', token: 'st_svc_...' });
const binaries = await berth.berth.listBinaries();

// A customer key throws at construction:
new OpsClient({ baseUrl: '...', token: 'sk_live_...' }); // OperatorPerimeterError

Modules

Driven from coverage-manifest.json (regenerate with bun run generate-manifest). Each module is reachable as ops.<module>.<method>() and is verified at TS↔Rust parity (see Tooling).

Module Methods Service Operator surface
auth 14 kapable-auth ADMIN surface (org/app provision, SSO-callback registration, beta gate, request metrics, launchpad admin)
berth 36 berth Deploy control-plane (binaries, deploy-sync, slots, reconcile, freeze, rollback, restart, canary/rollout) + observability reads (audit, versions, deploy/config diff, config, health-history, rollback-history, processes, dependency-graph)
billing 1 kapable-billing Internal billing-portal mint (X-Internal-Token)
burrow 4 burrow Tunnel REGISTRY (list/get/register/remove tunnels)
comms 2 kapable-comms Service-to-service internal routes (intercept, send; X-Internal-Token)
data 1 kapable-data DB query proxy (replaces ssh … psql)
foreman 15 foreman CI job queue + recipe runner (recipes, recipe-runs, tasks, runners, pipeline metrics)
gateway 6 kapable-gateway gateway_services CRUD + reconcile (owns Caddy routing)
harbor 23 harbor ADMIN/mutation surface (products, features, tiers, licenses, releases, org keypairs)
host 20 kapable-host Containers + blue-green deploy, snapshots, images, volumes
Total 122 10 services operator coverage 57.6% (98/170 ops-eligible endpoints)

harbor has no server-side RBAC and incomplete org-scoping (IDOR, IMP-1366); the customer SDK deferred it. It is safe here only because this client rejects customer keys at construction — operator-only by the SDK perimeter until IMP-1366 lands server RBAC.

Coverage

The denominator is every ops-eligible endpoint in the verified surface inventory (../docs/sdk-surface-inventory.json): an API route that is either (a) on an operator-tier service (Berth, Foreman, kapable-gateway, kapable-host, Burrow) and not public, or (b) gated to an explicitly operator-only auth tier (admin / platform_staff / service_token / internal_token) on a customer-tier service — i.e. exactly the routes the customer SDK rejects at its perimeter.

Berth alone contributes 85 ops-eligible endpoints (82 service_token), of which the SDK now wraps the 35 that cover the day-to-day deploy/inspect/observe loop (iter-34 added the audit / versions / deploy-diff / config(+diff) / health-history / rollback-history / processes / dependency-graph reads) — so the aggregate 57.6% is an honest figure against the full operator surface, not just the wrapped slice. Per-service: host/gateway/data 100%, foreman 83%, burrow 80%, auth 64%, billing/comms internal 50–67%, berth 41%. Remaining Berth gaps are the deliberately-deferred mutation/niche routes — see the next paragraph.

Berth — still deferred (lower-value or dangerous mutations, NOT wrapped): notifications email/slack (get/put/delete/test), key import/export/rotate, secrets PUT/DELETE (write side), secrets-canonical PUT/DELETE, retention-run, maintenance get/set, webhooks register/list/remove, caddy route add, admin reap-stale, POST .../config (config write), DELETE .../binaries/{name} (deregister), POST .../binaries/{name}/stop, proxy-health reset, queue delete, deploy submit/dry-run/cancel/approve, scheduled, openapi, retention get. The SSE-only GET /api/v1/events(+/{name}) are skipped here — they are a streaming surface, not a JSON read, and want an SSE-aware client method. All tracked by bun run check-drift.

Token tiering — st_* / sk_admin_ / session

The Permission / TokenType / Scope enums and the tier-aware AuthRequirement are re-exported from @kapable/sdk/security (a file: dependency), so the customer and operator packages share a single source of truth and cannot drift. This package adds the operator-perimeter helpers on top: isOperatorToken, classifyToken, OPS_ACCEPTED_TOKEN_TYPES, OPS_REJECTED_TOKEN_TYPES. Use them to validate a token's class before handing it to an OpsClient (the constructor enforces the same rule):

import { isOperatorToken, classifyToken } from '@kapable/ops-sdk';

isOperatorToken('st_ci_...');   // true  — service token
isOperatorToken('sk_admin_...'); // true  — platform superkey
isOperatorToken('kses_...');    // true  — platform_staff session
isOperatorToken('sk_live_...'); // false — customer key (rejected at construction)

Tooling

Mirrors the customer SDK's coverage + quality tooling (CONTRIBUTING.md):

Command What it does
bun run typecheck tsc --noEmit over src/.
bun test Unit tests + the cross-language parity test (test/parity.test.ts).
bun run build tsc declarations + per-module ESM bundles into dist/.
bun run generate-manifest Rebuilds coverage-manifest.json from live source — never hand-edit the manifest.
bun run check-drift Reports operator coverage + un-wrapped gaps, and fails (exit 1) on any phantom (a method claiming a route the server does not expose).

The introspector (scripts/ops-introspect.ts) parses the real TS client.ts methods and Rust mod.rs pub fns — it never hardcodes a method list — so the manifest, parity test, and drift report always reflect the code as it is now.

Dependencies

Dependencies

ID Version
@kapable/sdk file:../kapable-sdk

Development dependencies

ID Version
@types/bun ^1.2.0
typescript ^5.7.0
Details
npm
2026-06-09 22:32:32 +00:00
3
MIT
12 KiB
Assets (1)
Versions (3) View all
0.1.2 2026-06-09
0.1.1 2026-06-09
0.1.0 2026-06-09