Skip to main content
The control-plane package adds a durable SQLite store for multi-tenant objects: orgs, projects, teams, billing records, usage, secret references, and audit events. Import it alongside the Gateway when you need these boundaries.

ControlPlaneStore API

Import the store from the public facade:
import { ControlPlaneStore } from "smithers-orchestrator/control-plane";
Or from the scoped package:
import { ControlPlaneStore } from "@smithers-orchestrator/control-plane";
The store creates SQLite tables for:
  • organizations
  • teams and team membership
  • projects and project team grants
  • billing account records
  • identity-provider records for SAML/OIDC configuration
  • usage events, summaries, and quota checks
  • secret manager references, not secret values
  • audit events and org audit export
Constructing new ControlPlaneStore(sqlite) calls ensureControlPlaneTables(sqlite). You can call ensureControlPlaneTables(sqlite) directly when you only need to bootstrap the schema.

Store Methods

MethodPurpose
createOrg()Create an organization.
getOrg()Load an organization by ID.
createTeam()Create a team in an organization.
addTeamMember()Add or update a user’s team role.
createProject()Create a project in an organization.
addProjectTeam()Grant or update a team’s project role.
upsertBillingAccount()Create or update the org billing record.
upsertIdentityProvider()Create or update a SAML/OIDC identity provider record.
listIdentityProviders()List org identity providers, optionally filtered by status.
recordUsage()Append a usage event.
summarizeUsage()Aggregate usage by metric and unit for an org.
setUsageLimit()Create or update an org/project usage limit.
checkUsageLimit()Return the matching limit plus usedQuantity, remainingQuantity, and exceeded, or null when no limit is configured.
putSecretRef()Store an external secret reference, not the secret value.
listSecretRefs()List org or project secret references.
recordAuditEvent()Append an audit event.
exportOrgAudit()Export org data, usage summaries, secret refs, and audit events.
const store = new ControlPlaneStore(sqlite);

// Required: create the org and at least one project before recording any data.
const org = store.createOrg({
  orgId: "org_acme",
  slug: "acme",
  name: "Acme",
});

const project = store.createProject({
  orgId: org.orgId,
  projectId: "project_app",
  slug: "app",
  name: "App",
});

// Optional: record a usage event and set a quota for a metric.
store.recordUsage({
  orgId: org.orgId,
  projectId: project.projectId,
  runId: "run_123",
  metric: "agent_runtime_ms",
  quantity: 42_000,
  unit: "ms",
});

store.setUsageLimit({
  orgId: org.orgId,
  projectId: project.projectId,
  metric: "agent_runtime_ms",
  unit: "ms",
  period: "monthly",
  limitQuantity: 10_000_000,
});

// Optional: register a SAML or OIDC provider for the org.
store.upsertIdentityProvider({
  orgId: org.orgId,
  providerId: "idp_okta",
  type: "saml",
  issuer: "https://acme.okta.com",
  ssoUrl: "https://acme.okta.com/app/smithers/sso/saml",
  certificateRef: "vault://identity/acme-okta-cert",
});

// Optional: store a reference to a secret in an external provider (not the value).
store.putSecretRef({
  orgId: org.orgId,
  projectId: project.projectId,
  name: "deploy-token",
  provider: "aws-secrets-manager",
  ref: "arn:aws:secretsmanager:us-east-1:123:secret:deploy",
});

// Check whether the project is within its quota.
const quota = store.checkUsageLimit({
  orgId: org.orgId,
  projectId: project.projectId,
  metric: "agent_runtime_ms",
  unit: "ms",
  period: "monthly",
});
// quota is null when no matching limit exists; otherwise it includes
// { usedQuantity, remainingQuantity, exceeded, limitQuantity, ...limitMetadata }.

const audit = store.exportOrgAudit({ orgId: org.orgId });
Deleting an org cascades to all its child rows: projects, teams, identity providers, billing account, usage rows, usage limits, secret references, and audit rows. There is no soft-delete; use a status flag in your application layer if you need recoverable deletion.

Hosted Boundary

A hosted Smithers service should layer these primitives behind:
  • SSO/SAML or OIDC authentication
  • billing provider checkout and invoices
  • cloud object storage for large artifacts
  • managed secret provider reads at worker runtime
  • audit export delivery and retention policy
  • SLAs, support, compliance controls, and incident response
The open-source package owns the durable data contract. The hosted service owns identity, payment collection, tenant isolation, compliance operations, and infrastructure support.