• v0.5.0 8fa29c8c6b

    v0.5.0
    All checks were successful
    Build Web image / Build and push Web image (push) Successful in 33s
    Build API image / Build and push API image (push) Successful in 30m1s
    Stable

    nrupard released this 2026-06-30 16:20:01 +02:00 | 561 commits to main since this release

    Changelog

    99087e7 Merge pull request 'Release v0.5.0' (#298) from release/v0.5.0 into main
    d96d288 Release v0.5.0
    70dde96 Merge pull request 'fix(e2e): send Origin on /settings/profile POST so BUNYIP-259 CSRF middleware accepts it' (#296) from fix/BUNYIP-286-e2e-profile-csrf-origin into main
    4ff6c73 Merge pull request 'feat(web): per-field show/hide password toggle on signup form' (#294) from feat/BUNYIP-282-signup-password-toggle into main
    57b99a9 Merge pull request 'fix(web): re-evaluate signup submit gate when async breach check resolves' (#295) from fix/BUNYIP-283-signup-submit-gate-breach-async into main
    5f080a9 refactor(e2e): extract bunyip-web POST Origin header into lib/csrf helper
    017e359 Merge remote-tracking branch 'origin/main' into fix/BUNYIP-283-signup-submit-gate-breach-async
    ed2fee7 Merge remote-tracking branch 'origin/main' into feat/BUNYIP-282-signup-password-toggle
    e5a68f8 Merge pull request 'fix(e2e): send Origin on profile POST so CSRF middleware admits it' (#297) from fix/BUNYIP-284-e2e-profile-csrf-origin into main
    6d6ed38 fix(e2e): send Origin on profile POST so CSRF middleware admits it
    0f76514 fix(web): re-evaluate signup submit gate when async breach check resolves
    fbc3c93 feat(web): per-field show/hide password toggle on signup form
    167a2f4 Merge pull request 'fix(oidc): persist original auth_time on refresh family; re-intersect scope at rotation' (#287) from fix/BUNYIP-262-refresh-auth-time-scope into main
    4fa6bbd Merge remote-tracking branch 'origin/main' into fix/BUNYIP-262-refresh-auth-time-scope
    2404e98 Merge pull request 'fix(e2e): harden magic-link mail wait with timeout headroom and one re-request' (#293) from fix/BUNYIP-279-e2e-magic-link-mail-wait-headroom into main
    91d9a83 Merge remote-tracking branch 'origin/main' into fix/BUNYIP-262-refresh-auth-time-scope
    0858a3f Merge pull request 'fix(oidc): enforce allowed_grant_types + token_endpoint_auth_method at /oauth2/token' (#290) from fix/BUNYIP-254-token-endpoint-enforcement into main
    2186519 Merge pull request 'fix(web): Origin / Referer CSRF defense on every state-changing POST' (#291) from fix/BUNYIP-259-csrf-synchronizer-token into main
    ef27991 Merge pull request 'fix(oidc): thread real acr/amr through op_session creation + refresh family' (#288) from fix/BUNYIP-257-acr-amr-threading into main
    29fc8eb Merge pull request 'fix(oidc): allowlist RP origins on CSP so Authorize completes (BUNYIP-244)' (#276) from feat/BUNYIP-244-csp-allowlist-origins into main
    85f9595 fix(e2e): harden magic-link mail wait with timeout headroom and one re-request
    50978e6 Merge remote-tracking branch 'origin/main' into fix/BUNYIP-257-acr-amr-threading
    889733b Merge pull request 'fix(oidc): server-side intersect consent scopes; refuse to revive revoked entitlement rows' (#292) from fix/BUNYIP-261-consent-scope-smuggling into main
    f660cbb Merge pull request 'fix(auth): login hardening cluster (pre-login op_session revoke, multi-keyed rate limit, 2FA cookie hygiene)' (#289) from fix/BUNYIP-255-login-hardening into main
    1c6b8a6 Merge pull request 'feat(auth): server-side HIBP backstop on register, password reset, and password change' (#282) from fix/BUNYIP-253-server-hibp-backstop into main
    25b8254 Merge pull request 'fix(e2e): retry password-reset confirm past the per-IP rate limit' (#286) from fix/BUNYIP-278-e2e-reset-confirm-rate-limit-retry into main
    6cff735 Merge pull request 'fix(oidc): per-IP rate limit on /oauth2/{authorize,token,userinfo,revoke}' (#281) from fix/BUNYIP-264-oauth-rate-limiters into main
    7d26329 Merge pull request 'fix(log): scrub PII + secret-adjacent data from auth + stripe log lines' (#280) from fix/BUNYIP-265-log-hygiene into main
    355fab7 Merge pull request 'fix(deploy): require OIDC signing-key vars; refuse to boot under a dev-* kid in prod' (#275) from fix/BUNYIP-258-drop-dev-signing-key-defaults into main
    38a2295 Merge pull request 'feat(web): app-wide service-unavailable banner when bunyip-api is down (BUNYIP-243)' (#278) from feat/BUNYIP-243-server-down-banner into main
    1e77944 fix(e2e): retry password-reset confirm past the per-IP rate limit
    71831f9 fix(oidc): server-side intersect consent scopes; refuse to revive revoked entitlement rows
    25fe79c fix(web): Origin / Referer CSRF defense on every state-changing POST
    5efe927 fix(oidc): enforce allowed_grant_types + token_endpoint_auth_method at /oauth2/token
    5533b0e Merge pull request 'fix(e2e): give hub-login setup backoff headroom for 2FA rate limit' (#285) from fix/BUNYIP-276-e2e-setup-2fa-backoff-headroom into main
    b098dc7 fix(auth): login hardening cluster (pre-login op_session revoke, multi-keyed rate limit, 2FA cookie hygiene)
    2ad1d46 Merge branch 'main' into feat/BUNYIP-243-server-down-banner
    02907ba fix(oidc): thread real acr/amr through op_session creation + refresh family
    d55b601 fix(oidc): persist original auth_time on refresh family; re-intersect scope at rotation
    2fca2ed Merge branch 'main' into feat/BUNYIP-244-csp-allowlist-origins
    e46bfe9 Merge pull request 'fix(auth): invalidate prior pending reset tokens when a new reset is requested' (#284) from fix/BUNYIP-256-cap-pending-reset-tokens into main
    a784777 Merge branch 'main' into feat/BUNYIP-244-csp-allowlist-origins
    6f29641 Merge pull request 'fix(auth): host-scope the OP session cookie by default; opt-in for cross-subdomain sharing' (#283) from fix/BUNYIP-266-host-only-op-session-cookie into main
    cc9eb1e fix(e2e): give hub-login setup backoff headroom for 2FA rate limit
    f15ff02 Merge pull request 'fix(oidc): scope /oauth2/logout post_logout_redirect_uri to the id_token_hint's client' (#279) from fix/BUNYIP-260-logout-id-token-hint-compliance into main
    6fd9951 Merge branch 'main' into feat/BUNYIP-244-csp-allowlist-origins
    f2f51c2 Merge branch 'main' into feat/BUNYIP-243-server-down-banner
    63705b8 Merge pull request 'fix(oidc): constant-time PKCE code_challenge compare; validate nbf on at+jwt verifier' (#274) from fix/BUNYIP-263-pkce-constant-time-nbf into main
    be2a911 ci: re-trigger checks (E2E staging flake, not a code change)
    6c69b06 chore(deps): bump dunite to pick up CspConfig (BUNYIP-244)
    b774b14 Merge branch 'main' into feat/BUNYIP-244-csp-allowlist-origins
    e294507 feat(web): app-wide service-unavailable banner when bunyip-api is down
    97a7f2f feat(auth): server-side HIBP backstop on register, password reset, and password change
    791c6b4 fix(oidc): per-IP rate limit on /oauth2/{authorize,token,userinfo,revoke}
    5ff93fb Merge pull request 'fix(e2e): tolerate login rate limit and harden mail wait' (#277) from fix/BUNYIP-267-e2e-login-backoff-mail-hardening into main
    171fa03 fix(log): scrub PII + secret-adjacent data from auth + stripe log lines
    3f44c35 fix(oidc): scope /oauth2/logout post_logout_redirect_uri to the id_token_hint's client
    7c5f280 Merge pull request 'feat(oidc): pin at+jwt audience on the Resource-Server verifier path' (#273) from fix/BUNYIP-252-at-jwt-audience-binding into main
    071b8d8 fix(e2e): tolerate login rate limit and harden mail wait
    6aa8ff5 fix(auth): invalidate prior pending reset tokens when a new reset is requested
    04feaf0 fix(auth): host-scope the OP session cookie by default; opt-in for cross-subdomain sharing
    a808fd5 fix(oidc): allowlist RP origins on CSP so Authorize completes
    611df32 fix(deploy): require OIDC signing-key vars; refuse to boot under a dev-* kid in prod
    13ee3c1 fix(oidc): constant-time PKCE code_challenge compare; validate nbf on at+jwt verifier
    9203617 feat(oidc): pin at+jwt audience on the Resource-Server verifier path
    d82cf99 Merge pull request 'feat(auth): clarify breach-row label and polish the password strip' (#272) from feat/BUNYIP-240-inline-password-feedback into main
    1652907 feat(auth): clarify breach-row label and polish the password strip
    bfa7512 Merge pull request 'fix(web): allow the OIDC login redirect chain in form-action CSP' (#271) from fix/bunyip-csp-form-action-oidc into main
    4eb5d8a fix(web): allow the OIDC login redirect chain in form-action CSP
    bc15cb9 Merge pull request 'fix(e2e): harden hard_delete against non-cascade user FKs (BUNYIP-248)' (#270) from fix/bunyip-248-fk-hardening into main
    e5a36c4 fix(e2e): harden hard_delete against non-cascade user FKs (BUNYIP-248)
    c133f44 Merge pull request 'docs(e2e): Forgejo Actions secrets + variables reference (BUNYIP-247)' (#269) from docs/bunyip-247-forgejo-secrets-readme into main
    92ec6a1 Merge branch 'main' into docs/bunyip-247-forgejo-secrets-readme
    0432bc4 Merge pull request 'fix(e2e): hard-delete disposable accounts after each test (BUNYIP-246)' (#268) from fix/bunyip-246-e2e-account-hard-delete into main
    4de5c4b docs(e2e): authoritative Forgejo Actions secrets + variables reference
    e15bc19 docs: note hard_delete non-cascade FK limitation (review follow-up)
    9c7a38c fix(e2e): hard-delete disposable accounts after each test + reaper
    902db91 Merge pull request 'fix(ci): disable provenance attestation in docker check to avoid manifest-tag collision' (#267) from fix/BUNYIP-241-disable-provenance-in-docker-check into main
    f1cf1a8 Merge pull request 'fix(deploy): require BUNYIP_API_IMAGE + BUNYIP_WEB_IMAGE, drop :latest fallback (BUNYIP-237)' (#266) from fix/BUNYIP-237-compose-fail-loud-on-missing-image into main
    4cf36a4 Merge pull request 'feat(auth): live per-rule password feedback + breach check on /register + /reset-password (BUNYIP-240)' (#265) from feat/BUNYIP-240-inline-password-feedback into main
    3c4074e Merge pull request 'fix(ci): close shell-injection vector via head.ref in create-release.yml (BUNYIP-236)' (#263) from fix/BUNYIP-236-create-release-injection into main
    d3882ce fix(ci): disable provenance attestation in docker check to avoid manifest-tag collision
    0e7ba70 merge: resolve security.rs conflict with BUNYIP-235 (form-action for Stripe)
    281d85b fix(ci): disable provenance attestation in docker check to avoid manifest-tag collision
    f2bc132 feat(auth): live per-rule password feedback + breach check on /register + /reset-password (BUNYIP-240)
    872a7dc Merge pull request 'fix(csp): allow Stripe-hosted destinations in bunyip-web form-action (BUNYIP-235)' (#264) from fix/BUNYIP-235-bunyip-web-csp-stripe-form-action into main
    0ca52f4 fix(deploy): require BUNYIP_API_IMAGE + BUNYIP_WEB_IMAGE, drop :latest fallback (BUNYIP-237)
    a26fc8c fix(csp): allow Stripe-hosted destinations in bunyip-web form-action (BUNYIP-235)
    11332b8 fix(ci): close shell-injection vector via head.ref in create-release.yml (BUNYIP-236)
    fa0102a Merge pull request 'chore(oidc): trace consent grant/gate decisions to diagnose the first-time consent loop (BUNYIP-234)' (#262) from fix/BUNYIP-234-consent-loop-diagnostics into main
    2a7f693 chore(oidc): trace consent grant/gate decisions to diagnose the first-time consent loop (BUNYIP-234)
    f11d774 Merge pull request 'fix(launcher): close the cross-browser stale-JWT gap on the app launcher (BUNYIP-229)' (#256) from fix/BUNYIP-229-stale-jwt-cross-browser into main
    f4b43c4 Merge pull request 'docs(billing): mark the two open items resolved (decision-complete)' (#261) from docs/billing-m1-plan into main
    b052cb2 Merge branch 'main' into docs/billing-m1-plan
    08cc91c Merge pull request 'Derive OCI publish mode from trigger for bunyip-api and bunyip-web' (#258) from fix/GOV-15-twin-trigger-publish-mode into main
    fcde93d Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
    9a432ad Merge pull request 'fix(web): add Content-Security-Policy header to bunyip-web responses (BUNYIP-232)' (#260) from fix/bunyip-232-web-csp-header into main
    c03fff7 Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
    d23d469 fix(web): add Content-Security-Policy header to bunyip-web responses (BUNYIP-232)
    72c871b Merge pull request 'fix(oidc): atomic code redemption, cap refresh TTL, drop dead client fields (BUNYIP-73)' (#252) from fix/bunyip-73-oidc-provider-hardening into main
    601d411 Merge remote-tracking branch 'origin/main' into fix/bunyip-73-oidc-provider-hardening
    4d70d70 Merge pull request 'chore(ci): clear stale builder image before docker check (BUNYIP-231)' (#259) from chore/checks-workflow-9c0ac500 into main
    a6a6cf9 Merge pull request 'Use the new illustrated Bunyip mascot on the landing hero' (#245) from feat/BUNYIP-216-landing-mascot into main
    a271506 Merge branch 'main' into feat/BUNYIP-216-landing-mascot
    9fec28f Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
    7acffe6 Merge pull request 'ci(check): build check-docker to cacheonly instead of exporting a tagged image' (#257) from chore/BUNYIP-227-check-docker-cacheonly into main
    030e470 Merge branch 'main' into chore/BUNYIP-227-check-docker-cacheonly
    d141276 chore(ci): clear stale builder image before docker check (BUNYIP-231)
    b5bc5ad fix(ci): derive OCI publish mode from trigger, not git describe
    ec7e1a4 Merge branch 'main' into feat/BUNYIP-216-landing-mascot
    9c0ac50 Merge pull request 'fix(2fa): widen recovery code entropy to 80 bits (BUNYIP-202)' (#244) from fix/bunyip-202-recovery-code-entropy into main
    8e001ea Merge branch 'main' into fix/bunyip-202-recovery-code-entropy
    6aff69a Merge pull request 'fix(oidc): parse loopback redirect_uri host instead of string-prefix (BUNYIP-106)' (#242) from fix/bunyip-106-loopback-redirect-uri-parse into main
    023150c ci(check): build check-docker to cacheonly, drop tagged image export
    383b6ae fix(launcher): close the cross-browser stale-JWT gap on the app launcher (BUNYIP-229)
    2c06512 Merge branch 'main' into fix/bunyip-106-loopback-redirect-uri-parse
    4518568 Merge pull request 'fix(oidc): make authorization code redemption atomic (BUNYIP-199)' (#238) from fix/bunyip-199-atomic-code-redemption into main
    bb01200 Merge branch 'main' into fix/bunyip-199-atomic-code-redemption
    2947d0e Merge pull request 'fix(web): rotate JWT after tier-grant so the launcher unlocks without log-out (BUNYIP-226)' (#255) from fix/BUNYIP-226-rotate-jwt-after-tier-grant into main
    c3975f1 Merge pull request 'refactor(oci): de-duplicate registry admin check, sha256 fallback, dead re-exports (BUNYIP-81)' (#234) from chore/bunyip-81-oci-registry-dedup into main
    442c67e Merge branch 'main' into chore/bunyip-81-oci-registry-dedup
    f4b71d5 fix(web): rotate JWT after tier-grant so the launcher unlocks without log-out (BUNYIP-226)
    7d74272 Merge pull request 'fix(billing): handle sibling Stripe subs on cancel + gate Welcome page on real status (BUNYIP-225)' (#254) from fix/BUNYIP-225-hardening-resub-cancel-race into main
    32651ac Merge pull request 'ci(oci): switch OCI build cache to type=gha + per-image scope (GOV-20, GOV-21)' (#240) from ci/GOV-20-bunyip-gha-build-cache into main
    b1bb4c9 Merge branch 'main' into ci/GOV-20-bunyip-gha-build-cache
    a9a6dd0 fix(billing): handle sibling Stripe subs on cancel + gate Welcome page on real status (BUNYIP-225)
    b645a85 Merge pull request 'fix(consent): render the OIDC consent page through the public auth shell (BUNYIP-223)' (#253) from fix/BUNYIP-223-consent-page-styled-shell into main
    34184d7 fix(consent): render the OIDC consent page through the public auth shell (BUNYIP-223)
    dea159b Merge pull request 'feat(auth): grant initial trial only after BOTH email verified AND name saved (BUNYIP-221)' (#250) from feat/BUNYIP-221-trial-after-onboarding into main
    a7ebf03 fix(oidc): atomic code redemption, cap refresh TTL, drop dead client fields (BUNYIP-73)
    442f4cd Merge pull request 'feat(billing): force card-only Stripe Checkout, disable Pay with Link (BUNYIP-208)' (#251) from feat/bunyip-208-checkout-card-only into main
    834130c feat(billing): force card-only Stripe Checkout, disable Pay with Link (BUNYIP-208)
    746f5f3 Merge pull request 'test(stripe): regression-guard webhook idempotency fence ordering (BUNYIP-210)' (#249) from test/bunyip-210-webhook-fence-regression into main
    f3136ba feat(auth): grant initial trial only after BOTH email verified AND name saved (BUNYIP-221)
    69f1127 test(stripe): regression-guard webhook idempotency fence ordering (BUNYIP-210)
    b74693e Merge pull request 'feat(billing): grant 30-day signup free trial via Stripe Checkout (BUNYIP-209)' (#248) from feat/bunyip-209-signup-trial-period into main
    02243ce feat(billing): grant 30-day signup free trial via Stripe Checkout (BUNYIP-209)
    a4b32a9 Merge pull request 'fix(email): suppress login/reset tokens in disabled-email logs (BUNYIP-204)' (#247) from fix/bunyip-204-suppress-token-logging into main
    6f2483b fix(email): suppress login/reset tokens in disabled-email logs (BUNYIP-204)
    900a57b Merge pull request 'fix(stripe): fail closed when webhook secret is unset (BUNYIP-203)' (#246) from fix/bunyip-203-stripe-webhook-fail-closed into main
    be6e61a fix(stripe): fail closed when webhook secret is unset (BUNYIP-203)
    5e5f125 feat(landing): use the new illustrated mascot on the landing hero
    9a82d78 fix(2fa): widen recovery code entropy to 80 bits (BUNYIP-202)
    1435c0e Merge pull request 'fix(2fa): per-account verify lockout and tighter TOTP skew (BUNYIP-201)' (#243) from fix/bunyip-201-2fa-per-account-lockout into main
    14c46f0 fix(2fa): per-account verify lockout and tighter TOTP skew (BUNYIP-201)
    8267266 fix(oidc): parse loopback redirect_uri host instead of string-prefix (BUNYIP-106)
    51cf951 Merge pull request 'fix(oidc): re-validate tenant assignment on refresh rotation (BUNYIP-200)' (#241) from fix/bunyip-200-revalidate-tenant-on-refresh-rotation into main
    736cd77 fix(oidc): re-validate tenant assignment on refresh rotation (BUNYIP-200)
    d11e981 Merge pull request 'fix(domain): count unverified holders in tier slot usage (BUNYIP-105)' (#239) from fix/bunyip-105-count-unverified-tier-slots into main
    4145c35 ci(oci): switch build cache to gha with per-image scope
    87deecd fix(domain): count unverified holders in tier slot usage (BUNYIP-105)
    e4a9e3e fix(oidc): make authorization code redemption atomic (BUNYIP-199)
    e8fe39d Merge pull request 'fix(stripe): lock the real checkout price from the Stripe API (BUNYIP-215)' (#237) from fix/bunyip-215-pricelock-line-items into main
    8928490 Merge pull request 'fix(config): decouple dotenv load from parsing so defaults test is deterministic (BUNYIP-102)' (#236) from fix/bunyip-102-config-dotenv-decouple into main
    541c9ad fix(stripe): lock the real checkout price from the Stripe API (BUNYIP-215)
    57b41c9 fix(config): decouple dotenv load from parsing so defaults test is deterministic (BUNYIP-102)
    25c7d9e Merge pull request 'fix(web): add missing user-cog icon for Profile card (BUNYIP-171)' (#235) from fix/bunyip-171-profile-icon into main
    c168d46 fix(web): add missing user-cog icon for Profile card (BUNYIP-171)
    0176e55 refactor(oci): de-duplicate registry admin check, sha256 fallback, dead re-exports (BUNYIP-81)
    cf57fdb Merge pull request 'fix(stripe): finalize webhook idempotency after handler runs (BUNYIP-210)' (#233) from fix/bunyip-210-webhook-idempotency-ordering into main
    f25684e Merge pull request 'chore(infra): harden prod images, compose, CI, and dep hygiene (BUNYIP-80)' (#232) from chore/bunyip-80-harden-images-compose-ci into main
    711fc54 fix(stripe): finalize webhook idempotency after handler runs (BUNYIP-210)
    649bf9b chore(infra): harden prod images, compose, CI, and dep hygiene (BUNYIP-80)
    1bfb826 Merge pull request 'feat(account): cascade account delete to connected apps (BUNYIP-211)' (#231) from feat/bunyip-211-cascade-account-delete into main
    2589b1d feat(account): cascade account delete to connected apps (BUNYIP-211)
    e46b820 Merge pull request 'fix(oidc): close open redirect, scope leak, client auth, dead code (BUNYIP-74)' (#230) from fix/bunyip-74-oidc-handlers into main
    fba7df7 fix(oidc): close open redirect, scope leak, client auth, dead code (BUNYIP-74)
    8b14a24 Merge pull request 'fix(web): collect TOTP code in disable-2FA form (BUNYIP-212)' (#229) from fix/bunyip-212-disable-2fa-totp-code into main
    42d2621 fix(web): collect TOTP code in disable-2FA form (BUNYIP-212)
    81274e2 Merge pull request 'feat(web): forced post-registration onboarding (BUNYIP-206)' (#228) from feat/bunyip-206-onboarding-page into main
    5fa2780 Merge pull request 'test(e2e): un-fixme subscribe + billing-portal behind a staging-Stripe gate (BUNYIP-151)' (#227) from feat/bunyip-151-billing-specs-stripe-gate into main
    ebb001d feat(web): forced post-registration onboarding (name + email verification)
    83dece6 test(e2e): un-fixme subscribe + billing-portal behind a staging-Stripe gate (BUNYIP-151)
    8f3e3d7 Merge pull request 'fix(e2e): verify the disposable account before change-email (BUNYIP-150)' (#226) from fix/bunyip-150-change-email-verify-first into main
    c171761 fix(e2e): verify the disposable account before change-email (BUNYIP-150)
    c1100c5 Merge pull request 'fix(e2e): exempt non-prod registration cap + force JMAP public origin (BUNYIP-150)' (#225) from fix/bunyip-150-register-nonprod-jmap-origin into main
    5cb62c8 fix(e2e): exempt non-prod registration cap + force JMAP public origin (BUNYIP-150)
    e214f40 Merge pull request 'test(e2e): mail-sink helper + un-fixme reset/magic-link/change-email (BUNYIP-150)' (#220) from feat/bunyip-150-e2e-mail-sink into main
    4085b4c test(e2e): use nate@a8n.run sink mailbox + guard destroy to exact subaddress (BUNYIP-150)
    f1e26de test(e2e): read the mail sink via Stalwart JMAP instead of Mailpit (BUNYIP-150)
    e95ce8d test(e2e): mail-sink helper + un-fixme reset/magic-link/change-email (BUNYIP-150)
    ada9875 docs(billing): mark the two open items resolved (decision-complete)

    Downloads