// Cloud-only: the Organization keys SECTION of the API keys page — the console // surface over `/api/account/org-api-keys`, minting the machine credential for // the tenant-wide admin plane. // // Two members are built through the real flows. The guarantees pinned here: // // 1. an ADMIN sees the section, mints an org key through the dialog, gets the // one-time reveal, and the minted value ACTUALLY authenticates the admin // API (the whole point of the credential); // 2. the listing shows the key afterward and revoke asks for confirmation // before killing it — after which the value stops authenticating; // 3. a PLAIN MEMBER never sees the section at all. // // Runs against emulate >= 0.13.9, whose WorkOS emulator serves the org-key // routes (list/mint via /organizations/:id/api_keys, org-owner validation) — // the gap that previously kept this scenario impossible. import { expect } from "@effect/vitest"; import { Effect } from "effect"; import { scenario } from "../src/scenario"; import { Browser, Target } from "../src/services"; import { forBrowser, joinOrg } from "./support/session"; import { visit } from "../src/surfaces/browser"; declare global { interface Window { __e2eCopied?: Array; } } scenario( "Admin · organization keys are minted in the console and authenticate the admin API", { timeout: 180_000 }, Effect.gen(function* () { const target = yield* Target; const browser = yield* Browser; const admin = yield* target.newIdentity(); const invitee = yield* target.newIdentity({ org: false }); const member = yield* joinOrg(target, admin, invitee); let mintedValue = ""; // ── The admin's view: mint, verify, revoke ────────────────────────────── yield* browser.session(forBrowser(admin), async ({ page, step }) => { let slug = ""; await step("Land in the workspace and open the API keys page", async () => { await visit(page, "/"); await page.waitForURL((url) => /^\/[a-z0-9-]+\/?$/.test(url.pathname), { timeout: 30_000, }); slug = new URL(page.url()).pathname.split("/").filter(Boolean)[0] ?? ""; await page.getByRole("link", { name: "API keys" }).click(); await page.waitForURL((url) => url.pathname === `/${slug}/api-keys`, { timeout: 30_000 }); }); await step("The admin is offered the Organization keys section", async () => { await page .getByRole("heading", { name: "Organization keys", exact: true }) .waitFor({ state: "visible", timeout: 30_000 }); }); await step("Mint an org key through the dialog and capture the reveal", async () => { await page.getByRole("button", { name: "New org key" }).click(); const dialog = page.getByRole("dialog"); await dialog.getByLabel("Name").fill("e2e backend reader"); await dialog.getByRole("button", { name: "Create key" }).click(); // The one-time secret panel renders once the key exists; its first // input holds the plaintext value (same shape the personal-key // feedback scenario reads). await dialog.getByText("It is only shown once").waitFor({ timeout: 30_000 }); mintedValue = await dialog.locator("input").first().inputValue(); expect(mintedValue, "a real key value is revealed once").toMatch(/^sk_/); await dialog.getByRole("button", { name: "Close", exact: true }).first().click(); }); await step("The minted key appears in the org listing", async () => { await page .getByText("e2e backend reader") .first() .waitFor({ state: "visible", timeout: 30_000 }); }); await step("The minted value authenticates the tenant-wide admin API", async () => { // The credential's purpose, proven from outside the browser: a backend // holding ONLY this value can read the admin plane. const response = await fetch(new URL("/api/admin/users", target.baseUrl), { headers: { authorization: `Bearer ${mintedValue}` }, }); expect(response.status, "the org key reads the admin plane").toBe(200); const body = (await response.json()) as { users: ReadonlyArray<{ email: string | null }>; }; expect( body.users.map((user) => user.email), "and sees the workspace's members", ).toContain(admin.credentials?.email); }); await step("Revoke asks for confirmation, then the key stops working", async () => { await page.getByRole("button", { name: "Revoke e2e backend reader" }).click(); // The confirm dialog names the key and warns; nothing is revoked yet. await page .getByRole("heading", { name: "Revoke organization key" }) .waitFor({ state: "visible", timeout: 30_000 }); await page.getByRole("button", { name: "Revoke key" }).click(); await page .getByRole("heading", { name: "Revoke organization key" }) .waitFor({ state: "hidden", timeout: 30_000 }); // The revoked value no longer authenticates. const after = await fetch(new URL("/api/admin/users", target.baseUrl), { headers: { authorization: `Bearer ${mintedValue}` }, }); expect(after.status, "the revoked key is refused").toBe(401); }); }); // ── The plain member's view ─────────────────────────────────────────── yield* browser.session(forBrowser(member), async ({ page, step }) => { await step("A plain member is not shown the Organization keys section", async () => { await visit(page, "/"); await page.waitForURL((url) => /^\/[a-z0-9-]+\/?$/.test(url.pathname), { timeout: 30_000, }); const slug = new URL(page.url()).pathname.split("/").filter(Boolean)[0] ?? ""; await visit(page, `/${slug}/api-keys`); // The personal half renders for everyone… await page .getByRole("heading", { name: "Personal keys" }) .waitFor({ state: "visible", timeout: 30_000 }); // …the org section does not exist for a non-admin. expect( await page.getByRole("heading", { name: "Organization keys", exact: true }).count(), "a plain member is not shown a section that would only refuse them", ).toBe(0); }); }); }), );