Component · shared/

shared

The wire-format domain types every package shares — one source of truth, so the API, clients, and backends can't drift. Pure types, no runtime.

Role in the architecture#

Data flows one way in Enclave: every package depends on shared for the wire format. Changing a contract here is what keeps every package in lock-step — the control plane, SDK, MCP server, console, and demo all import these types. Since there's no runtime, a contract change is a pure type change the compiler propagates everywhere.

Source
shared/src/index.ts (domain types) · shared/src/auth.ts (the auth contract + token helpers).

What it exports#

The domain types and the auth contract. See data contracts for the full field-by-field reference.

shared/src/index.tsts
// shared/src/index.ts — the domain contract
export type SessionPhase = "pending" | "running" | "succeeded"
  | "failed" | "killed" | "torn_down";
export interface CreateSessionRequest { code: string; /* … */ }
export interface Session { id: string; orgId: string; /* … */ }
export interface SessionResult { exitCode: number | null; /* … */ }
export interface EgressPolicy { mode: "deny_all" | "allowlist"; /* … */ }
export type StreamFrame = /* discriminated union on `kind` */;
export interface AuditEvent { ts: string; type: AuditEventType; /* … */ }

// re-exported from ./auth.ts
export { signUserJwt, verifyUserJwt, parseApiKey,
  type Role, type Scope, type Principal };

Auth helpers#

Beyond types, shared ships the small set of token helpers both services agree on, so console-api and the control plane verify the same way:

  • signUserJwt(claims, secret) / verifyUserJwt(token, secret) — HS256 user JWTs carrying { sub, email, orgId, role, exp }.
  • parseApiKey(raw) — splits an ek_<id>_<secret> key into its parts (returns null if malformed).