Tags

Tags give the ability to mark specific points in history as being important
  • v0.16.1

    protected
    45c87f78 · release: 0.16.1 ·
    Release: auth v0.16.1
    0.16.1 — 2026-10-18
    
    Carries 0.16.0, whose tag was never published, and pins deploy/example to the release image. Adds `contract/`, which pins what the portal depends on in an Ory config, and `check-ory`, an opt-in validator for a deployment's own finished files. A deployment that renders its configs needs no change.
    
    - `contract/` holds the Kratos and Hydra schemas the portal depends on. `node dist/server/config.mjs check-ory` validates a deployment's own `kratos.yml`, `hydra.yml`, identity schema and recovery-gate hook against it.
    - The OTLP endpoint is quoted in the `tracing` blocks of `kratos.yml` and `hydra.yml`. Optional: `git diff v0.15.0..v0.16.1 -- kratos hydra`.
    - Hardening: identity headers with underscores in their names are dropped at the edge, and the device verify rate limit also matches a trailing path.
    - Render refuses more line-break characters in values, and a failed render clears the earlier output.
    
    - Deployment: non-breaking; `check-ory` is opt-in, see Config changes in CHANGELOG.md.
  • v0.16.0

    protected
    88e0be8d · release: 0.16.0 ·
    0.16.0 — 2026-10-18
    
    Adds `contract/`, which pins what the portal depends on in an Ory config, and `check-ory`, an opt-in validator for a deployment's own finished files. A deployment that renders its configs needs no change.
    
    - `contract/` holds the Kratos and Hydra schemas the portal depends on. `node dist/server/config.mjs check-ory` validates a deployment's own `kratos.yml`, `hydra.yml`, identity schema and recovery-gate hook against it.
    - The OTLP endpoint is quoted in the `tracing` blocks of `kratos.yml` and `hydra.yml`. Optional: `git diff v0.15.0..v0.16.0 -- kratos hydra`.
    - Hardening: identity headers with underscores in their names are dropped at the edge, and the device verify rate limit also matches a trailing path.
    - Render refuses more line-break characters in values, and a failed render clears the earlier output.
    
    - Deployment: non-breaking; `check-ory` is opt-in, see Config changes in CHANGELOG.md.
  • v0.15.0

    protected
    e2903711 · release: 0.15.0 ·
    Release: auth v0.15.0
    0.15.0 — 2026-10-12
    
    The image carries the Ory and edge policy and renders it from the deployment's env and content tree at `/etc/othala`. This is a breaking release: an existing deployment follows the seven Deployment changes steps in CHANGELOG.md, and `deploy/example/` is the end state.
    
    - `node dist/server/config.mjs render` writes `kratos.yml`, `hydra.yml`, the courier templates and `othala.caddy` from env and the content root. It refuses a blank secret, a leftover `${` and malformed YAML, and writes owner-only files. `check` validates env and content offline; `gen-secrets` mints every secret except the SMTP URI.
    - `othala.caddy` holds three snippets: `othala-routes`, `othala-forward-auth` and `othala-oidc-app`. They strip client-supplied identity headers by family, rate-limit device and self-service, and answer 403 and 503 in place.
    - Content moves to `/etc/othala` (`apps/`, `groups.yaml`, `courier/`). A retired or unknown `OTHALA_*` env name stops the portal and fails `check`.
    - `deploy/example/` is a compose deployment, and e2e runs it. Every Ory service runs as uid 10000.
    - `scripts/render-config.sh`, `caddy/Caddyfile`, `caddy/snippets/` and `e2e/gen-secrets.sh` are removed.
    - Opening Admin from a session that needed a second factor now returns to the admin page instead of a not-found page.
    - The `:latest` image tag and its signature move only on a release tag.
    
    - Deployment: breaking; see Deployment changes in CHANGELOG.md.
  • v0.14.0

    protected Release: auth v0.14.0
    0.14.0 — 2026-10-11
    
    The home page lists every app with its full description, in calm sections.
    
    - App tiles are rows with the logo, the name and the full description, with no truncation. They sit in two columns on wider screens and one on phones.
    - Sections have real headings, and each tile has a labelled Guide button.
    - Apps without a logo show initials on a monogram plate. Single-colour logos invert in dark mode.
    - The guide dialog shows the app's address, which the tile no longer carries.
    - Astro 7.3.6 refuses cross-site form posts from the `Sec-Fetch-Site` header first, and the CSRF tests now send real cross-site headers. Playwright moves to 1.64 and OpenTelemetry to 0.223.
    
    - None: image bump only.
  • v0.13.3

    protected Release: auth v0.13.3
    0.13.3 — 2026-10-10
    
    App logos now live beside each manifest, and passkeys carry a clearer name.
    
    - App logos are served from `<stem>.svg` files beside each `<stem>.yaml` manifest. The image ships no app logos.
    
    - Passkey and security-key names read "<instance name> Single Sign-On". The relying-party id is unchanged, so existing passkeys keep working; saved items keep their old label until renamed.
    - The web app manifest's name follows `OTHALA_INSTANCE_NAME`.
    - The consent screen shows the monogram only.
    - Documentation is shorter across the README, architecture, decisions, security and guides.
    
    - The `icon_slug` and `icon_fallback` manifest fields are retired: ignored at serve time and rejected by manifest-lint. The bundled icon set is removed.
    
    - A logo is served only to a signed-in member who can see that tile, sandboxed (`Content-Security-Policy: sandbox`, `nosniff`, private cache). Every other request gets the same 404.
    
    - The cookie-rotation runbook now states the shipped single-slot behavior: rotation signs every member out. The secret-rotation and backup runbooks now say `secrets.system` encrypts Hydra's signing keys and session data, while client secrets are hashed.
    
    - Put `<stem>.svg` beside each `<stem>.yaml` in the manifest directory (stem = the manifest filename, the same key as `<stem>.md`). At most 32 KiB, with an `<svg>` root.
    - Remove `icon_slug` and `icon_fallback` from your manifests.
    - Copy `*.svg` alongside `*.yaml` and `*.md` into the mounted manifest directory, and do not prune them.
    - Re-vendor `kratos/kratos.yml`.
    - No environment changes.
  • v0.13.2

    protected Release: auth v0.13.2
    0.13.2 — 2026-10-09
    
    Two more app tiles get their real logos.
    
    - Two more app tiles show the projects' real logos, and two unused icons are removed.
  • v0.13.1

    protected Release: auth v0.13.1
    0.13.1 — 2026-10-09
    
    Enrollment is easier to follow, and app tiles show the real software logos.
    
    - TOTP enrollment shows the setup key as text beside the QR code, with no click to reveal.
    - The setup-link result leads with **Copy message** (link and code together). **Copy link** and **Copy code** sit beside it and copy only what they say.
    - When an identity has no password yet, the settings password panel is open on load, so a password manager finds the field without a click.
    - App tiles use the projects' real logos instead of hand-drawn plates, and unused icons are removed. A tile whose icon slug no longer resolves shows its monogram. `portal/public/icons/NOTICE` credits each source and license.
  • v0.13.0

    protected Release: auth v0.13.0
    0.13.0 — 2026-10-08
    
    Apps without a secret can sign in, one bad app file no longer takes the rest down, and devices without a browser can sign in with a code.
    
    - Public clients: an app manifest can register a client without a secret.
    - Device authorization grant (RFC 8628) for devices without a browser. The person enters the code on the portal, signs in, and confirms a screen that shows the same code, so a link carrying someone else's code is caught.
    - Device logins need a second factor. A passkey-only identity is refused, because Kratos counts a passkey as aal1.
    
    - An invalid app manifest is quarantined: it is dropped with a logged reason and its app is refused at login and consent, while the other apps keep serving. Before, one bad file failed the whole set. A quarantined app's Hydra client keeps its refresh tokens and its client_credentials grant working until the manifest is fixed or the client is deleted from Hydra.
    - Consumers re-vendor `hydra/hydra.yml`, which now enables the device grant and pins the user-code lifetime.
    - Consumers add the device routes to their Caddyfile and the `othala_device` rate-limit zone for `/oauth2/device/auth` and `/device/verify`; see `caddy/Caddyfile`.
    
    - Accepted risk: a denied or refused device code answers `authorization_pending` to the device's poll until the code expires.
  • v0.12.0

    protected Release: auth v0.12.0
    0.12.0 — 2026-10-03
    
    Emails name the household, the portal runs on Node 24, Kratos and Hydra updates arrive the day they ship, and code that served old shapes is gone.
    
    ### Added
    
    - Recovery, sign-in code and email-verification emails name the household, say where to enter the code and how long it lasts, and end with a warning not to share it.
    
    ### Changed
    
    - The portal builds and runs on Node 24 LTS.
    - Admins invite a person with the setup link only.
    - ID-token claims are always limited to the scopes the app was granted.
    - `oidc.client_id` must match `^[a-z][a-z0-9]*$`.
    - Kratos and Hydra updates are proposed the day they are released, as one reviewed change.
    - Deployers render and mount the email templates in `kratos/courier/` with `scripts/render-config.sh`, next to `kratos.yml`. Kratos reads a template once, so a re-render needs a Kratos restart.
    
    ### Removed
    
    - The "Email a code instead" invite. Its code could not be redeemed, because Kratos binds a recovery code to the flow that sent it.
    - `presentation.access_group`. Use `presentation.access`, a list. A manifest without it gets no access. A manifest without an `oidc:` block is rejected as invalid.
    - The `admin` identity group. Household admin is the admin marker only.
  • v0.11.0

    protected Release: auth v0.11.0
    0.11.0 — 2026-10-03
    
    Signing out and removing access now also ends app sign-ins, apps that ask for a fresh sign-in get one, and people with elevated app roles keep a second factor.
    
    ### Changed
    
    - Signing out of the portal also ends your app sign-ins and app access on every device. Apps with a back-channel logout address are told at once; other apps keep their own session until it expires.
    - Removing someone's groups, roles or admin marker now also ends their app sign-ins on every device, not only their app access. They stay signed in to the portal.
    - People who hold a role above an app's entry level keep at least one authenticator app or security key through their settings page, as admins do.
    - Settings tells an admin with one security key and no authenticator app how to add a second key.
    - Expired-page and code messages say how long codes last and cover replaced pages.
    - A skip-to-content link, and 44px header links.
    
    ### Fixed
    
    - Apps that ask for a fresh sign-in (`prompt=login`) or a maximum sign-in age (`max_age`) get one: an older portal session goes through a fresh sign-in first. A `max_age` under 30 seconds is treated as 30 seconds.
    - Kratos and Hydra calls from the portal, and outgoing mail, time out instead of hanging a request.
  • v0.10.3

    protected Release: auth v0.10.3
    0.10.3 — 2026-10-02
    
    Second-factor and sign-out rules for elevated app roles, a group-aware forward-auth snippet, and clearer errors and logs.
    
    ### Changed
    
    - Giving someone an app role above the app's entry level now requires them to have an authenticator app or security key first, as making them an admin already does. This holds when adding a person and when editing one. People who already hold such a role can still be edited or lowered.
    - An admin cannot remove the last authenticator app or security key of someone who holds such a role.
    - Removing another person's authenticator app, security key or backup codes also signs them out everywhere. The lost-device runbook no longer has a separate sign-out step.
    - The admin audit log records person creation (`create-user`). A write that landed but whose follow-up step failed is recorded as `partial` instead of `refused` or `ok`, and an admin who gives up their own access is told if their app grants could not be revoked.
    - The reference `forward-auth` snippet calls the portal's `/api/forward-auth` and takes a third argument, the required group. A signed-in member outside the group gets 403. Copies of the snippet need the new argument.
    - Upstream failures (Kratos, Hydra) in sign-in, consent and forward-auth are logged to stderr with the failing step. Responses are unchanged.
    - Code-entry screens remind people to check spam or junk. An admin's page points to the admin-recovery runbook.
    - The copy button in app guides is a full-size tap target.
    - `SECURITY.md` lists the accepted risk for members with no second factor.
    
    ### Fixed
    
    - A Kratos outage shows "Back in a moment" instead of asking people to sign in again.
    - `@opentelemetry/sdk-trace-base` is declared as a direct dependency. It was already installed.
    
    ### Removed
    
    - The `/admin/activity` redirect stub. It now returns 404.
  • v0.10.2

    protected Release: auth v0.10.2
    0.10.2 — 2026-10-01
    
    Internal simplification. No behavior change.
    
    ### Changed
    
    - The server entry is TypeScript, bundled like the other server entries. `dist/server/listen.mjs` and `npm start` are unchanged.
    - Every Kratos hook checks its bearer through one helper.
    - CI type-checks every TypeScript file: portal, e2e and site.
  • v0.10.1

    protected Release: auth v0.10.1
    0.10.1 — 2026-10-01
    
    A readiness check that reads its dependencies, an audit line per admin action, and one access decision.
    
    ### Changed
    
    - `/readyz` on the admin listener checks Kratos and Hydra readiness. It answers 503 and names the dependency that is not ready. `/healthz` stays liveness only.
    - App sign-in, forward-auth, admin pages and emailed-code sessions are decided by one function over one parsed identity. The access rules are unchanged.
    - `DEPLOY.md`: verify the image signature with cosign before pinning, and pin by tag and digest. Take a `pg_dump` before any deploy that changes an Ory pin; rolling back across that change means restoring it.
    
    ### Added
    
    - Each admin action writes one JSON line to stdout: `event`, `action`, `actor`, `target` and `result`, with identity ids only.
    - CI fails on a detected secret or an untrackable image pin, and runs the manifest lint.
  • v0.10.0

    protected Release: auth v0.10.0
    0.10.0 — 2026-10-01
    
    An apps-first home with setup guides, and fewer env vars.
    
    ### Added
    
    - The signed-in home is an apps-first tile grid with a top bar for account actions.
    - Apps can carry a setup guide and `presentation.requires` prerequisites defined under `requirements/`; a tile shows readiness.
    - `manifest-lint` warns on an undefined `presentation.requires` name.
    - Account settings groups sign-in, two-step, recovery and profile into cards, with named passkeys and in-place enrollment.
    
    ### Removed
    
    Delete each from the deploy environment.
    
    - `OTHALA_DEFAULT_SCHEMA_ID`: Kratos defaults.
    - `OTHALA_WEBAUTHN_RP_ID`, `OTHALA_WEBAUTHN_RP_ORIGINS`: `kratos.yml` uses `OTHALA_APEX` and `OTHALA_PUBLIC_URL`.
    - `OTHALA_SMTP_FROM_ADDRESS`: mail comes from `noreply@<OTHALA_APEX>`.
    - `OTHALA_SITE_NAME`: `OTHALA_INSTANCE_NAME` is the brand name, now required.
    - `OTHALA_ADMIN_CONTACT`: the dashboard says "your administrator".
    - `OTHALA_DEFAULT_GROUP`, `OTHALA_IDENTITY_GROUPS`: fixed at `admin` and `everyone`.
    - `OTHALA_ADMIN_FRESHNESS_HOURS`: step-up is 1h.
    - `OTHALA_HIBP_ENABLED`, `OTHALA_PASSWORD_MIN_LENGTH`: breach check on, minimum 12.
    - `OTHALA_CORS_ALLOWED_ORIGINS`: Hydra allows `OTHALA_PUBLIC_URL`.
    - `OTHALA_PUBLIC_HOST`: the Caddyfile uses `OTHALA_PUBLIC_URL`.
    - `OTHALA_OTLP_PROVIDER`, `OTHALA_OTLP_ENVIRONMENT`, `OTEL_*`, `OTLP_INGEST_TOKEN`: use `OTHALA_OTLP_ENDPOINT`.
    - `KRATOS_PUBLIC_URL`, `HYDRA_PUBLIC_URL`, `KRATOS_ADMIN_URL`, `HYDRA_ADMIN_URL`, `KRATOS_ADMIN_TOKEN` and `HYDRA_ADMIN_TOKEN`: fixed at `kratos:4433`, `kratos:4434`, `hydra:4445`, no bearer.
    - `ADMIN_HOST`: renamed `PORTAL_ADMIN_BIND_HOST`, required in production.
    - `KRATOS_PG_HOST`, `HYDRA_PG_HOST`, `KRATOS_ADMIN_HOST` and `CONSENT_HOST`: hosts are `postgres`, `kratos`, `othala`.
    - `MANIFEST_DIR` (production reads `/etc/portal/manifests`), `PORT`, `HOST`, `ADMIN_PORT`, `PORTAL_LOGIN_URL` and `PORTAL_CONSENT_URL`: fixed.
    - `SMTP_USER`, `SMTP_PASS`, `ACME_EMAIL`, Kratos and Hydra `DSN`: credentials ride in `OTHALA_SMTP_CONNECTION_URI` and `dsn`.
    
    ### Changed
    
    - Production needs `OTHALA_INSTANCE_NAME`, `OTHALA_CONTACT_RECIPIENT` and `OTHALA_SMTP_CONNECTION_URI`.
    - Only a password change signs out other sessions; passkey, key, app and backup-code changes keep them.
    - Kratos and Hydra trace with `OTHALA_OTLP_ENDPOINT`.
    - Kratos login flow lifespan is 1h, up from 10m.
    - Kratos public CORS is off.
    - Caddy `othala_selfservice` limit is 30/min, up from 10.
    - `kratos.yml` and `hydra.yml` drop keys restating upstream defaults.
    - The e2e suite creates an identity through the admin form and always runs the Caddy edge.
    
    ### Fixed
    
    - `/admin/users/new` creates the identity email-verified (`email_verified: true` in the id_token).
  • v0.8.0

    protected Release: auth v0.8.0
    0.8.0 — 2026-09-30
    
    Apps receive only the groups they bind, privileged roles sign in at aal2, and revoking a person reaches apps by back-channel logout.
    
    - An app's `groups` claim carries only the groups its manifest binds (`presentation.access` and `group_role_map` keys) plus its role's `claim_emit`; identity groups and other apps' groups are no longer sent.
    - An identity that resolves to a role above an app's entry role signs in to apps and forward-auth edges at aal2, as admin-marked identities already do.
    - While no manifest set has loaded, forward-auth answers 503 to an aal1 session.
    - The step-up notice for an account without a second factor points to Settings to enrol one.
    - Force re-login, delete and sign out everywhere revoke each Hydra login session by id, so apps with a `backchannel_logout_uri` receive a logout token.
    - Consent is no longer remembered in Hydra; the manifest's `skip_consent` decides whether the grant screen is shown.
    - Refresh tokens issued before 0.8.0 keep their claims until their consent sessions are revoked; revoke consent for every subject once after deploying.
  • v0.7.1

    protected Release: auth v0.7.1
    0.7.1 — 2026-09-30
    
    Release hardening: rate limits key on the real client, and release jobs wait for e2e.
    
    - Self-service rate limits key on the client address, trusting `X-Forwarded-For` only from private-range proxies.
    - The SBOM and release jobs run only after e2e passes.
    - Pipeline components pin to 4.8.0, the reference docs to `v0.6.0`, and the portal runtime image to a digest.
    - Leftover source-comment headers are trimmed, and the unused `axe-core` e2e dependency is removed.
    - Renovate: lock file maintenance, and the `ubi10/nodejs-22` 10.2 image digest.
  • v0.7.0

    protected Release: auth v0.7.0
    0.7.0 — 2026-09-30
    
    Fewer moving parts: one registration lane, one Kratos client, one logout path.
    
    - Profile changes need a sign-in from the last 5 minutes (was 15).
    - An account with a passkey or password changes its email or recovery email only from a session whose newest sign-in used a passkey or password; the profile hook is now `/admin/profile-gate`.
    - Signing in to an app after another account signed out of the shared browser starts a fresh app sign-in; a sign-out an app did not start goes through the portal's own sign-out.
    - Every state-changing portal form carries a token bound to its action; the portal refuses to start without a `CSRF_SECRET` of at least 32 bytes.
    - Client registration runs only in the portal, on boot; the one-shot registration command, its compose service and its docs are gone.
    - The portal image builds on `ci-runtime-node` 4.8.0.
    - Source comments and docs are trimmed, and the tracked-prose ceiling drops to 153,000 bytes.
    
    - `POST /admin/revoke-user` and `OTHALA_ADMIN_ENDPOINT_BEARER`; the admin console covers the same ground.
    - `HYDRA_PAIRWISE_SALT` and the Hydra pairwise block.
    - LDAP remnants: the `ldap-app` snippet, the lab `glauth.cfg` and `filedrop` fixture, the LDAP bridge settings, and the `ldap` and `oidc+ldap` tile kinds.
    - The `admin-session` snippet, `scripts/pre-tag-check.sh`, the two CI jobs that compared mirrored copies, and the `is_admin` and `groups` fields of the gate webhook body; the gates read the admin API.
  • v0.6.4

    protected Release: auth v0.6.4
    othala v0.6.4
    
    Session and profile lifecycle: access ends where it should, identity fields
    apps key on are admin-controlled, and admin accounts cannot lock themselves
    out.
    
    - Deleting an identity, or removing a group or role, revokes its app grants;
      signing out of an app also ends the portal session.
    - Usernames are admin-controlled; saving profile settings ends the account's
      other sessions; email_verified reflects only the account's own address.
    - Admin accounts keep a second factor through settings, and the admin console
      refuses to deactivate yourself or the last active admin.
    - Signing out takes a token-bound form post; the request form requires a
      signed-in account; the error page shows only reasons it recognises.
    - The password policy rejects any known-breached password and fails closed.
    - Reference edge snippets pass the verified identity id upstream and keep the
      Kratos session cookie away from app backends.
  • v0.6.3

    protected Release: auth v0.6.3
    othala v0.6.3
    
    Second-factor step-up at app sign-in.
    
    - Signing in to connected apps now completes second-factor verification for
      accounts with one enrolled, and for admin accounts. Admin accounts sign in
      with a passkey or password rather than an emailed code. Granting admin
      requires an enrolled second factor.
  • v0.6.2

    protected Release: auth v0.6.2
    othala v0.6.2
    
    Quieter health-probe logs, a markdown-sanitizer gap closed, and three
    routine dependency majors.
    
    - `kratos.yml`/`hydra.yml` set `request_log.disable_for_health: true` on both
      listeners, so health probes stop logging. Hydra's admin listener logs them
      anyway: probe Hydra's public `/health/ready`, as e2e does (smoke A0).
    - Base image UBI 9 -> UBI 10; isomorphic-dompurify v4 (jsdom 30); nodemailer
      v10.
    
    - Education markdown drops `<style>` and form controls.