Tighten §3 comments (todo §3); drop stale 'next §3 item' forward-refs, condense compose/Ory/bootstrap headers
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
// One-command bootstrap (todo §3, the MVP bar). Runs as the one-shot `bootstrap` compose
|
||||
// service after kratos+keto are healthy; `web` waits for it to finish. Idempotent — safe
|
||||
// to re-run on every `docker compose up`:
|
||||
// One-command bootstrap (todo §3, the MVP bar). One-shot compose service: runs after
|
||||
// kratos+keto are healthy (web waits on it), idempotent on every `docker compose up`:
|
||||
// 1. generate the JWKS signing key if absent (committed dev key makes this a safety net);
|
||||
// 2. seed a demo admin identity (admin@plainpages.local / admin) in Kratos;
|
||||
// 2. seed a demo admin (admin@plainpages.local / admin) in Kratos;
|
||||
// 3. grant it the `admin` role in Keto so menu/permission checks resolve out of the box.
|
||||
// On finish it prints a first-run banner (login URL + creds + change-before-prod warning).
|
||||
// Fails loud on any unexpected upstream error.
|
||||
// Then prints a first-run banner; fails loud on any unexpected upstream error.
|
||||
import { existsSync, writeFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { generateJwks, type JwkSet } from "./gen-jwks.ts";
|
||||
|
||||
@@ -68,10 +68,9 @@ export function loadConfig(env: Env = process.env): Config {
|
||||
cacheTemplates: readBool(env, "CACHE_TEMPLATES", false),
|
||||
cookieSecret: readSecret(env, "COOKIE_SECRET", "dev-insecure-cookie-secret", requireSecure),
|
||||
csrfSecret: readSecret(env, "CSRF_SECRET", "dev-insecure-csrf-secret", requireSecure),
|
||||
// The session JWT is signed by the Kratos tokenizer key (kratos.yml jwks_url); the §4
|
||||
// verifier reads that same key. Kratos does not republish it over HTTP, so default to a
|
||||
// file:// of the tokenizer JWKS mounted into the web container (compose.yml) — not a
|
||||
// well-known endpoint. Prod overrides with a real key (README: JWT signing key & rotation).
|
||||
// §4 verifier reads the same key the Kratos tokenizer signs with (kratos.yml jwks_url).
|
||||
// Kratos doesn't republish it over HTTP, so default to a file:// of the tokenizer JWKS
|
||||
// mounted into web (compose.yml). Prod overrides with a real key (README: rotation).
|
||||
jwksUrl: readUrl(env, "JWKS_URL", "file:///etc/config/kratos/tokenizer/jwks.json"),
|
||||
ketoReadUrl: readUrl(env, "KETO_READ_URL", "http://keto:4466"),
|
||||
ketoWriteUrl: readUrl(env, "KETO_WRITE_URL", "http://keto:4467"),
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { generateKeyPairSync, randomUUID } from "node:crypto";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
// ES256 signing JWKS for the Kratos session tokenizer (§3). Ory recommends ES* over the
|
||||
// symmetric HS family; ES256 is also our verifier's preferred alg (src/jwt.ts). Kratos
|
||||
// signs with the FIRST key in the set and the app verifies by `kid` (§4) — so rotation is
|
||||
// prepend a fresh key, keep the old one ~one TTL (10m) for in-flight tokens, then drop it.
|
||||
// (Re)generate the committed dev key (prod supplies its own — see README):
|
||||
// docker compose run --rm -T web node src/gen-jwks.ts > ory/kratos/tokenizer/jwks.json
|
||||
// ES256 signing JWKS for the Kratos session tokenizer (§3) — Ory-recommended and the
|
||||
// verifier's preferred alg (src/jwt.ts). Rotation runbook: README, JWT signing key.
|
||||
// (Re)generate the committed dev key (prod supplies its own):
|
||||
// docker compose run --rm -T --no-deps web node src/gen-jwks.ts > ory/kratos/tokenizer/jwks.json
|
||||
|
||||
export interface SigningJwk {
|
||||
kid: string;
|
||||
|
||||
@@ -70,7 +70,7 @@ test("session settings: branded cookie, bounded lifespan, sliding refresh", () =
|
||||
|
||||
test("session tokenizer template 'plainpages' mints a short-lived signed JWT", () => {
|
||||
// whoami(tokenize_as: plainpages) → a locally-verifiable JWT, so the hot path never
|
||||
// calls Ory (§4). The JWKS signer is generated/mounted by the next §3 item.
|
||||
// calls Ory (§4). Signed with the committed tokenizer/jwks.json (gen-jwks.ts).
|
||||
assert.match(kratosYml, /tokenizer:\s*\n\s*templates:\s*\n\s*plainpages:/, "plainpages template defined");
|
||||
assert.match(kratosYml, /ttl:\s*10m/, "~10m TTL — re-minted on refresh");
|
||||
assert.match(kratosYml, /subject_source:\s*id/, "sub = the Kratos identity id");
|
||||
|
||||
Reference in New Issue
Block a user