Skip to content

v0.4.10 — Multiple superadmins, OIDC floor-guard, emergency CLI

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Jul 18:24
7edca72

[0.4.10] - 2026-07-02

Changed

  • Remove instance-superadmin ceiling: multiple active superadmin@instance assignments are allowed; OIDC group→superadmin grants are no longer capped at one. The dropped index was redundant with the Serializable user.count() guard in POST /setup; first-run bootstrap protection is unchanged.
  • Consolidate rate-limit factories into declarative policy registry (no behavior change)
  • Centralize MFA enroll rate-limit constants in RATE_POLICIES; add registry edge-case and wiring tests
  • Extract inline-only rate limits to INLINE_RATE_LIMITS (excluded from RatePolicyName; compile-time guard against rateLimit() misuse)
  • Remove unused SSE message variant and stale nginx metrics location; fix dangling ADR links in deploy docs
  • Docs: superadmin runbook for multiple instance admins and OIDC offboarding prerequisites (SECURITY-CONTROLS.md, deploy/README.md)

Security

  • Fix event-settings GET authz-order oracle (404→403 for cross-org probing of non-existent events); add defense-in-depth assertEventManageAccess to handlePatchEvent handler body (route wrapper already enforced scope); reduce QR image cache TTL from 24h to 5min
  • Emergency CLI attendee export: enforce mode 0600 on overwrite; writable emergency-exports bind mount; reject --out under public UPLOAD_DIR or outside EMERGENCY_EXPORT_DIR when those env vars are set; reject EMERGENCY_EXPORT_DIR when it is a public alias under UPLOAD_DIR raw or realpath (including symlinked upload roots); require raw --out under raw EMERGENCY_EXPORT_DIR (not only canonical realpath); resolve symlinks before path checks; write via validated canonical path with O_NOFOLLOW (loop until full buffer is written)

Fixed

  • POST /setup maps Serializable transaction conflicts (P2034) to 409 already_initialized when two first-run submissions race with different emails
  • bootstrap-superadmin --force recovery path works after removing the single-superadmin partial unique index
  • OIDC group-sync cannot revoke the last active instance superadmin (floor-guard with audit event auth.oidc.superadmin_revoke_blocked; Serializable transaction on active instance-superadmin revoke; inactive owners skip the floor check; retries P2034 serialization losers so concurrent OIDC logins do not fail)

Added

  • CLI: admitto emergency ops binary (apps/cli) — checkin admit/lookup, attendees export, mail retry-failed, auth bootstrap-superadmin/reset-mfa, sessions revoke/purge, retention run
  • Automated retention cron (auth sessions, mail delivery snapshots) and nightly pg_dump backup sidecar in deploy compose

Deploy

  • Container image: ghcr.io/solarssk/admitto:0.4.10 (rolling :0.4)
  • Migrations apply automatically on container start (with pre-migration backup when pending). No manual migrate deploy.

Full changelog