The local e2e SSO
scripts/e2e/sso.sh runs a separate, local Bookbag SSO on ports 8290, 3290 and 8299 for testing EvalBook with CodeBook and MadeBook; what it starts, what it writes, and the cookie caveat.
scripts/e2e/sso.sh runs a separate, local Bookbag SSO for testing EvalBook against CodeBook and MadeBook. It never touches the owner's development SSO and never production. It lives in its own checkout, the Bookbag/SSO-evalbook worktree on branch feat/evalbook, with its own databases, its own encryption key and a model provider that is a test double.
| e2e SSO | the owner's SSO (never touched) | |
|---|---|---|
| checkout | Bookbag/SSO-evalbook (feat/evalbook) |
Bookbag/SSO |
| API and issuer | http://localhost:8290 |
:8090 |
| web (sign-in, admin) | http://localhost:3290 |
:3200 |
| databases | fresh components/*/db/e2e.sqlite3 in the worktree |
development.sqlite3 |
| encryption key | generated once into SSO-evalbook/.env.e2e (gitignored, chmod 600) |
its own |
| AI provider | scripts/e2e/ai-stub.mjs on :8299, a test double |
whatever the owner set |
Use
source ~/.nvm/nvm.sh && nvm use 24.19.0
export E2E_SECRETS_DIR=/somewhere/private # optional; default log/e2e/secrets (gitignored)
scripts/e2e/sso.sh start # first start bootstraps everything; later starts reuse it
scripts/e2e/sso.sh verify # live checks, PASS/FAIL per line, exit code = failures
scripts/e2e/sso.sh status
scripts/e2e/sso.sh stop # stops only the processes it started, by PID
Logs and PIDs are in log/e2e/.
What the first start does
-
Writes
SSO-evalbook/.env.e2ewith a random 32-byteSSO_ENCRYPTION_KEY, after checking that git ignores it, and derives ane2eenvironment file (no secrets) from the development one: port 8290, issuerhttp://localhost:8290, UIhttp://localhost:3290, every context on its owne2e.sqlite3. -
Starts the AI stub, then creates the schema and applies the migrations.
-
Registers three apps with SSO's own registration script:
app origin peer path evalbookhttp://localhost:3006/project/api/peercodebook(its e2e instance)http://localhost:3283/workspace/api/peermadebook(its e2e instance)http://localhost:3281/workspace/api/peerEach app token is written to
$E2E_SECRETS_DIR/tokens.envasEVALBOOK_SSO_APP_TOKEN,CODEBOOK_SSO_APP_TOKENandMADEBOOK_SSO_APP_TOKEN, withSSO_ISSUER. SSO shows a token once; if one is missing from the file the app is re-registered with--rotate, which retires the old token. -
Creates a local-only platform admin,
e2e-admin@bookbag.test, with a generated password written to$E2E_SECRETS_DIR/admin.env(E2E_ADMIN_EMAIL,E2E_ADMIN_PASSWORD). -
Registers the stub as the platform's provider (
custom, base URLhttp://localhost:8299/v1, chat modelevalbook-stub-chatas the default, embedding modelevalbook-stub-embed). -
Starts the SSO API (
master=e2e) and the SSO web app on 3290 with its own dist directory and its API addresses pointing at:8290, so it never proxies to:8090.
Both .env files are chmod 600, and no token, password, key or peer secret is ever printed. The SSO API runs with SSO_ALLOWED_ORIGINS set to its web origin and the three product origins, SSO_CHAT_ORIGINS set to the three product origins, and SSO_PRIVATE_HOSTS covering localhost and 127.0.0.1 on 3006, 8086, 3283, 8283, 3281 and 8281, so events can reach the products' local receivers once their events URLs are set in the e2e SSO's app registry at http://localhost:3290/admin/apps.
Pointing EvalBook at it
In .env.local: SSO_ORIGIN=http://localhost:8290, SSO_UI_ORIGIN=http://localhost:3290, and SSO_APP_TOKEN copied from tokens.env with an editor (do not echo it). In nextjs-app/.env.local: NEXT_PUBLIC_SSO_ORIGIN=http://localhost:3290. EvalBook asks SSO for its client id and redirect address at /apps/api/bootstrap, and the products learn each other and the peer secret from /apps/api/peers. The rest of the local setup is on Local development.
The AI stub is a test double
ai-stub.mjs answers the chat-completions wire (blocking and streamed) and the embeddings wire deterministically, with usage counted from the text, so SSO meters and ledgers every call exactly as it would a real provider's. The reply is [ai-stub] <hash>, or whatever follows STUB_REPLY: in the last user message; STUB_TOOL: <name> <json> returns a tool call and STUB_FAIL: <status> an error. Every response is marked X-Test-Double: evalbook-ai-stub.
Nothing it says is a measurement. A judge run on it proves the plumbing (budget reservation, idempotent charge, the AiCall record), not the output, and nothing scored by it counts as evidence. See LLM judges.
Caveats
- Cookies are not port-scoped. The e2e SSO's session cookie and the owner's SSO on
:8090share the namessoonlocalhost; signing in to one in a browser replaces the other's session. Use a separate browser profile for the e2e SSO. - Do not run a production build in
SSO-evalbook/nextjs-appwhile its dev server is up; stop it first withsso.sh stop. - Starting fresh:
sso.sh stop, then deleteSSO-evalbook/components/*/db/e2e.sqlite3and the secrets files; the nextstartbootstraps again. Keep.env.e2eunless you also delete the databases, because the signing key and the platform AI key are sealed with it.