import { describe, expect, spyOn, test } from "bun:test"; import { cleanupExpiredSessions, createApp } from "../../server/app"; import { hashToken, MemoryAuthStore } from "../../server/auth"; import { MemoryAuditStore } from "../../server/audit-store"; import type { ManagementService } from "../../server/management"; import { MemoryOperationStore, MemoryWorkspaceLeaseProvider, } from "../../server/operation-store"; import { MemoryWorkspaceStore } from "../../server/workspace-store"; import { MemoryTrustStore } from "../../server/trust-store"; import type { BuildController } from "../../server/build-controller"; function request( path: string, init: RequestInit = {}, token?: string, ): Request { const headers = new Headers(init.headers); if (token) headers.set("authorization", `Bearer ${token}`); return new Request(`https://kuber.astrxl.dev${path}`, { ...init, headers }); } describe("kuber API authentication", () => { test("logs every request start and completion without changing responses", async () => { const logs: Record[] = []; const app = createApp({ store: new MemoryAuthStore(), requestId: () => "request-log-id", logger: { error: () => {}, log: (entry) => logs.push(entry), }, }); const response = await app(request("/api/v2/health")); expect(response.status).toBe(200); expect(logs).toEqual( expect.arrayContaining([ expect.objectContaining({ event: "kuber.server.request.start", requestId: "request-log-id", method: "GET", pathname: "/api/v2/health", }), expect.objectContaining({ event: "kuber.server.request.end", requestId: "request-log-id", status: 200, durationMs: expect.any(Number), }), ]), ); }); test("ignores request logging failures", async () => { const app = createApp({ store: new MemoryAuthStore(), logger: { error: () => {}, log: () => { throw new Error("logger unavailable"); }, }, }); expect((await app(request("/api/v2/health"))).status).toBe(200); }); test("logs in, resolves identity, and revokes the session", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "dmgnr", passwordHash: "stored-hash", roles: ["admin"], }); const app = createApp({ store, now: () => Date.parse("2026-09-02T00:00:00.000Z"), verifyPassword: async (password, hash) => password === "correct" && hash === "stored-hash", }); const login = await app( request("/api/v2/login", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ username: "dmgnr", password: "correct", persistent: false, }), }), ); expect(login.status).toBe(200); const session = (await login.json()) as { token: string; expiresAt: string; }; expect(session.expiresAt).toBe("2026-09-03T00:00:00.000Z"); const me = await app(request("/api/v2/me", {}, session.token)); expect(await me.json()).toEqual({ username: "dmgnr", roles: ["admin"] }); const logout = await app( request("/api/v2/logout", { method: "POST" }, session.token), ); expect(logout.status).toBe(204); expect((await app(request("/api/v2/me", {}, session.token))).status).toBe( 401, ); }); test("rejects invalid credentials and unauthenticated requests", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "dmgnr", passwordHash: "stored-hash", roles: ["admin"], }); const app = createApp({ store, verifyPassword: async () => false, }); const login = await app( request("/api/v2/login", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ username: "dmgnr", password: "wrong" }), }), ); expect(login.status).toBe(401); expect((await app(request("/api/v2/me"))).status).toBe(401); }); test("provides an unauthenticated health endpoint", async () => { const app = createApp({ store: new MemoryAuthStore() }); const response = await app(request("/api/v2/health")); expect(response.status).toBe(200); expect(await response.json()).toEqual({ status: "ok" }); }); test("provides an explicit expired-session startup cleanup helper", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "user", passwordHash: "hash", roles: ["viewer"], }); await store.putSession({ tokenHash: hashToken("expired"), username: "user", authVersion: 1, expiresAt: "2026-09-01T00:00:00.000Z", }); expect( await cleanupExpiredSessions( store, Date.parse("2026-09-02T00:00:00.000Z"), ), ).toBe(1); }); test("rate limits repeated failed logins", async () => { const app = createApp({ store: new MemoryAuthStore(), now: () => 0, }); const login = () => app( request("/api/v2/login", { method: "POST", body: JSON.stringify({ username: "missing", password: "wrong" }), }), ); for (let attempt = 0; attempt < 5; attempt += 1) { expect((await login()).status).toBe(401); } const limited = await login(); expect(limited.status).toBe(429); expect(limited.headers.get("retry-after")).toBe("300"); }); }); describe("operation response safety", () => { test("database and storage reconcile concurrently while conflicting scopes fail fast", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(); const leases = new MemoryWorkspaceLeaseProvider(); const entered = new Set(); let release!: () => void; const blocked = new Promise((resolve) => (release = resolve)); let bothEntered!: () => void; const bothStarted = new Promise((resolve) => (bothEntered = resolve)); const reconcile = (name: string) => async () => { entered.add(name); if (entered.size === 2) bothEntered(); await blocked; return {}; }; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases, management: { reconcileDatabases: reconcile("database"), reconcileStorage: reconcile("storage"), stop: async () => [], } as unknown as ManagementService, }); const post = (path: string, key: string, body: unknown = { compose: { services: {} } }) => app(request(`/api/v2/workspaces/demo/${path}`, { method: "POST", headers: { "idempotency-key": key }, body: JSON.stringify(body), }, "token")); const database = post("databases", "database-one"); const storage = post("storage", "storage-one"); await bothStarted; expect(entered).toEqual(new Set(["database", "storage"])); const sameScope = await post("databases", "database-two"); expect(sameScope.status).toBe(409); const broad = await post("lifecycle", "lifecycle", { action: "stop" }); expect(broad.status).toBe(409); release(); expect((await database).status).toBe(200); expect((await storage).status).toBe(200); }); test("redacts database and storage reconciliation results immediately", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const seen: unknown[] = []; const databaseResult = { credentials: { password: "database-password" }, env: [{ name: "DB_PASSWORD", value: "database-password" }], }; const storageResult = { credentials: { secretKey: "storage-secret" }, env: [{ name: "STORAGE_SECRET", value: "storage-secret" }], }; const management = { reconcileDatabases: async (_workspace: unknown, compose: unknown) => { seen.push(compose); return databaseResult; }, reconcileStorage: async (_workspace: unknown, compose: unknown) => { seen.push(compose); return storageResult; }, } as unknown as ManagementService; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore: new MemoryOperationStore(undefined, () => crypto.randomUUID(), ), management, }); const compose = { services: {}, secret: "internal-compose-secret", }; for (const [path, key, secret] of [ ["databases", "db-once", "database-password"], ["storage", "storage-once", "storage-secret"], ] as const) { const result = await app( request( `/api/v2/workspaces/demo/${path}`, { method: "POST", headers: { "idempotency-key": key }, body: JSON.stringify({ compose }), }, "token", ), ); expect(result.status).toBe(200); const body = JSON.stringify(await result.json()); expect(body).not.toContain(secret); expect(body).not.toContain("internal-compose-secret"); expect(body).toContain('"redacted":true'); } expect(seen).toHaveLength(2); expect(JSON.stringify(seen[0])).toContain("internal-compose-secret"); expect(databaseResult.credentials.password).toBe("database-password"); expect(storageResult.credentials.secretKey).toBe("storage-secret"); }); test("redacts failed reconciliation errors immediately and when retrieved", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(undefined, () => crypto.randomUUID(), ); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management: { reconcileDatabases: async () => { throw new Error( 'database provider failed DB_PASSWORD=database-password response={"data":{"token":"kube-secret"}}', ); }, reconcileStorage: async () => { throw new Error( 'storage provider failed STORAGE_SECRET=storage-secret response={"data":{"password":"storage-kube-secret"}}', ); }, } as unknown as ManagementService, }); const path = "/api/v2/workspaces/demo/databases"; const init = { method: "POST", headers: { "idempotency-key": "failed-reconcile" }, body: JSON.stringify({ compose: { services: {} } }), }; const immediate = await app(request(path, init, "token")); const immediateBody = JSON.stringify(await immediate.json()); expect(immediate.status).toBe(500); expect(immediateBody).not.toContain("database-password"); expect(immediateBody).not.toContain("kube-secret"); expect(immediateBody).toContain("DATABASE_RECONCILE_FAILED"); expect(immediateBody).toContain("during operation execution: Unexpected failure; check server logs using the operation ID"); const operationId = (await operationStore.list())[0]!.metadata.name; const retrieved = await app( request(`/api/v2/operations/${operationId}`, {}, "token"), ); const retrievedBody = JSON.stringify(await retrieved.json()); expect(retrievedBody).not.toContain("database-password"); expect(retrievedBody).not.toContain("kube-secret"); const storageImmediate = await app( request( "/api/v2/workspaces/demo/storage", { ...init, headers: { "idempotency-key": "failed-storage" }, }, "token", ), ); const storageBody = JSON.stringify(await storageImmediate.json()); expect(storageImmediate.status).toBe(500); expect(storageBody).not.toContain("storage-secret"); expect(storageBody).not.toContain("storage-kube-secret"); const storageId = (await operationStore.list())[1]!.metadata.name; const storageRetrieved = await app( request(`/api/v2/operations/${storageId}`, {}, "token"), ); expect(JSON.stringify(await storageRetrieved.json())).not.toContain( "storage-kube-secret", ); const idempotent = await app(request(path, init, "token")); const idempotentBody = JSON.stringify(await idempotent.json()); expect(idempotentBody).not.toContain("database-password"); expect(idempotentBody).not.toContain("kube-secret"); }); }); describe("API key route expiry", () => { test("omitted expiry creates a non-expiring key that authenticates and survives cleanup", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "admin", passwordHash: "hash", roles: ["admin"], }); await store.putUser({ username: "ci", passwordHash: "hash", roles: ["viewer"], }); await store.putSession({ tokenHash: hashToken("admin-token"), username: "admin", authVersion: 1, expiresAt: "2027-01-01T00:00:00.000Z", }); let time = Date.parse("2026-10-05T00:00:00.000Z"); const app = createApp({ store, now: () => time }); const created = await app( request( "/api/v2/users/ci/keys", { method: "POST", body: JSON.stringify({ capabilities: ["kubernetes:read"] }), }, "admin-token", ), ); expect(created.status).toBe(201); const key = (await created.json()) as { id: string; token: string; expiresAt?: string; }; expect(key).not.toHaveProperty("expiresAt"); expect((await store.listApiKeys("ci"))[0]).not.toHaveProperty("expiresAt"); const listed = await app( request("/api/v2/users/ci/keys", {}, "admin-token"), ); const list = (await listed.json()) as { items: Record[] }; expect(list.items).toEqual([expect.objectContaining({ id: key.id })]); expect(list.items[0]).not.toHaveProperty("expiresAt"); time = Date.parse("2028-01-01T00:00:00.000Z"); expect(await cleanupExpiredSessions(store, time)).toBe(1); expect((await app(request("/api/v2/me", {}, key.token))).status).toBe(200); }); test("explicit finite expiry is enforced and malformed expiry is rejected", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "admin", passwordHash: "hash", roles: ["admin"], }); await store.putUser({ username: "ci", passwordHash: "hash", roles: ["viewer"], }); await store.putSession({ tokenHash: hashToken("admin-token"), username: "admin", authVersion: 1, expiresAt: "2027-01-01T00:00:00.000Z", }); let time = Date.parse("2026-10-05T00:00:00.000Z"); const app = createApp({ store, now: () => time }); const create = (expiresAt: unknown) => app( request( "/api/v2/users/ci/keys", { method: "POST", body: JSON.stringify({ capabilities: ["kubernetes:read"], expiresAt, }), }, "admin-token", ), ); const expiry = "2026-10-06T00:00:00.000Z"; const created = await create(expiry); expect(created.status).toBe(201); const key = (await created.json()) as { token: string; expiresAt: string }; expect(key.expiresAt).toBe(expiry); expect((await app(request("/api/v2/me", {}, key.token))).status).toBe(200); for (const invalid of [ null, 0, "", "2026-10-05T00:00:00.000Z", "2027-10-06T00:00:00.000Z", ]) expect((await create(invalid)).status).toBe(400); time = Date.parse(expiry); expect((await app(request("/api/v2/me", {}, key.token))).status).toBe(401); }); test("a finite parent API key cannot delegate a non-expiring child", async () => { const store = new MemoryAuthStore(); await store.putUser({ username: "ci", passwordHash: "hash", roles: ["viewer"], }); await store.createApiKey({ id: "finite-parent-key-1", tokenHash: hashToken("parent-token"), username: "ci", capabilities: ["users:write", "kubernetes:read"], expiresAt: "2027-01-01T00:00:00.000Z", }); const app = createApp({ store, now: () => Date.parse("2026-10-05T00:00:00.000Z"), }); const created = await app( request( "/api/v2/users/ci/keys", { method: "POST", body: JSON.stringify({ capabilities: ["kubernetes:read"] }), }, "parent-token", ), ); expect(created.status).toBe(403); expect((await created.json()) as { code: string }).toMatchObject({ code: "API_KEY_DELEGATION_FORBIDDEN", }); }); }); async function authenticatedStore(role: "viewer" | "operator" | "admin") { const store = new MemoryAuthStore(); await store.putUser({ username: role, passwordHash: "hash", roles: [role] }); await store.putSession({ tokenHash: hashToken("token"), username: role, authVersion: 1, expiresAt: "2030-01-01T00:00:00.000Z", }); return store; } describe("kuber v2 HTTP routes", () => { test("streams build status and logs, supports resume cursors, and keeps version headers", async () => { const controller = { getBuildProject: async () => "demo", getBuildStatus: async () => ({ state: "running", phase: "building" }), getBuildEvents: async (_id: string, after = 0) => [ { type: "log", sequence: 4, message: "build output" }, ].filter((event) => event.sequence > after), reconcileBuild: async () => ({ state: "running", phase: "building" }), } as unknown as BuildController; const app = createApp({ store: await authenticatedStore("operator"), builds: controller }); const abort = new AbortController(); const response = await app(request( "/api/v2/builds/build-1/events?after=2", { headers: { accept: "text/event-stream" }, signal: abort.signal }, "token", )); expect(response.status).toBe(200); expect(response.headers.get("content-type")).toContain("text/event-stream"); expect(response.headers.get("x-kuber-version")).toBeTruthy(); const reader = response.body!.getReader(); let body = ""; while (!body.includes("event: status")) { const { done, value } = await reader.read(); if (done) break; body += new TextDecoder().decode(value); } expect(body).toContain("id: 4\nevent: log"); expect(body).toContain("build output"); expect(body).toContain("event: status"); abort.abort(); await reader.cancel(); const resumedAbort = new AbortController(); const resumed = await app(request( "/api/v2/builds/build-1/events", { headers: { accept: "text/event-stream", "last-event-id": "4" }, signal: resumedAbort.signal }, "token", )); const resumedReader = resumed.body!.getReader(); const resumedChunk = await resumedReader.read(); expect(new TextDecoder().decode(resumedChunk.value)).not.toContain("id: 4"); resumedAbort.abort(); await resumedReader.cancel(); }); test("checks authentication and workspace scope before opening a build stream", async () => { const controller = { getBuildProject: async () => "other", getBuildStatus: async () => ({ state: "running", phase: "building" }), getBuildEvents: async () => [], reconcileBuild: async () => ({ state: "running", phase: "building" }), } as unknown as BuildController; const app = createApp({ store: await authenticatedStore("operator"), builds: controller }); const unauthenticated = await app(request( "/api/v2/builds/build-1/events", { headers: { accept: "text/event-stream" } }, )); expect(unauthenticated.status).toBe(401); const store = new MemoryAuthStore(); await store.putUser({ username: "scoped", passwordHash: "hash", roles: ["operator"] }); await store.createApiKey({ id: "scoped-key-12345678", username: "scoped", tokenHash: hashToken("scoped-token"), capabilities: ["kubernetes:write"], workspace: "demo", }); const scopedApp = createApp({ store, builds: controller }); const forbidden = await scopedApp(request( "/api/v2/builds/build-1/events", { headers: { accept: "text/event-stream" } }, "scoped-token", )); expect(forbidden.status).toBe(403); expect(forbidden.headers.get("content-type")).not.toContain("text/event-stream"); }); test("rejects malformed SSE cursors before opening the stream", async () => { const controller = { getBuildProject: async () => "demo", getBuildStatus: async () => ({ state: "running", phase: "building" }), getBuildEvents: async () => [], reconcileBuild: async () => ({ state: "running", phase: "building" }), } as unknown as BuildController; const app = createApp({ store: await authenticatedStore("operator"), builds: controller }); const response = await app(request( "/api/v2/builds/build-1/events?after=1.5", { headers: { accept: "text/event-stream" } }, "token", )); expect(response.status).toBe(400); expect(response.headers.get("content-type")).toContain("application/problem+json"); }); test("grants, lists, revokes, and enforces namespace trust for applies", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const trustStore = new MemoryTrustStore(); const fingerprint = "a".repeat(64); const headers = { "x-kuber-trust-project": "demo", "x-kuber-trust-fingerprint": fingerprint, }; const apply = (app: ReturnType) => app( request( "/api/v2/workspaces/demo/resources/apply", { method: "POST", headers, body: JSON.stringify({ resources: [] }), }, "token", ), ); const unavailable = await createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore: new MemoryOperationStore(), management: { applyResources: async () => [], } as unknown as ManagementService, }); const unavailableApply = await apply(unavailable); expect(unavailableApply.status).toBe(503); expect(await unavailableApply.json()).toMatchObject({ code: "TRUST_STORE_UNAVAILABLE", }); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore: new MemoryOperationStore(), trustStore, management: { applyResources: async () => [], } as unknown as ManagementService, }); const untrustedApply = (headers?: RequestInit["headers"]) => app( request( "/api/v2/workspaces/demo/resources/apply", { method: "POST", headers, body: JSON.stringify({ resources: [] }), }, "token", ), ); expect((await untrustedApply()).status).toBe(428); expect((await apply(app)).status).toBe(403); expect( ( await app( request( "/api/v2/workspaces/demo/trust", { method: "POST", body: JSON.stringify({ fingerprint }) }, "token", ), ) ).status, ).toBe(204); const status = await app( request("/api/v2/workspaces/demo/trust", {}, "token"), ); expect(status.status).toBe(200); expect(await status.json()).toEqual({ fingerprints: [fingerprint] }); expect((await apply(app)).status).toBe(200); expect( ( await app( request( `/api/v2/workspaces/demo/trust?fingerprint=${fingerprint}`, { method: "DELETE" }, "token", ), ) ).status, ).toBe(204); expect((await apply(app)).status).toBe(403); }); test("returns OPERATION_CONFLICT when an idempotency key is reused for another body", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const trustStore = new MemoryTrustStore(); const fingerprint = "c".repeat(64); await trustStore.grant("demo", fingerprint); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, trustStore, operationStore: new MemoryOperationStore(), management: { applyResources: async () => [], } as unknown as ManagementService, }); const apply = (resources: unknown[]) => app( request( "/api/v2/workspaces/demo/resources/apply", { method: "POST", headers: { "idempotency-key": "same-apply", "x-kuber-trust-project": "demo", "x-kuber-trust-fingerprint": fingerprint, }, body: JSON.stringify({ resources }), }, "token", ), ); expect((await apply([])).status).toBe(200); const conflict = await apply([ { apiVersion: "v1", kind: "Service", metadata: { name: "web" } }, ]); expect(conflict.status).toBe(409); expect(await conflict.json()).toMatchObject({ code: "OPERATION_CONFLICT" }); }); test("starts preferred resource operations before returning so progress can be polled", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const trustStore = new MemoryTrustStore(); const fingerprint = "b".repeat(64); let start!: () => void; let finish!: () => void; let complete!: () => void; const started = new Promise((resolve) => (start = resolve)); const unblock = new Promise((resolve) => (finish = resolve)); const completed = new Promise((resolve) => (complete = resolve)); const management = { applyResources: async ( _workspace: unknown, _resources: unknown, execution: { emit?: (event: { resource: { apiVersion: string; kind: string; name: string }; phase: "apply"; state: "started" | "succeeded"; }) => Promise; }, ) => { await execution.emit?.({ resource: { apiVersion: "v1", kind: "Service", name: "web" }, phase: "apply", state: "started", }); start(); await unblock; await execution.emit?.({ resource: { apiVersion: "v1", kind: "Service", name: "web" }, phase: "apply", state: "succeeded", }); complete(); return []; }, } as unknown as ManagementService; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore: new MemoryOperationStore(), trustStore, management, }); await app( request( "/api/v2/workspaces/demo/trust", { method: "POST", body: JSON.stringify({ fingerprint }) }, "token", ), ); const submitted = await app( request( "/api/v2/workspaces/demo/resources/apply", { method: "POST", headers: { "idempotency-key": "progress-once", prefer: "respond-async", "x-kuber-trust-project": "demo", "x-kuber-trust-fingerprint": fingerprint, }, body: JSON.stringify({ resources: [] }), }, "token", ), ); expect(submitted.status).toBe(202); const { operationId } = (await submitted.json()) as { operationId: string }; await started; const events = await app( request(`/api/v2/operations/${operationId}/events?after=0`, {}, "token"), ); expect(await events.json()).toMatchObject({ items: [{ sequence: 1, data: { state: "started" } }], }); finish(); await completed; }); test("uses exact origins, request IDs, and problem+json errors", async () => { const app = createApp({ store: new MemoryAuthStore(), allowedOrigins: ["https://console.example"], requestId: () => "generated-id", }); const denied = await app( request("/api/v2/health", { headers: { origin: "https://console.example.evil" }, }), ); expect(denied.status).toBe(403); expect(denied.headers.get("content-type")).toContain( "application/problem+json", ); expect(denied.headers.get("x-request-id")).toBe("generated-id"); expect(await denied.json()).toMatchObject({ code: "ORIGIN_NOT_ALLOWED", requestId: "generated-id", }); const allowed = await app( request("/api/v2/health", { headers: { origin: "https://console.example", "x-request-id": "caller-id", }, }), ); expect(allowed.headers.get("access-control-allow-origin")).toBe( "https://console.example", ); expect(allowed.headers.get("x-request-id")).toBe("caller-id"); }); test("enforces capabilities and supports user CRUD with revocation", async () => { const viewerStore = await authenticatedStore("viewer"); const viewerApp = createApp({ store: viewerStore }); expect( (await viewerApp(request("/api/v2/users", {}, "token"))).status, ).toBe(403); const store = await authenticatedStore("admin"); const auditStore = new MemoryAuditStore(); const app = createApp({ store, auditStore, hashPassword: async (password) => `hashed:${password}`, }); const created = await app( request( "/api/v2/users", { method: "POST", body: JSON.stringify({ username: "alice", password: "secret", roles: ["operator"], }), }, "token", ), ); expect(created.status).toBe(201); expect(await created.json()).toEqual({ username: "alice", roles: ["operator"], disabled: false, }); expect((await store.getUser("alice"))?.passwordHash).toBe("hashed:secret"); const revoke = await app( request( "/api/v2/users/alice/sessions/revoke", { method: "POST" }, "token", ), ); expect(revoke.status).toBe(200); expect(await revoke.json()).toEqual({ username: "alice", revoked: 0 }); expect((await auditStore.list()).map((event) => event.spec.action)).toEqual( ["user.create", "sessions.revoke"], ); }); test("provides workspace ETags and idempotent synchronous operations", async () => { const store = await authenticatedStore("operator"); const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", now: () => new Date("2026-09-02T00:00:00.000Z"), }); const operationStore = new MemoryOperationStore( () => new Date("2026-09-02T00:00:00.000Z"), () => "operation-uid", ); let stops = 0; const management = { stop: async () => { stops += 1; return ["api"]; }, } as unknown as ManagementService; const app = createApp({ store, workspaceStore, operationStore, management, }); const created = await app( request( "/api/v2/workspaces", { method: "POST", body: JSON.stringify({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }), }, "token", ), ); expect(created.status).toBe(201); expect(created.headers.get("etag")).toBe('"1"'); const missingPrecondition = await app( request( "/api/v2/workspaces/demo", { method: "PUT", body: JSON.stringify({ source: { uri: "oci://example/demo", digest: "sha256:def" }, }), }, "token", ), ); expect(missingPrecondition.status).toBe(428); const stop = () => app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", headers: { "idempotency-key": "stop-once" }, body: JSON.stringify({ action: "stop", services: ["api"] }), }, "token", ), ); expect((await stop()).status).toBe(200); expect((await stop()).status).toBe(200); expect(stops).toBe(1); expect(await operationStore.list("demo")).toHaveLength(1); }); test("logs raw diagnostics for correlated generic failures", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const logs: unknown[] = []; const providerError = Object.assign( new Error( 'provider failed password=top-secret config={"compose":"private"}', ), { name: "KubernetesError", stack: "KubernetesError: provider failed\n at provider (test.ts:1:1)", body: { status: "Failure", reason: "InternalError", code: 500, message: "contains top-secret", }, }, ); spyOn(workspaceStore, "update").mockRejectedValue(providerError); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, requestId: () => "request-123", logger: { error: (entry) => logs.push(entry) }, }); const result = await app( request( "/api/v2/workspaces/demo", { method: "PUT", headers: { "if-match": '"1"' }, body: JSON.stringify({ source: { uri: "cas://secret-source", digest: "secret-digest" }, config: { compose: "private-config", password: "top-secret" }, }), }, "token", ), ); expect(result.status).toBe(500); expect(await result.json()).toMatchObject({ code: "INTERNAL_ERROR", requestId: "request-123", detail: "The request could not be completed", }); expect(logs).toEqual([ { event: "request.failed", requestId: "request-123", method: "PUT", pathname: "/api/v2/workspaces/demo", workspaceId: "demo", status: 500, code: "INTERNAL_ERROR", errorName: "KubernetesError", message: 'provider failed password=top-secret config={"compose":"private"}', stack: "KubernetesError: provider failed\n at provider (test.ts:1:1)", kubernetesStatus: { status: "Failure", reason: "InternalError", code: 500, }, }, ]); }); test("lists persisted operation events with capability and workspace scope checks", async () => { const store = await authenticatedStore("operator"); const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "event-id", ); const operation = await operationStore.create({ workspaceId: "demo", action: "resources.apply", idempotencyKey: "event-key", }); await operationStore.emit(operation.metadata.name, { resource: { apiVersion: "v1", kind: "Service", name: "web" }, phase: "apply", state: "succeeded", }); await store.createApiKey({ id: "demo-reader-key-01", tokenHash: hashToken("demo-reader-token"), username: "operator", capabilities: ["kubernetes:read"], workspace: "demo", expiresAt: "2030-01-01T00:00:00.000Z", }); await store.createApiKey({ id: "other-reader-key-1", tokenHash: hashToken("other-reader-token"), username: "operator", capabilities: ["kubernetes:read"], workspace: "other", expiresAt: "2030-01-01T00:00:00.000Z", }); const app = createApp({ store, workspaceStore, operationStore }); const path = `/api/v2/operations/${operation.metadata.name}/events?after=0`; const allowed = await app(request(path, {}, "demo-reader-token")); expect(allowed.status).toBe(200); expect(await allowed.json()).toMatchObject({ items: [ { sequence: 1, data: { resource: { kind: "Service", name: "web" }, phase: "apply" }, }, ], nextCursor: 1, retainedFirstSequence: 1, cursorGap: false, }); expect((await app(request(path, {}, "other-reader-token"))).status).toBe( 403, ); expect( (await app(request(`${path}x`, {}, "demo-reader-token"))).status, ).toBe(400); }); test("reports operation event cursor gaps after retained history is truncated", async () => { const operationStore = new MemoryOperationStore( undefined, () => "retained", ); const operation = await operationStore.create({ workspaceId: "demo", action: "resources.apply", idempotencyKey: "retained-events", }); for (let sequence = 0; sequence < 257; sequence += 1) { await operationStore.emit(operation.metadata.name, { resource: { apiVersion: "v1", kind: "ConfigMap", name: "config" }, phase: "apply", state: "succeeded", }); } const app = createApp({ store: await authenticatedStore("operator"), operationStore, }); const response = await app( request( `/api/v2/operations/${operation.metadata.name}/events?after=0`, {}, "token", ), ); expect(response.status).toBe(200); const events = (await response.json()) as { retainedFirstSequence: number; cursorGap: boolean; items: { sequence: number }[]; }; expect(events.retainedFirstSequence).toBe(2); expect(events.cursorGap).toBe(true); expect(events.items[0]?.sequence).toBe(2); }); test("rejects JSON bodies over the configured limit", async () => { const app = createApp({ store: await authenticatedStore("admin"), workspaceStore: new MemoryWorkspaceStore(), jsonBodyLimit: 32, }); const result = await app( request( "/api/v2/workspaces", { method: "POST", body: JSON.stringify({ value: "x".repeat(64) }) }, "token", ), ); expect(result.status).toBe(413); expect(await result.json()).toMatchObject({ code: "BODY_TOO_LARGE" }); }); test("does not expose request internals or corrupt success when auditing fails", async () => { const logs: unknown[] = []; const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "operation-uid", ); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management: { stop: async () => ["api"] } as unknown as ManagementService, auditStore: { append: async () => { throw new Error("audit unavailable"); }, list: async () => [], }, requestId: () => "audit-request-123", logger: { error: (entry) => logs.push(entry) }, }); const result = await app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", headers: { "idempotency-key": "private-request" }, body: JSON.stringify({ action: "stop", password: "do-not-store" }), }, "token", ), ); expect(result.status).toBe(200); const body = (await result.json()) as Record; expect(body.operation.spec).toEqual({ workspaceId: "demo", action: "workspace.stop", }); expect(body.operation.status.state).toBe("succeeded"); expect(logs).toEqual([ { event: "operation.audit.failed", requestId: "audit-request-123", method: "POST", pathname: "/api/v2/workspaces/demo/lifecycle", workspaceId: "demo", operationId: "operation-operation-uid", status: 500, code: "AUDIT_APPEND_FAILED", errorName: "Error", message: "Successful operation audit event could not be appended", }, ]); expect(JSON.stringify(logs)).not.toContain("audit unavailable"); expect(JSON.stringify(logs)).not.toContain("private-request"); expect(JSON.stringify(logs)).not.toContain("do-not-store"); expect( await operationStore.get("operation-operation-uid"), ).not.toHaveProperty("spec.request"); }); test("fails and identifies operations that cannot acquire the workspace lease", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(undefined, () => "blocked"); const leases = new MemoryWorkspaceLeaseProvider(); await leases.acquire("demo", "other"); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases, management: { stop: async () => [] } as unknown as ManagementService, }); const result = await app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", body: JSON.stringify({ action: "stop" }) }, "token", ), ); expect(result.status).toBe(409); expect(await result.json()).toMatchObject({ code: "WORKSPACE_BUSY", operationId: "operation-blocked", }); expect((await operationStore.get("operation-blocked"))?.status.state).toBe( "pending", ); }); test("a stalled observation-only wait does not block mutation and remains idempotent", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(); const leases = new MemoryWorkspaceLeaseProvider(); let waitStarted!: () => void; let finishWait!: () => void; const started = new Promise((resolve) => (waitStarted = resolve)); const blocked = new Promise((resolve) => (finishWait = resolve)); let waits = 0; let stops = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases, management: { waitForResources: async () => { waits += 1; waitStarted(); await blocked; }, stop: async () => { stops += 1; return ["api"]; }, } as unknown as ManagementService, }); const waitRequest = () => app( request( "/api/v2/workspaces/demo/resources/wait", { method: "POST", headers: { "idempotency-key": "wait-once", prefer: "respond-async" }, body: JSON.stringify({ deployments: ["api"] }), }, "token", ), ); const submitted = await waitRequest(); expect(submitted.status).toBe(202); await started; const duplicate = await waitRequest(); expect(duplicate.status).toBe(202); expect(waits).toBe(1); const stop = await app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", headers: { "idempotency-key": "stop-during-wait" }, body: JSON.stringify({ action: "stop" }), }, "token", ), ); expect(stop.status).toBe(200); expect(stops).toBe(1); finishWait(); }); test("keeps a concurrent idempotent operation pending when its lease acquisition is denied", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "same-key", ); let acquireCount = 0; let releaseCount = 0; let allowFirstAcquire!: () => void; let signalFirstAcquire!: () => void; const firstAcquireStarted = new Promise((resolve) => { signalFirstAcquire = resolve; }); const leases = { acquire: async () => { acquireCount += 1; if (acquireCount === 2) return undefined; if (acquireCount === 1) { signalFirstAcquire(); await new Promise((resolve) => { allowFirstAcquire = resolve; }); } return { workspaceId: "demo", holder: "operation-same-key", expiresAt: new Date().toISOString(), renew: async () => true, release: async () => { releaseCount += 1; }, }; }, }; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases, management: { stop: async () => ["api"] } as unknown as ManagementService, }); const stop = () => app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", headers: { "idempotency-key": "same-key" }, body: JSON.stringify({ action: "stop" }), }, "token", ), ); const owner = stop(); await firstAcquireStarted; const duplicate = await stop(); expect(duplicate.status).toBe(409); expect((await operationStore.get("operation-same-key"))?.status.state).toBe( "pending", ); allowFirstAcquire(); expect((await owner).status).toBe(200); expect((await operationStore.get("operation-same-key"))?.status.state).toBe( "succeeded", ); expect(acquireCount).toBe(4); expect(releaseCount).toBe(3); }); test("lets the lease winner claim execution even when a duplicate created the operation", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "same-key", ); let acquireCount = 0; let releaseFirstAcquire!: () => void; let firstAcquireStarted!: () => void; const firstAcquire = new Promise((resolve) => { firstAcquireStarted = resolve; }); const leases = { acquire: async () => { acquireCount += 1; if (acquireCount === 1) { firstAcquireStarted(); await new Promise((resolve) => { releaseFirstAcquire = resolve; }); return undefined; } return { workspaceId: "demo", holder: "operation-same-key", expiresAt: new Date().toISOString(), renew: async () => true, release: async () => {}, }; }, }; let executions = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases, management: { stop: async () => { executions += 1; return ["api"]; }, } as unknown as ManagementService, }); const stop = () => app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", headers: { "idempotency-key": "same-key" }, body: JSON.stringify({ action: "stop" }), }, "token", ), ); const creator = stop(); await firstAcquire; expect((await stop()).status).toBe(200); releaseFirstAcquire(); expect((await creator).status).toBe(409); expect(executions).toBe(1); expect((await operationStore.get("operation-same-key"))?.status.state).toBe( "succeeded", ); }); test("releases a lease when the initial execution claim fails", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "claim-fails", ); spyOn(operationStore, "claimExecution").mockRejectedValue( new Error("claim unavailable"), ); let releases = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases: { acquire: async () => ({ workspaceId: "demo", holder: "operation-claim-fails", expiresAt: new Date().toISOString(), renew: async () => true, release: async () => { releases += 1; }, }), }, management: { stop: async () => [] } as unknown as ManagementService, }); expect( ( await app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", body: JSON.stringify({ action: "stop" }) }, "token", ), ) ).status, ).toBe(500); expect(releases).toBe(3); }); test("fails a claimed operation before execution when lease ownership is lost", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "lost-lease", ); let executions = 0; let releases = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases: { acquire: async () => ({ workspaceId: "demo", holder: "operation-lost-lease", expiresAt: new Date().toISOString(), renew: async () => false, release: async () => { releases += 1; }, }), }, management: { stop: async () => { executions += 1; return []; }, } as unknown as ManagementService, }); const result = await app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", body: JSON.stringify({ action: "stop" }) }, "token", ), ); expect(result.status).toBe(409); expect(executions).toBe(0); expect(releases).toBe(3); expect(await result.json()).toMatchObject({ code: "WORKSPACE_LEASE_LOST", }); expect( (await operationStore.get("operation-lost-lease"))?.status, ).toMatchObject({ state: "failed", error: { code: "WORKSPACE_LEASE_LOST" }, }); }); test("aborts blocked execution and fails the operation when renewal loses the lease", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "blocked-loss", ); const originalSetTimeout = globalThis.setTimeout; let scheduledRenewal!: () => void; globalThis.setTimeout = ((callback: Parameters[0]) => { scheduledRenewal = callback as () => void; return 0 as unknown as ReturnType; }) as typeof setTimeout; try { let executionStarted!: () => void; const started = new Promise((resolve) => { executionStarted = resolve; }); let observedAbort = false; let renewals = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, leases: { acquire: async () => ({ workspaceId: "demo", holder: "operation-blocked-loss", expiresAt: new Date().toISOString(), renew: async () => ++renewals <= 3, release: async () => {}, }), }, management: { stop: async ( _workspace: { project: string; uid: string }, _names?: string[], execution?: { signal?: AbortSignal }, ) => { executionStarted(); await new Promise((resolve) => { execution?.signal?.addEventListener( "abort", () => { observedAbort = true; resolve(); }, { once: true }, ); }); return []; }, } as unknown as ManagementService, }); const pending = app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", body: JSON.stringify({ action: "stop" }) }, "token", ), ); await started; scheduledRenewal(); const result = await pending; expect(observedAbort).toBe(true); expect(result.status).toBe(409); expect(await result.json()).toMatchObject({ code: "WORKSPACE_LEASE_LOST", }); expect( (await operationStore.get("operation-blocked-loss"))?.status, ).toMatchObject({ state: "failed", error: { code: "WORKSPACE_LEASE_LOST" }, }); } finally { globalThis.setTimeout = originalSetTimeout; } }); test("renews the workspace lease while an operation remains in flight", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); let scheduledRenewal: (() => void) | undefined; const originalSetTimeout = globalThis.setTimeout; const originalClearTimeout = globalThis.clearTimeout; const clearedTimers: unknown[] = []; globalThis.setTimeout = ((callback: Parameters[0]) => { scheduledRenewal = callback as () => void; return 0 as unknown as ReturnType; }) as typeof setTimeout; globalThis.clearTimeout = ((timer: ReturnType) => { clearedTimers.push(timer); }) as typeof clearTimeout; try { let releaseOperation!: () => void; let operationStarted!: () => void; const started = new Promise((resolve) => { operationStarted = resolve; }); const completed = new Promise((resolve) => { releaseOperation = () => resolve(["api"]); }); let renewals = 0; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore: new MemoryOperationStore(undefined, () => "renewing"), leases: { acquire: async () => ({ workspaceId: "demo", holder: "operation-renewing", expiresAt: new Date().toISOString(), renew: async () => { renewals += 1; return true; }, release: async () => {}, }), }, management: { stop: async () => { operationStarted(); return completed; }, } as unknown as ManagementService, }); const response = app( request( "/api/v2/workspaces/demo/lifecycle", { method: "POST", body: JSON.stringify({ action: "stop" }) }, "token", ), ); await started; expect(renewals).toBe(3); scheduledRenewal?.(); await Promise.resolve(); await Promise.resolve(); expect(renewals).toBe(6); releaseOperation(); expect((await response).status).toBe(200); expect(renewals).toBe(9); expect(clearedTimers).toEqual([0]); } finally { globalThis.setTimeout = originalSetTimeout; globalThis.clearTimeout = originalClearTimeout; } }); test("reuses a failed reconciliation without attempting a second failure transition", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore( undefined, () => "reconcile", ); let reconciliations = 0; const management = { reconcileDatabases: async () => { reconciliations += 1; const [operation] = await operationStore.list("demo"); await operationStore.transition(operation!.metadata.name, "failed", { error: { code: "RECONCILE_FAILED", message: "Database reconciliation failed", }, }); return {}; }, } as unknown as ManagementService; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management, }); const reconcile = () => app( request( "/api/v2/workspaces/demo/databases", { method: "POST", headers: { "idempotency-key": "reconcile-once" }, body: JSON.stringify({ compose: {} }), }, "token", ), ); for (const result of [await reconcile(), await reconcile()]) { expect(result.status).toBe(500); expect(await result.json()).toMatchObject({ code: "RECONCILE_FAILED", detail: "Database reconciliation failed", }); } expect(reconciliations).toBe(1); expect( (await operationStore.get("operation-reconcile"))?.status.state, ).toBe("failed"); }); test("returns safe database phase and claim details on first and repeated failures", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(undefined, () => "db-failure"); const { DatabaseReconciliationError } = await import("../../lib/database"); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management: { reconcileDatabases: async () => { throw new DatabaseReconciliationError( "database apply", new Error("Forbidden: DB_PASSWORD=private-value"), { service: "web", username: "web_role", database: "web_db", secretName: "web" }, ); }, } as unknown as ManagementService, }); const reconcile = () => app(request( "/api/v2/workspaces/demo/databases", { method: "POST", headers: { "idempotency-key": "db-failure" }, body: JSON.stringify({ compose: {} }) }, "token", )); for (const result of [await reconcile(), await reconcile()]) { expect(result.status).toBe(500); const problem = await result.json() as { code: string; detail: string }; expect(problem.code).toBe("DATABASE_RECONCILE_FAILED"); expect(problem.detail).toContain("database apply for requested database claim: Forbidden"); expect(JSON.stringify(problem)).not.toContain("private-value"); } expect((await operationStore.get("operation-db-failure"))?.status.error?.message) .toContain("database apply for requested database claim"); }); test("never exposes syntactically valid secret-like database claim identifiers", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(undefined, () => "db-secret-identifier"); const { DatabaseReconciliationError } = await import("../../lib/database"); const secretLike = ["DB_PASSWORD_private123", "svc_api_token_abc", "role_secret_key_123"]; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management: { reconcileDatabases: async () => { throw new DatabaseReconciliationError( "database apply", Object.assign(new Error("Forbidden"), { statusCode: 403 }), { service: secretLike[1]!, username: secretLike[2]!, database: secretLike[0]!, secretName: "safe-secret-name" }, ); }, } as unknown as ManagementService, }); const response = await app(request( "/api/v2/workspaces/demo/databases", { method: "POST", headers: { "idempotency-key": "db-secret-identifier" }, body: JSON.stringify({ compose: {} }) }, "token", )); const responseBody = JSON.stringify(await response.json()); const operation = await operationStore.get("operation-db-secret-identifier"); expect(response.status).toBe(500); expect(responseBody).toContain("database apply for requested database claim: Forbidden (HTTP 403)"); expect(operation?.status.error?.message).toContain("database apply for requested database claim"); for (const identifier of secretLike) { expect(responseBody).not.toContain(identifier); expect(JSON.stringify(operation)).not.toContain(identifier); } }); test("logs allowlisted database failure metadata with the operation ID, never provider data", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" } }); const operationStore = new MemoryOperationStore(undefined, () => "diagnostic"); const logs: Record[] = []; const { DatabaseReconciliationError } = await import("../../lib/database"); const secretLike = "DB_PASSWORD_private123"; const cause = Object.assign(new Error(`token=${secretLike}`), { name: secretLike, code: "ECONNREFUSED", statusCode: 503, body: { message: secretLike, headers: { authorization: secretLike } }, stack: `Error: ${secretLike}\n at ${secretLike} (/tmp/${secretLike}/lib/database.ts:22:7)`, }); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, logger: { error: (entry) => logs.push(entry) }, management: { reconcileDatabases: async () => { throw new DatabaseReconciliationError("database apply", cause, { service: secretLike, username: secretLike, database: secretLike, secretName: secretLike, }); } } as unknown as ManagementService, }); const response = await app(request("/api/v2/workspaces/demo/databases", { method: "POST", body: JSON.stringify({ compose: {} }), }, "token")); expect(response.status).toBe(500); expect(await response.json()).toMatchObject({ code: "DATABASE_RECONCILE_FAILED", operationId: "operation-diagnostic", }); const diagnostic = logs.filter((entry) => entry.event === "operation.database_reconcile.failed"); expect(diagnostic).toHaveLength(1); expect(diagnostic[0]).toMatchObject({ operationId: "operation-diagnostic", phase: "database apply", errorClass: "UnknownError", providerCode: "ECONNREFUSED", providerStatus: 503, topFrame: "lib/database.ts:22:7", }); expect(JSON.stringify(diagnostic)).not.toContain(secretLike); expect(JSON.stringify(await operationStore.get("operation-diagnostic"))).not.toContain(secretLike); }); test("retains a safe diagnosis for an ordinary database provider error through HTTP, persistence and polling", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid" }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const operationStore = new MemoryOperationStore(undefined, () => "ordinary-db-error"); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, operationStore, management: { reconcileDatabases: async () => { throw Object.assign(new Error("provider failed: DATABASE_URL=postgresql://admin:private@db.example/app"), { statusCode: 403, body: { reason: "Forbidden", message: "password=private", code: 403 }, }); }, } as unknown as ManagementService, }); const reconcile = () => app(request( "/api/v2/workspaces/demo/databases", { method: "POST", headers: { "idempotency-key": "ordinary-db-error" }, body: JSON.stringify({ compose: {} }) }, "token", )); const expected = "Database reconciliation failed during operation execution: Forbidden (HTTP 403)"; for (const result of [await reconcile(), await reconcile()]) { expect(result.status).toBe(500); expect(await result.json()).toMatchObject({ code: "DATABASE_RECONCILE_FAILED", detail: expected, operationId: "operation-ordinary-db-error", }); } const persisted = await operationStore.get("operation-ordinary-db-error"); expect(persisted?.status.error).toEqual({ code: "DATABASE_RECONCILE_FAILED", message: expected }); const polled = await app(request("/api/v2/operations/operation-ordinary-db-error", {}, "token")); expect(polled.status).toBe(200); expect(await polled.json()).toMatchObject({ status: { error: { message: expected } } }); expect(JSON.stringify(persisted)).not.toContain("private"); }); test("routes workspace adoption and keeps platform adoption admin-only", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const adopted: string[] = []; const adoption = { adopt: async (workspaceId: string, workspaceUid: string) => { adopted.push(`${workspaceId}:${workspaceUid}`); return { workspaceId, workspaceUid, resourcesAdopted: 2 }; }, adoptPlatform: async (workspaceUid: string) => ({ workspaceId: "kuber-system", workspaceUid, resourcesAdopted: 1, }), }; const operatorApp = createApp({ store: await authenticatedStore("operator"), workspaceStore, adoption, }); const regular = await operatorApp( request("/api/v2/workspaces/demo/adopt", { method: "POST" }, "token"), ); expect(regular.status).toBe(200); expect(adopted).toEqual(["demo:workspace-uid"]); expect( ( await operatorApp( request( "/api/v2/platform/kuber-system/adopt", { method: "POST", body: JSON.stringify({ workspaceUid: "platform" }), }, "token", ), ) ).status, ).toBe(403); const adminApp = createApp({ store: await authenticatedStore("admin"), workspaceStore, adoption, }); const platform = await adminApp( request( "/api/v2/platform/kuber-system/adopt", { method: "POST", body: JSON.stringify({ workspaceUid: "platform" }) }, "token", ), ); expect(platform.status).toBe(200); }); test("audits failed workspace adoption with request correlation", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const auditStore = new MemoryAuditStore(); const logs: unknown[] = []; const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, auditStore, requestId: () => "adopt-request-123", logger: { error: (entry) => logs.push(entry) }, adoption: { adopt: async () => { throw new Error("provider adoption failed"); }, adoptPlatform: async () => ({ workspaceId: "kuber-system", workspaceUid: "platform", resourcesAdopted: 0, }), }, }); const result = await app( request("/api/v2/workspaces/demo/adopt", { method: "POST" }, "token"), ); expect(result.status).toBe(500); expect(await result.json()).toMatchObject({ code: "INTERNAL_ERROR", detail: "The request could not be completed", requestId: "adopt-request-123", }); expect(await auditStore.list("demo")).toMatchObject([ { spec: { action: "workspace.adopt", outcome: "failure", workspaceId: "demo", details: { route: "/api/v2/workspaces/demo/adopt", requestId: "adopt-request-123", }, }, }, ]); expect(logs).toMatchObject([ { event: "request.failed", requestId: "adopt-request-123", method: "POST", pathname: "/api/v2/workspaces/demo/adopt", workspaceId: "demo", status: 500, code: "INTERNAL_ERROR", errorName: "Error", message: "provider adoption failed", }, ]); }); test("forwards Kubernetes adoption errors with request correlation", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, requestId: () => "adopt-kubernetes-request-123", adoption: { adopt: async () => { throw { statusCode: 422, body: { apiVersion: "v1", kind: "Status", status: "Failure", reason: "Invalid", message: 'Ingress.networking.k8s.io "web" is invalid: spec: Required value', code: 422, }, }; }, adoptPlatform: async () => ({ workspaceId: "kuber-system", workspaceUid: "platform", resourcesAdopted: 0, }), }, }); const result = await app( request("/api/v2/workspaces/demo/adopt", { method: "POST" }, "token"), ); expect(result.status).toBe(422); expect(await result.json()).toMatchObject({ code: "KUBERNETES_ERROR", detail: 'Ingress.networking.k8s.io "web" is invalid: spec: Required value', requestId: "adopt-kubernetes-request-123", }); }); test("does not forward arbitrary adoption errors as Kubernetes errors", async () => { const workspaceStore = new MemoryWorkspaceStore({ uid: () => "workspace-uid", }); await workspaceStore.create({ id: "demo", source: { uri: "oci://example/demo", digest: "sha256:abc" }, }); const app = createApp({ store: await authenticatedStore("operator"), workspaceStore, adoption: { adopt: async () => { throw { statusCode: 422, body: { message: "arbitrary provider failure" }, }; }, adoptPlatform: async () => ({ workspaceId: "kuber-system", workspaceUid: "platform", resourcesAdopted: 0, }), }, }); const result = await app( request("/api/v2/workspaces/demo/adopt", { method: "POST" }, "token"), ); expect(result.status).toBe(500); expect(await result.json()).toMatchObject({ code: "INTERNAL_ERROR", detail: "The request could not be completed", }); }); });