• v0.14.1 ff5e197123

    v0.14.1
    All checks were successful
    Build Web image / Build and push Web image (push) Successful in 1m0s
    E2E / deployment (push) Successful in 1m2s
    Check / fmt + clippy + build + tests (push) Successful in 5m4s
    Build API image / Build and push API image (push) Successful in 10m50s
    Stable

    nrupard released this 2026-08-13 19:36:23 +02:00 | 0 commits to main since this release

    Changelog

    ff5e197 Merge pull request 'Release v0.14.1' (#534) from release/v0.14.1 into main
    a996175 Release v0.14.1
    e5f28be Merge pull request 'fix(build): give every cargo cache mount a per-image id and sharing=locked' (#533) from fix/BUNYIP-534-cache-mount-sharing into main
    4062a17 fix(build): give every cargo cache mount a per-image id and sharing=locked

    Downloads
  • v0.14.0 fa8d22ebf6

    v0.14.0
    All checks were successful
    E2E / deployment (push) Successful in 1m3s
    Build Web image / Build and push Web image (push) Successful in 3m7s
    Check / fmt + clippy + build + tests (push) Successful in 3m24s
    Build API image / Build and push API image (push) Successful in 14m47s
    Stable

    nrupard released this 2026-08-13 15:24:23 +02:00 | 4 commits to main since this release

    Changelog

    fa8d22e Merge pull request 'Release v0.14.0' (#532) from release/v0.14.0 into main
    d2d5a42 Release v0.14.0
    2522b70 Merge pull request 'fix(apps): resolve the Let's Chat link to chat.{domain}, not the slug (BUNYIP-533)' (#531) from fix/BUNYIP-533-lets-chat-subdomain into main
    43e043b fix(apps): resolve the Let's Chat link to chat.{domain}, not the slug (BUNYIP-533)
    86e631c Merge pull request 'feat(admin): proactive Stripe key permission self-test on /admin/stripe (BUNYIP-532)' (#530) from feat/BUNYIP-532-stripe-permission-self-test into main
    781b003 feat(admin): proactive Stripe key permission self-test on /admin/stripe (BUNYIP-532)
    36338fb Merge pull request 'chore(secrets): retire sync-secrets.nu; Group-1 not from Infisical (BUNYIP-531)' (#529) from chore/BUNYIP-531-retire-sync-secrets into main
    1dc0182 chore(secrets): retire sync-secrets.nu; Group-1 secrets are not from Infisical
    ce2cb5a Merge pull request 'docs(secrets): Infisical folder paths are project-relative (BUNYIP-530)' (#528) from docs/BUNYIP-529-secret-path-runtime into main
    cdf8f01 docs(secrets): Infisical folder paths are project-relative (/runtime, not /bunyip/runtime)
    fc0c0a0 Merge pull request 'feat(secrets): make SMTP_PASSWORD Group-2-only (BUNYIP-529)' (#527) from feat/BUNYIP-529-smtp-group2-only into main
    5f1d9cf docs(compose): note the Group-2 runtime fetch in the secrets header
    9a7e77a feat(secrets): make SMTP_PASSWORD Group-2-only (Infisical, not a file secret)
    1fae7fe Merge pull request 'docs(secrets): document the Group-2 Infisical runtime fetch (BUNYIP-528)' (#524) from docs/BUNYIP-528-group2-infisical-docs into main
    86928a0 Merge pull request 'docs(admin): explain why a Stripe price is replaced, not edited (BUNYIP-511)' (#526) from docs/BUNYIP-511-explain-price-immutability into main
    61cd03a docs(admin): explain why a Stripe price is replaced, not edited (BUNYIP-511)
    8c1521b Merge pull request 'feat(admin): tier/pricing config cohesion - mapping home, checkout-trial, (none) clearing, per-tier visibility (BUNYIP-527)' (#525) from feat/BUNYIP-527-tier-config-cohesion into main
    11ea8fe feat(admin): tier/pricing config cohesion - mapping home, checkout-trial relocation, (none) clearing, per-tier visibility (BUNYIP-527)
    7bf1c32 docs(secrets): document the Group-2 Infisical runtime fetch, sweep stale secret docs
    0f7d8fd Merge pull request 'fix(pricing): show each tier's own trial and reflect slot availability on /pricing (BUNYIP-526)' (#522) from feat/BUNYIP-526-per-tier-trial-and-availability into main
    8c8b233 Merge pull request 'feat(secrets): fetch Group-2 SMTP secret from Infisical at runtime (app-native, BUNYIP-525)' (#523) from feat/BUNYIP-525-infisical-runtime-fetch into main
    b17e068 Merge pull request 'feat(admin): edit Stripe products and replace prices from /admin/stripe (BUNYIP-511)' (#521) from feat/BUNYIP-511-edit-products-replace-prices into main
    7b1b1ae feat(secrets): fetch Group-2 SMTP secret from Infisical at runtime (app-native)
    8a5d4f9 fix(pricing): show each tier's own trial and reflect slot availability on /pricing (BUNYIP-526)
    ede6502 feat(admin): edit Stripe products and replace prices from /admin/stripe (BUNYIP-511)
    798e975 Merge pull request 'feat(admin): move the /pricing publish switch into the Stripe tier catalog mapping (BUNYIP-524)' (#520) from feat/BUNYIP-524-pricing-switch-in-catalog-mapping into main
    8f52b09 feat(admin): move the public /pricing publish switch into the Stripe tier catalog mapping (BUNYIP-524)
    8d5e4da Merge pull request 'fix(pricing): exempt /v1/pricing from the rate-limit floor and cache it in the BFF (BUNYIP-518)' (#517) from fix/BUNYIP-518-pricing-ratelimit-floor-exempt into main
    026ad66 fix(pricing): exempt /v1/pricing from the rate-limit floor and cache it in the BFF (BUNYIP-518)
    c099489 Merge pull request 'fix(stripe): name the missing permission, stop faking an empty list' (#514) from fix/BUNYIP-516-stripe-permission-errors-visible into main
    1c8faf5 fix(stripe): name the missing permission, stop faking an empty list
    443da76 Merge pull request 'feat(admin): derive a tier's Stripe product from its mapped price (BUNYIP-517)' (#516) from feat/BUNYIP-517-derive-tier-product-from-price into main
    42d1754 Merge pull request 'feat(admin): unarchive a Stripe product or price from the admin Stripe page (BUNYIP-513)' (#515) from feat/BUNYIP-513-unarchive-stripe-plan into main
    f9914db feat(admin): derive a tier's Stripe product from its mapped price (BUNYIP-517)
    013a459 Merge branch 'main' into feat/BUNYIP-513-unarchive-stripe-plan
    04b652b feat(admin): unarchive a Stripe product or price from the admin Stripe page (BUNYIP-513)
    0e737dd Merge pull request 'fix(admin): archive Stripe plans all-or-nothing with a member guard (BUNYIP-512)' (#513) from fix/BUNYIP-512-archive-cascade-and-member-guard into main
    fec98ca fix(admin): archive Stripe plans all-or-nothing with a member guard (BUNYIP-512)
    e1e6afb Merge pull request 'fix(pricing): publish every mapped tier and name every silent cause' (#512) from fix/BUNYIP-515-pricing-multi-tier-and-visible-reasons into main
    0a30bcf fix(pricing): publish every mapped tier and name every silent cause
    9a38eee Merge pull request 'fix(web): restore always-visible, grabbable scrollbars' (#511) from fix/BUNYIP-509-visible-scrollbars into main
    e0c7989 fix(web): restore always-visible, grabbable scrollbars
    7e9b705 Merge pull request 'fix(admin): show the real Stripe webhook URL and fix the copy' (#510) from fix/BUNYIP-510-stripe-webhook-url-copy into main
    b0a6a25 fix(admin): show the real Stripe webhook URL and fix the copy
    50aeea9 Merge pull request 'feat(email): send a real test message from admin Email' (#509) from feat/BUNYIP-508-admin-test-email-send into main
    68d74af feat(email): send a real test message from admin Email
    b30888e Merge pull request 'fix(email): announce a configurable SMTP EHLO name' (#508) from fix/BUNYIP-507-configurable-smtp-ehlo-name into main
    e8ee656 fix(email): announce a configurable SMTP EHLO name
    ec89432 Merge pull request 'fix(web): make API response decoding skew-tolerant' (#507) from fix/BUNYIP-506-skew-tolerant-decoding into main
    5ecf063 fix(web): make API response decoding skew-tolerant

    Downloads
  • v0.13.0 f154d3f82b

    v0.13.0
    All checks were successful
    Build Web image / Build and push Web image (push) Successful in 2m26s
    E2E / deployment (push) Successful in 3m1s
    Build API image / Build and push API image (push) Successful in 11m27s
    Check / fmt + clippy + build + tests (push) Successful in 16m34s
    Stable

    nrupard released this 2026-08-10 14:58:53 +02:00 | 54 commits to main since this release

    Changelog

    f154d3f Merge pull request 'Release v0.13.0' (#506) from release/v0.13.0 into main
    79cf1a4 Release v0.13.0
    13fbf52 Merge pull request 'feat(secrets): sync the app secrets from Infisical' (#505) from feat/BUNYIP-504-sync-secrets-infisical into main
    f4eb570 feat(secrets): sync the app secrets from Infisical
    86c88d7 Merge pull request 'refactor(web): move the skin pages into a skin module (BUNYIP-501)' (#503) from feat/BUNYIP-501-skin-module into main
    00199db Merge pull request 'feat(web): make the CSP host allow-list a config input (BUNYIP-503)' (#504) from feat/BUNYIP-503-csp-config into feat/BUNYIP-501-skin-module
    489dff6 feat(web): make the CSP host allow-list a config input
    0d1d6a0 Merge branch 'main' into feat/BUNYIP-501-skin-module
    f876cda Merge pull request 'feat(web): read the meta description and footer brand from config (BUNYIP-501)' (#502) from feat/BUNYIP-501-debrand-chrome into main
    680e88e refactor(web): move the skin pages into a skin module
    ba3c0a0 Merge branch 'main' into feat/BUNYIP-501-debrand-chrome
    e81a92f Merge pull request 'feat(web): make brand colors skin-overridable (BUNYIP-500)' (#501) from feat/BUNYIP-500-theming into main
    0e3b6cc feat(web): read the meta description and footer brand from config
    b384a06 Merge main into feat/BUNYIP-500-theming
    51b11fe Merge pull request 'feat(web): render the app name from config (BUNYIP-499)' (#500) from feat/BUNYIP-499-branding-config into main
    fe2ec5e feat(web): make brand colors skin-overridable
    31b1d2c feat(web): render the app name from config
    b722711 Merge pull request 'Rename the subscription vocabulary to membership' (#486) from refactor/BUNYIP-488-membership-vocabulary into main
    705a45d fix(migrations): move the membership rename off the colliding version
    0ef8ae6 Merge main into refactor/BUNYIP-488-membership-vocabulary
    2f21e78 refactor: rename the subscription vocabulary to membership

    Downloads
  • v0.12.0 92b1134ca4

    v0.12.0
    All checks were successful
    E2E / deployment (push) Successful in 1m24s
    Build Web image / Build and push Web image (push) Successful in 3m41s
    Check / fmt + clippy + build + tests (push) Successful in 15m49s
    Build API image / Build and push API image (push) Successful in 23m18s
    Stable

    nrupard released this 2026-08-07 19:06:38 +02:00 | 75 commits to main since this release

    Changelog

    92b1134 Merge pull request 'Release v0.12.0' (#499) from release/v0.12.0 into main
    0db0fe3 Release v0.12.0
    e87ef5d Merge pull request 'ci: run every workflow step under Nushell' (#491) from chore/BUNYIP-489-nushell-workflow-shell into main
    d645134 Merge branch 'main' into chore/BUNYIP-489-nushell-workflow-shell
    5ced1bd Merge pull request 'fix(e2e): report a 2FA-verify 5xx accurately, not as a rejected code' (#498) from fix/BUNYIP-496-e2e-2fa-5xx-diagnostic into main
    fbd1f00 fix(e2e): report a 2FA-verify 5xx accurately, not as a rejected code
    54ad30b Merge pull request 'refactor(events): consume dunite-events, drop bunyip bus + SSE copies' (#497) from feat/DEV-528-consume-events into main
    57df47c refactor(events): consume dunite-events, drop bunyip bus + SSE copies
    4c33799 Merge pull request 'refactor(version): consume dunite-update-check, drop bunyip copy' (#496) from feat/DEV-530-consume-update-check into main
    a2b18e4 refactor(version): consume dunite-update-check, drop bunyip copy
    2cc3145 Merge pull request 'refactor(observability): consume dunite-core error-log + client-IP' (#495) from feat/DEV-529-consume-observability into main
    4c022db refactor(observability): consume dunite-core error-log + client-IP
    6622c91 Merge pull request 'refactor(services): consume dunite-hibp + dunite-webhook, drop bunyip copies' (#494) from feat/DEV-527-consume-hibp-webhook into main
    8024c7c refactor(services): consume dunite-hibp + dunite-webhook, drop bunyip copies
    03fd39e Merge pull request 'refactor(csrf): consume dunite-core OriginGuard, drop bunyip-api copy' (#493) from feat/DEV-526-consume-dunite-csrf into main
    b746094 refactor(csrf): consume dunite-core OriginGuard, drop bunyip-api copy
    28b6ff6 Merge pull request 'ci(e2e): drop the doubled E2E prefix from the published check names' (#481) from fix/BUNYIP-478-e2e-check-name-dedup into main
    7df4eaa Merge pull request 'fix(web): log transport/decode detail suppressed from the user' (#480) from fix/BUNYIP-477-log-suppressed-detail into main
    b4e6be0 Merge pull request 'chore(scripts): rewrite the CI guards and operator scripts in Nushell' (#492) from chore/BUNYIP-490-nushell-ci-guards into main
    e41d6e3 chore(scripts): rewrite the CI guards and operator scripts in Nushell
    3508642 Merge branch 'main' into fix/BUNYIP-477-log-suppressed-detail
    5230768 Merge pull request 'feat(config): consolidate the at-rest keys into APP_ENCRYPTION_KEY' (#483) from chore/BUNYIP-483-single-app-encryption-key into main
    827fefb fix(ci): unblock the Stripe-env gate and point the transitional key layer at its removal
    46f5d6d ci: run every workflow step under Nushell
    651732e Merge branch 'main' into chore/BUNYIP-483-single-app-encryption-key
    19accaf Merge pull request 'fix(web): space the admin stat cards on the page rhythm' (#490) from fix/BUNYIP-367-card-spacing into main
    e533ad7 fix(web): space the admin stat cards on the page rhythm
    22b5ec8 Merge pull request 'fix(web): scroll the sidebar independently of the page' (#489) from fix/BUNYIP-368-sidebar-independent-scroll into main
    f9e0d34 fix(web): scroll the sidebar independently of the page
    65c9a8c Merge pull request 'feat(web): mount the feedback launcher in the admin panel' (#488) from feat/BUNYIP-370-feedback-everywhere into main
    c01c074 feat(web): mount the feedback launcher in the admin panel
    4ec789c Merge pull request 'feat(pricing): drive /pricing from the admin Pricing tiers page' (#487) from feat/BUNYIP-487-admin-driven-pricing into main
    44150e0 feat(pricing): drive /pricing from the admin Pricing tiers page
    54d5f82 Merge pull request 'test(web): cover every primary wash in the contrast guard' (#485) from fix/BUNYIP-485-primary-text-token into main
    c96bfcc test(web): cover every primary wash in the contrast guard
    96cd54f fix(web): split a primary-text token off the fill
    1935111 Merge pull request 'fix(web): focus the first field on every auth card' (#484) from fix/BUNYIP-486-auth-card-autofocus into main
    0366753 fix(web): focus the first field on every auth card
    8a010e7 feat(config): consolidate the at-rest keys into APP_ENCRYPTION_KEY
    b975786 Merge pull request 'feat(stripe): make the database the only source of Stripe config' (#482) from chore/BUNYIP-482-remove-stripe-env-vars into main
    0f24fe2 feat(stripe): make the database the only source of Stripe config
    d85ba61 ci(e2e): drop the doubled E2E prefix from the published check names
    72d990d Merge pull request 'fix(api): return the generic AppError envelope for extractor errors' (#479) from fix/BUNYIP-481-extractor-error-handlers into main
    03ae306 fix(web): log the transport/decode detail suppressed from the user
    43f869a Merge pull request 'ci(e2e): prefix E2E check names so branch protection can match them' (#477) from fix/BUNYIP-478-e2e-check-names into main
    28e5579 fix(api): return the generic AppError envelope for extractor errors
    4d31d51 Merge pull request 'fix(web): collapse backend/transport errors to a generic message' (#478) from fix/BUNYIP-477-simpler-error-messages into main
    190534f fix(web): collapse backend/transport errors to a generic message
    8502ba7 ci(e2e): prefix E2E check names so branch protection can match them
    71426e2 Merge pull request 'fix(e2e): match the destructive error box by class substring' (#476) from fix/BUNYIP-480-e2e-destructive-selector into main
    6039855 fix(e2e): match the destructive error box by class substring
    3c5aa9e Merge pull request 'fix(web): unify auth copy, admin separators, landing title' (#475) from fix/BUNYIP-471-copy-drift into main
    312a201 fix(web): unify auth copy, admin separators, landing title
    ab29a35 Merge pull request 'feat(web): add shared empty_state() and route every list through it' (#474) from fix/BUNYIP-468-empty-state into main
    fb83df3 feat(web): add shared empty_state() and route every list through it
    ba9d503 Merge pull request 'feat(web): a11y wiring - label association, machine-readable time, links' (#473) from fix/BUNYIP-466-a11y-wiring into main
    375bde4 feat(web): a11y wiring - label association, machine-readable time, links
    f829fe8 Merge pull request 'chore(infra): verify + surface two-hop trusted-proxy posture (BUNYIP-476)' (#472) from chore/BUNYIP-476-verify-trusted-proxy into main
    2596a65 chore(infra): verify + surface two-hop trusted-proxy posture (BUNYIP-476)
    598a72d Merge pull request 'feat(web): consolidate shared UI kit across admin/settings/auth' (#471) from fix/BUNYIP-467-shared-kit into main
    73fc2bb feat(web): consolidate shared UI kit across admin/settings/auth
    f1c2a90 Merge pull request 'feat(admin): IP2Proxy/IP2Location dataset refresh + freshness readout (BUNYIP-474)' (#470) from feat/BUNYIP-474-dataset-age-and-refresh into main
    401fcb6 feat(admin): IP2Proxy/IP2Location dataset refresh + freshness readout (BUNYIP-474)
    c2e13c8 Merge pull request 'fix(admin): drag-and-drop application reorder, fix broken swap (BUNYIP-473)' (#468) from fix/BUNYIP-473-app-reorder-dnd into main
    3c577f2 Merge pull request 'fix(web): token + contrast fixes (yellow, destructive reds, indigo dark, muted-foreground)' (#469) from fix/BUNYIP-465-token-contrast into main
    7b8736d fix(admin): drag-and-drop application reorder, fix broken swap (BUNYIP-473)
    d7471bb fix(web): token + contrast fixes (yellow indicator, destructive reds, indigo dark, muted-foreground)
    8f8e66a Merge pull request 'fix(web): spacing/responsive nits (rhythm, grid, overflow, sort cue, ellipsis)' (#467) from fix/BUNYIP-472-spacing-responsive-nits into main
    825f6e3 Merge pull request 'feat(admin): advisory ASN/VPN enrichment of client IPs (BUNYIP-437)' (#466) from feat/BUNYIP-437-ip-enrichment-consumer into main
    a512e55 Merge pull request 'fix(web): Title-case the browser titles to match their page h1s' (#465) from fix/BUNYIP-470-title-casing into main
    f5f0afb Merge pull request 'fix(web): align card-title and page-h1 sizes to the app scale' (#464) from fix/BUNYIP-469-typography-sizes into main
    65be63d fix(web): spacing/responsive/affordance nits (rhythm, grid, overflow, sort cue, ellipsis)
    26d912b feat(admin): advisory ASN/VPN enrichment of client IPs (BUNYIP-437)
    296976c fix(web): Title-case the browser titles to match their page h1s
    6338619 fix(web): align card-title and page-h1 sizes to the app scale
    6418071 Merge pull request 'fix(web): add --destructive-text token for legible dark-mode destructive text' (#463) from fix/BUNYIP-464-destructive-text-token into main
    f9f048f Merge pull request 'fix(web): surface admin API-fetch failures instead of empty/zero state' (#462) from fix/BUNYIP-461-admin-api-error-state into main
    165ca0a Merge pull request 'fix(web): give the warning badge a dark-mode amber pair' (#461) from fix/BUNYIP-463-warning-badge-dark into main
    fabfe2a Merge pull request 'fix(web): render footer brand host from runtime config' (#460) from fix/BUNYIP-462-footer-runtime-domain into main
    e9b39f9 fix(web): add a --destructive-text token for legible dark-mode destructive text
    b07e9fe fix(web): surface admin API-fetch failures instead of empty/zero state
    7c2357d Merge pull request 'fix(admin): realign application edit panel (BUNYIP-460)' (#459) from fix/BUNYIP-460-application-panel-alignment into main
    b9edfd2 fix(web): give the warning badge a dark-mode amber pair
    b8fac53 fix(web): render footer brand host from runtime config
    8add73a fix(admin): realign application edit panel (BUNYIP-460)
    fd2cb2a Merge pull request 'Consume dunite-geoip and dunite-image-upload (DEV-531)' (#458) from refactor/DEV-531-consume-dunite-geoip-image into main
    4af42c9 refactor(avatar): consume dunite-image-upload for the validation (DEV-531)
    cb25933 refactor(geoip): consume dunite-geoip instead of bunyip's copy (DEV-531)

    Downloads
  • v0.11.1 d96f82cd07

    v0.11.1
    All checks were successful
    Build Web image / Build and push Web image (push) Successful in 58s
    E2E / Playwright against deployment (push) Successful in 1m25s
    Check / fmt + clippy + build + tests (push) Successful in 3m9s
    Build API image / Build and push API image (push) Successful in 9m11s
    Stable

    nrupard released this 2026-08-04 16:51:35 +02:00 | 163 commits to main since this release

    Changelog

    d96f82c Merge pull request 'Release v0.11.1' (#457) from release/v0.11.1 into main
    e15873f Release v0.11.1
    a8e299c Merge pull request 'fix(migrations): backfill entitlement source-check before 20260802000010' (#456) from fix/BUNYIP-457-entitlement-source-check-backfill into main
    3ad7986 Merge pull request 'Split bunyip-web's admin handlers and routes (DEV-517)' (#455) from refactor/DEV-517-bunyip-web-admin-split into main
    49aa3cb ci(migrations): scope immutability gate to *.sql so doc edits pass
    bbaedc6 fix(migrations): backfill entitlement source-check before 20260802000010
    5b6f8b2 refactor(web): move the admin route table into routes/admin.rs (DEV-517)
    b0a516b refactor(web): prune the per-section admin imports (DEV-517)
    a1e472b refactor(web): give the split admin modules their own tests and items (DEV-517)
    4425a9f refactor(web): split the admin handlers one module per section (DEV-517)

    Downloads
  • v0.11.0 7c12b59032

    v0.11.0
    All checks were successful
    Build Web image / Build and push Web image (push) Successful in 1m0s
    E2E / Playwright against deployment (push) Successful in 1m22s
    Check / fmt + clippy + build + tests (push) Successful in 8m31s
    Build API image / Build and push API image (push) Successful in 9m20s
    Stable

    nrupard released this 2026-08-04 15:02:32 +02:00 | 173 commits to main since this release

    Changelog

    7c12b59 Merge pull request 'Release v0.11.0' (#454) from release/v0.11.0 into main
    b4e72ad Release v0.11.0
    f7ff8ee Merge pull request 'fix(justfile): run create-release cargo lock-sync in docker' (#453) from fix/BUNYIP-456-create-release-docker-cargo into main
    a0396ef fix(justfile): run create-release cargo lock-sync in docker
    4bdcdbf Merge pull request 'chore(deps): collapse the dunite pins onto one merged rev (DEV-495)' (#452) from chore/DEV-495-repin-dunite-merged-revs into main
    fc3a2e7 chore(deps): collapse the dunite pins onto one merged rev (DEV-495)
    9e8cb9b Merge pull request 'refactor(models): consume dunite-user-core for the account vocabulary (DEV-517)' (#451) from feat/DEV-517-consume-user-core into main
    c6ad1c1 refactor(models): consume dunite-user-core for the account vocabulary (DEV-517)
    c923d39 Merge pull request 'refactor(stripe): consume dunite-stripe StripeService (DEV-515 pt 2)' (#450) from feat/DEV-515-consume-stripe-service into main
    6e54f98 Merge remote-tracking branch 'origin/main' into feat/DEV-515-consume-stripe-service
    5ac8fbc refactor(api): map StripeServiceError at the handler call sites (DEV-515 pt 2)
    5d88783 refactor(stripe): consume dunite-stripe StripeService (DEV-515 pt 2)
    91a3212 Merge pull request 'feat(web): mask secrets/codes by default with an explicit reveal (BUNYIP-371)' (#449) from feat/BUNYIP-371-mask-secrets-screenshare into main
    bf2cdf7 fix(web): address BUNYIP-371 review - stronger blur, no-JS reveal, layout
    19a23ed docs(web): index the sensitive-reveal handler in the app.js header
    8e0d2e7 feat(web): mask secrets/codes by default with an explicit reveal
    73ff349 Merge pull request 'docs(e2e): document the TOTP secret invariant + mismatch recovery (BUNYIP-454)' (#448) from docs/BUNYIP-454-e2e-totp-invariant into main
    24c8a60 docs(e2e): document the TOTP secret invariant + mismatch recovery
    67d0c1a Merge pull request 'refactor(stripe): consume dunite-stripe response DTOs (DEV-515 pt 1)' (#447) from feat/DEV-515-consume-stripe-dtos into main
    a800234 Merge remote-tracking branch 'origin/main' into feat/DEV-515-consume-stripe-dtos
    34de435 Merge pull request 'fix(e2e): recover the 2FA single-use collision instead of re-submitting (BUNYIP-453)' (#446) from fix/BUNYIP-453-totp-fill-collision-retry into main
    64404c1 refactor(stripe): consume dunite-stripe response DTOs (DEV-515 pt 1)
    4b80cd7 Merge pull request 'feat(admin): Stripe webhook-endpoint management UI (DEV-518)' (#445) from feat/DEV-518-webhook-endpoint-ui into main
    de6291e fix(e2e): recover the 2FA single-use collision instead of re-submitting
    675bd68 Merge pull request 'refactor(feedback): consume dunite-feedback (DEV-516)' (#444) from feat/DEV-516-consume-feedback into main
    7fd82e0 feat(admin): Stripe webhook-endpoint management UI in bunyip-web (DEV-518)
    6765caa refactor(feedback): consume dunite-feedback shared crate (DEV-516)
    92cdd11 Merge pull request 'refactor(stripe): consume dunite-stripe-core (DEV-514)' (#443) from feat/DEV-514-consume-stripe-core into main
    61e6b7b refactor(stripe): consume dunite-stripe-core for webhook verification (DEV-514)
    2f032d9 Merge pull request 'test(e2e): give magic-link.spec the 3x timeout its mail retry needs (BUNYIP-452)' (#442) from test/BUNYIP-452-magic-link-test-slow into main
    0793d24 test(e2e): give magic-link.spec the 3x timeout its mail retry needs
    6ade9ba Merge pull request 'fix(rate-limit): exempt register-challenge from the per-IP floor (stateless mint)' (#441) from fix/BUNYIP-450-exempt-register-challenge-rate-floor into main
    af4b0f9 fix(rate-limit): exempt register-challenge from the per-IP floor
    f229dca Merge pull request 'fix(e2e): back off on a 429 from the register-challenge rate floor' (#440) from fix/BUNYIP-449-e2e-register-challenge-429-backoff into main
    d11482d Merge pull request 'fix(e2e): reconcile deploy-sync gate paths + log served commit on skip' (#439) from fix/BUNYIP-448-e2e-deploy-sync-gate-paths into main
    b3e57d8 fix(e2e): bound register-challenge backoff to the 60s per-test timeout
    e9a89bf fix(e2e): track only bunyip-API build paths in the deploy-sync gate
    96d8734 fix(e2e): back off on a 429 from the register-challenge rate floor
    4748083 fix(e2e): reconcile deploy-sync gate paths + log served commit on skip
    fccf43d Merge pull request 'fix(seed): allow 'seed' entitlement source so demo templates load (PMS-709)' (#438) from fix/PMS-709-seed-entitlement-source into main
    76eb48d test(seed): regression that demo-msp loads its full dataset (PMS-709)
    d9350d3 fix(seed): allow 'seed' as an entitlement source so demo templates load

    Downloads
  • v0.10.0 b71229e466

    v0.10.0
    Some checks failed
    E2E / Playwright against deployment (push) Failing after 29s
    Build Web image / Build and push Web image (push) Failing after 54s
    Check / fmt + clippy + build + tests (push) Successful in 2m48s
    Build API image / Build and push API image (push) Successful in 15m31s
    Stable

    nrupard released this 2026-08-02 18:53:07 +02:00 | 215 commits to main since this release

    Changelog

    b71229e Merge pull request 'Release v0.10.0' (#437) from release/v0.10.0 into main
    d43a6f1 Release v0.10.0
    718761d Merge pull request 'chore(ci): run E2E on the dev runner label' (#436) from chore/BUNYIP-446-e2e-dev-runner-label into main
    3123b79 chore(ci): run E2E on the dev runner label
    94e55cd Merge pull request 'fix(security): record the Stripe last-4 hint as deliberate and lock its ceiling (BUNYIP-443)' (#435) from fix/BUNYIP-443-stripe-secret-last4-hint into main
    13b6593 fix(security): record the Stripe last-4 hint as deliberate and lock its ceiling (BUNYIP-443)
    68651d8 Merge pull request 'feat(admin): flex the remaining single-column settings screens (BUNYIP-435)' (#434) from feat/BUNYIP-435-admin-settings-flex-layout into main
    a484eb4 Merge pull request 'chore(ci): run Check on the dev runner label' (#433) from chore/BUNYIP-444-check-dev-runner-label into main
    d0a5979 feat(admin): flex the remaining single-column settings screens (BUNYIP-435)
    2059435 chore(ci): run Check on the dev runner label
    3cca69a Merge pull request 'fix(security): make the SMTP password write-only, never sent to the browser (BUNYIP-432)' (#432) from fix/BUNYIP-432-smtp-password-write-only into main
    f67acee fix(security): make the SMTP password write-only, never sent to the browser (BUNYIP-432)
    8249cfb Merge pull request 'feat(admin): move any member to any tier, gated behind the admin's 2FA (BUNYIP-431)' (#431) from feat/BUNYIP-431-admin-tier-change-2fa into main
    0f92dd9 feat(admin): move any member to any tier, gated behind the admin's 2FA (BUNYIP-431)
    81251ca Merge pull request 'feat(admin): route every significant admin action through the shared confirm (BUNYIP-430)' (#430) from feat/BUNYIP-430-shared-admin-confirm into main
    3625651 feat(admin): route every significant admin action through the shared confirm (BUNYIP-430)

    Downloads
  • v0.9.1 17fd58e5d3

    v0.9.1
    Some checks failed
    E2E / Playwright against deployment (push) Failing after 57s
    Build Web image / Build and push Web image (push) Successful in 2m25s
    Check / fmt + clippy + build + tests (push) Successful in 14m21s
    Build API image / Build and push API image (push) Successful in 15m26s
    Stable

    nrupard released this 2026-08-01 21:19:12 +02:00 | 231 commits to main since this release

    Changelog

    17fd58e Merge pull request 'Release v0.9.1' (#429) from release/v0.9.1 into main
    7ef2a4a Release v0.9.1
    eb8a9e0 Merge pull request 'feat(feedback): link the captured IP into the ban flow (BUNYIP-436)' (#428) from feat/BUNYIP-436-feedback-ip-ban-link into main
    3916f1d feat(feedback): link the captured IP into the ban flow (BUNYIP-436)
    dabeb9d Merge pull request 'feat(admin): add a Test connection button to SMTP settings (BUNYIP-433)' (#427) from feat/BUNYIP-433-smtp-test-connection into main
    a90f166 feat(admin): add a Test connection button to SMTP settings (BUNYIP-433)
    8e85dc7 Merge pull request 'chore(deps): repin dunite to its merged main commit (BUNYIP-438)' (#426) from chore/BUNYIP-438-repin-dunite-main into main
    4999152 chore(deps): repin dunite to its merged main commit
    0d972c2 Merge pull request 'chore(deps): bump sqlx 0.7 to 0.8 (BUNYIP-399)' (#395) from fix/BUNYIP-399-sqlx-0.8 into main
    a768c20 Merge main into fix/BUNYIP-399-sqlx-0.8
    78ab8b4 Merge pull request 'fix(e2e): isolate the OIDC consent drive and guard the re-save' (#425) from fix/BUNYIP-402-e2e-setup-post-consent-resave into main
    bf86b71 Merge branch 'main' into fix/BUNYIP-402-e2e-setup-post-consent-resave
    e870905 Merge pull request 'fix(security): stop the rate-limit floor panicking actix's router' (#420) from fix/BUNYIP-426-audit-rollup-2026-07-30 into main
    1b4728a Merge main into fix/BUNYIP-426-audit-rollup-2026-07-30
    b3c580b fix(e2e): isolate the OIDC consent drive and guard the re-save
    904dba0 Merge pull request 'feat(admin): super-admin-gated rate limit and IP ban management' (#424) from feat/BUNYIP-413-super-admin-rate-limit-ip-ban-management into main
    a4ee380 feat(admin): super-admin-gated rate limit and IP ban management
    09c5c7e Merge pull request 'fix(api): guard cookie writes with an Origin/Referer check' (#423) from fix/BUNYIP-423-api-origin-csrf-guard into main
    7278712 fix(api): guard cookie writes with an Origin/Referer check
    b2ac7ca Merge pull request 'fix(web): self-host CDN scripts and drop script-src 'unsafe-inline'' (#422) from fix/BUNYIP-424-self-host-scripts-drop-unsafe-inline into main
    6357b8d fix(web): self-host CDN scripts and drop script-src 'unsafe-inline'
    c355cbc Merge pull request 'fix(ci): keep deployment secrets out of PR-triggered runs' (#421) from fix/BUNYIP-425-pr-ci-secret-scope into main
    7dc2fed fix(ci): keep deployment secrets out of PR-triggered runs
    fa40423 fix(security): stop the rate-limit floor panicking actix's router
    fbfb0b8 fix(security): close the 2026-07-30 audit sweep findings
    835a8b2 Merge pull request 'fix(admin): stop the users list clipping its role badges' (#419) from fix/BUNYIP-421-admin-panel-clipping into main
    6a9a7c1 fix(admin): stop the users list clipping its role badges
    a6c491d Merge pull request 'fix(2fa): accept the previous TOTP step and consume every code' (#418) from fix/BUNYIP-428-totp-step-window-and-single-use into main
    4da31a4 fix(2fa): accept the previous TOTP step and consume every code
    d07e747 chore(deps): bump sqlx 0.7 to 0.8, repin dunite to sqlx-0.8 rev

    Downloads
  • v0.9.0 d12470870c

    v0.9.0
    All checks were successful
    E2E / Playwright against deployment (push) Successful in 1m43s
    Build Web image / Build and push Web image (push) Successful in 3m13s
    Build API image / Build and push API image (push) Successful in 18m48s
    Check / fmt + clippy + build + tests (push) Successful in 28m53s
    Stable

    nrupard released this 2026-07-30 19:33:04 +02:00 | 261 commits to main since this release

    Changelog

    d124708 Merge pull request 'Release v0.9.0' (#417) from release/v0.9.0 into main
    a976032 Release v0.9.0
    6d5fd25 Merge pull request 'feat(admin): make application Active + Maintenance toggle switches, not text (BUNYIP-420)' (#416) from feat/BUNYIP-420-app-toggle-switches into main
    63015f4 feat(admin): make application Active + Maintenance toggle switches, not text (BUNYIP-420)
    0968ac4 Merge pull request 'feat(admin): consolidate Stripe nav and raise the dashboard switch (BUNYIP-417)' (#415) from feat/BUNYIP-417-nav-stripe-dashboard-switch into main
    60d2184 feat(admin): consolidate Stripe nav and raise the dashboard switch (BUNYIP-417)
    bf66498 Merge pull request 'feat(admin): port a8n-tools Stripe setup docs + Products and Prices into the Stripe panel (BUNYIP-416)' (#414) from feat/BUNYIP-416-stripe-products-prices-docs into main
    3fc00d1 feat(admin): port a8n-tools Stripe setup docs + Products and Prices into the Stripe panel (BUNYIP-416)
    0e3df4c Merge pull request 'feat(admin): two-column block layout for Tier Settings (BUNYIP-415 follow-up)' (#413) from feat/BUNYIP-415-tier-settings-two-column into main
    2ffc6ff feat(admin): two-column block layout for Tier Settings (BUNYIP-415 follow-up)
    e411a58 Merge pull request 'feat(admin): two-column block layouts for sparse full-width admin screens (BUNYIP-415)' (#412) from feat/BUNYIP-415-admin-two-column-layouts into main
    2b2e741 feat(admin): two-column block layouts for sparse full-width admin screens (BUNYIP-415)
    6c714eb Merge pull request 'feat(feedback): record source IP + user agent and mirror to the audit log (BUNYIP-411)' (#411) from feat/BUNYIP-411-feedback-request-metadata into main
    b978102 feat(feedback): record source IP + user agent and mirror to the audit log (BUNYIP-411)
    f7e5d98 Merge pull request 'feat(admin): redesign feedback list as scannable rows linking to detail (BUNYIP-422)' (#410) from feat/BUNYIP-422-feedback-list-redesign into main
    c4bb9a7 feat(admin): redesign feedback list as scannable rows linking to detail (BUNYIP-422)
    8639736 Merge pull request 'feat(docs): fix prose contrast and personalize image-pull docs (BUNYIP-407)' (#409) from feat/BUNYIP-407-docs-contrast-personalize into main
    dda63fa feat(docs): fix prose contrast and personalize image-pull docs (BUNYIP-407)
    508b734 Merge pull request 'feat(admin): overhaul the users filter bar and list (BUNYIP-410 follow-up)' (#408) from feat/BUNYIP-410-users-filter-overhaul into main
    e75ec83 feat(admin): overhaul the users filter bar and list (filters, sort, chips, states)
    464ed1f Merge pull request 'feat(admin): consolidate Users + Memberships into one filterable users page (BUNYIP-410)' (#407) from feat/BUNYIP-410-merge-users-memberships into main
    0e1a6e2 feat(admin): consolidate Users + Memberships into one filterable users page (BUNYIP-410)
    35b682b Merge pull request 'feat(oauth): name and show the icon of the requesting app on the consent screen (BUNYIP-406)' (#406) from feat/BUNYIP-406-consent-app-identity into main
    93e968f feat(oauth): use Mokosh's real brand logo on the consent screen (BUNYIP-406)
    b7023ea feat(oauth): name and show the icon of the requesting app on the consent screen (BUNYIP-406)
    e47de5d Merge pull request 'feat(admin): reorder applications with arrow icons instead of Up/Down text (BUNYIP-404)' (#405) from feat/BUNYIP-404-reorder-arrow-icons into main
    a1e84de feat(admin): reorder applications with arrow icons instead of "Up"/"Down" text (BUNYIP-404)
    83fa32d Merge pull request 'fix(sessions): show external IP and a detected device on Active Sessions (BUNYIP-409)' (#404) from fix/BUNYIP-409-session-ip-device into main
    25d62b1 fix(sessions): show external IP and a detected device on Active Sessions (BUNYIP-409)
    4374314 Merge pull request 'feat(admin): list-plus-detail redesign of the admin users screen (BUNYIP-405)' (#403) from feat/BUNYIP-405-admin-user-detail into main
    afe871b feat(admin): list-plus-detail redesign of the admin users screen (BUNYIP-405)
    f90a91a Merge pull request 'fix(web): guard empty canvas blob + fall back to original file on upload (BUNYIP-408)' (#402) from fix/BUNYIP-408-avatar-empty-blob into main
    27a7b08 fix(web): guard empty canvas blob + fall back to original file on upload (BUNYIP-408)
    c5f43a9 Merge pull request 'fix(web): avatar preview uses a data: URL, not a CSP-blocked blob: URL (BUNYIP-408)' (#401) from fix/BUNYIP-408-avatar-preview-csp into main
    5763c82 fix(web): avatar preview uses a data: URL, not a CSP-blocked blob: URL (BUNYIP-408)
    f4ef773 Merge pull request 'fix(web): ship avatar-picker CSS inline so a stale styles.css can't break it (BUNYIP-408)' (#400) from fix/BUNYIP-408-avatar-picker-inline-css into main
    a93dd05 fix(web): ship avatar-picker CSS inline so a stale styles.css can't break it (BUNYIP-408)
    56f7e4d Merge pull request 'feat(web): rich reusable avatar picker replacing the native file input (BUNYIP-408)' (#399) from feat/BUNYIP-408-avatar-picker into main
    2a91c05 feat(web): rich reusable avatar picker replacing the native file input (BUNYIP-408)
    ff4ebf3 Merge pull request 'fix(web): lift app-shell topbar above main so the profile menu is usable (BUNYIP-408)' (#398) from fix/BUNYIP-408-profile-menu-stacking into main
    94dfd8f fix(web): lift the app-shell topbar above main so the profile menu is usable (BUNYIP-408)
    13b7c71 Merge pull request 'feat(profile): consistent profile menu, first name, uploadable avatar (BUNYIP-408)' (#397) from feat/BUNYIP-408-profile-menu-avatar into main
    ea1be22 feat(profile): consistent profile menu, first name, uploadable avatar (BUNYIP-408)
    774af98 Merge pull request 'ci: install gcc on the openSUSE runner so cargo can link' (#396) from ci/fix-cc-linker-gcc into main
    b41a5a6 ci(e2e): install Chromium system libraries trimmed from the runner
    67e312d ci: also install libopenssl-devel for openssl-sys
    ce96f13 ci: install gcc on the openSUSE runner so cargo can link

    Downloads
  • v0.8.0 fd2f6c39e8

    v0.8.0
    All checks were successful
    E2E / Playwright against deployment (push) Successful in 35s
    Build Web image / Build and push Web image (push) Successful in 54s
    Check / fmt + clippy + build + tests (push) Successful in 2m37s
    Build API image / Build and push API image (push) Successful in 10m9s
    Stable

    nrupard released this 2026-07-24 18:04:51 +02:00 | 308 commits to main since this release

    Changelog

    fd2f6c3 Merge pull request 'Release v0.8.0' (#394) from release/v0.8.0 into main
    79f5a85 Release v0.8.0
    5bcb5c3 Merge pull request 'fix(cleanup): resolve four bunyip review findings (BUNYIP-400)' (#392) from fix/BUNYIP-400-cleanup into main
    84a9a1e Merge pull request 'fix(admin): report real outcome of ten admin mutations (BUNYIP-398)' (#391) from fix/BUNYIP-398-admin-false-success into main
    c395aa4 Merge pull request 'fix(web): never trap an admin on the onboarding email-verification gate (BUNYIP-401)' (#393) from fix/BUNYIP-401-admin-never-trapped-on-unverified-email into main
    9b315cd style: wrap onboarding_needed signature to satisfy rustfmt (BUNYIP-401)
    8162bcd fix(web): never trap an admin on the onboarding email-verification gate (BUNYIP-401)
    3f2f7c7 fix(cleanup): resolve four bunyip review findings
    2e69f8d fix(admin): report real outcome of ten admin mutations
    22d2d1a Merge pull request 'docs(getting-started): drop the dead help.psa.systems row (PMS-661)' (#390) from fix/PMS-661-remove-dead-help-psa-systems into main
    ebdaace docs(getting-started): drop the dead help.psa.systems row (PMS-661)
    4dc90e7 Merge pull request 'fix(email): reword password-reset email + show request country (BUNYIP-397)' (#389) from fix/BUNYIP-397-reset-email-copy into main
    d66073d fix(email): reword password-reset email and show the request country (BUNYIP-397)
    5e93a4e Merge pull request 'feat(docs): Mokosh product quick-start for mokosh-server (PMS-662)' (#388) from feat/PMS-662-mokosh-quickstart into main
    737b151 feat(docs): seed a Mokosh product quick-start for mokosh-server (PMS-662)
    6fdef53 Merge pull request 'feat(docs): Mokosh local Compose + OCI login docs for mokosh-server (PMS-678)' (#387) from feat/PMS-678-mokosh-setup-docs into main
    4de3cc8 feat(docs): seed Mokosh setup docs (compose, registry login, split) for mokosh-server (PMS-678)
    5e6552d Merge pull request 'fix(web): OCI sign-in step is always required, not "only if private" (BUNYIP-393)' (#386) from fix/BUNYIP-393-oci-login-always-required into main
    3156dfc fix(web): drop the "only if private" qualifier from the OCI sign-in step (BUNYIP-393)
    baa6f37 Merge pull request 'fix(docs): make the public per-app docs read public, not entitlement-gated (BUNYIP-394)' (#385) from fix/BUNYIP-388-public-docs-not-entitlement-gated into main
    b6e1d92 feat(catalog): show restricted-but-documented apps as a docs-only locked card (BUNYIP-395)
    7f25f20 fix(docs): make the public per-app docs read public, not entitlement-gated (BUNYIP-394)
    66e5319 Merge pull request 'fix(web): docs admin route 404 + catalog link on wrong apps (BUNYIP-390)' (#384) from fix/BUNYIP-388-docs-admin-route-and-catalog-link into main
    7de67b6 feat(web): gate the catalog Documentation link on a has_docs flag (BUNYIP-391)
    11b4d6e fix(web): register admin docs routes + move catalog docs link to OCI apps (BUNYIP-390)
    c777d16 Merge pull request 'chore(oci-build): replace bunyip-api stub-cache hacks with cargo-chef (BUNYIP-389)' (#383) from chore/BUNYIP-389-cargo-chef-build into main
    8a66354 chore(oci-build): replace bunyip-api stub-cache hacks with cargo-chef (BUNYIP-389)
    8a78e72 Merge pull request 'feat(docs): per-application documentation, admin-authored + public (BUNYIP-388)' (#382) from feat/BUNYIP-388-application-docs into main
    e3032c5 fix(docs): gate per-app doc reads, audit doc writes, robust sort_order (BUNYIP-388)
    040603c fix(docs): friendlier empty state for an app with no docs (BUNYIP-388)
    6fe190b feat(docs): per-application documentation, admin-authored + public (BUNYIP-388)
    00b631e Merge pull request 'fix(web): make public /docs user-facing, drop internal dev runbooks (BUNYIP-387)' (#381) from fix/BUNYIP-387-user-facing-docs into main
    6c09fc7 fix(web): describe the account action instead of naming a button (BUNYIP-387)
    515d03b fix(web): make public /docs user-facing, drop internal dev runbooks
    5d79006 Merge pull request 'feat(oci): retain app version history so bumps do not lose old versions (BUNYIP-386)' (#380) from feat/BUNYIP-386-oci-version-history into main
    6cfc71d Merge pull request 'feat(web): serve top-level docs publicly at /docs (BUNYIP-385)' (#379) from feat/BUNYIP-385-docs-route into main
    e62f108 feat(download): retain + serve historical binary releases (BUNYIP-386)
    d1bdbf0 feat(oci): self-heal version history + fill digest on the serve path (BUNYIP-386)
    31b483c feat(oci): retain app version history so bumps do not lose old versions (BUNYIP-386)
    80b110e fix(web): strip raw HTML from rendered docs for defense-in-depth (BUNYIP-385)
    9247577 fix(web): use axum 0.7 colon route param for /docs/:slug (BUNYIP-385)
    78919d0 feat(web): serve top-level docs publicly at /docs (BUNYIP-385)
    eadfafd Merge pull request 'fix(web): close the SSE EventSource on pagehide (BUNYIP-380)' (#377) from fix/BUNYIP-380-sse-pagehide-close into main
    f1d2e4b Merge branch 'main' into fix/BUNYIP-380-sse-pagehide-close
    9d09fbe Merge pull request 'fix(e2e): register disposable accounts through the signup bot guard (BUNYIP-384)' (#378) from fix/BUNYIP-384-e2e-signup-guard into main
    c8877e6 fix(e2e): register disposable accounts through the signup bot guard (BUNYIP-384)
    411d01b fix(web): close the SSE EventSource on pagehide (BUNYIP-380)
    73f07d6 Merge pull request 'feat(auth): merge the 2FA trust-device control into sign-in remember-me (BUNYIP-382)' (#376) from feat/BUNYIP-382-merge-2fa-remember into main
    ec5903b Merge branch 'main' into feat/BUNYIP-382-merge-2fa-remember
    1e70872 Merge pull request 'feat(auth): uniform 30-min / 1-day (30-day-remember) session lifetimes (BUNYIP-381)' (#375) from feat/BUNYIP-381-token-lifetimes into main
    b4ce83e feat(auth): merge the 2FA trust-device control into sign-in remember-me (BUNYIP-382)
    5b78d6c feat(auth): uniform 30-min / 1-day (30-day-remember) session lifetimes, drop admin idle leash (BUNYIP-381)
    eb6a124 Merge pull request 'feat(auth): signup bot-guard foundation - honeypot + submit-timing (BUNYIP-377)' (#374) from feat/BUNYIP-377-signup-bot-prevention into main
    616e6f9 feat(web): wire the register form to the signup bot guard (BUNYIP-377)
    c65ce8d feat(auth): signup bot-guard foundation - honeypot + submit-timing (BUNYIP-377)
    f8dccb1 Merge pull request 'feat(auth): harden the login-approval gate (BUNYIP-375)' (#373) from feat/BUNYIP-375-approval-gate-hardening into main
    5f18691 feat(auth): harden the login-approval gate (BUNYIP-375)
    87039ec Merge pull request 'feat(auth): suspicious-login notify-and-approve gate (BUNYIP-373)' (#372) from feat/BUNYIP-373-suspicious-login-approval into main
    4be752a fix(auth): make the login-approval attempt cap and single-use race-free (BUNYIP-373)
    9256804 feat(auth): gate suspicious logins behind an emailed approval code (BUNYIP-373)
    e13fb92 Merge pull request 'fix(catalog): correct stale Mokosh app names and disable vervain-agent (BUNYIP-374)' (#371) from fix/BUNYIP-374-applications-catalog-names-vervain into main
    ac330a4 feat(auth): BUNYIP-373 foundation - schema, challenge token, config flag
    5a96743 Merge pull request 'feat(web): add a Docker Compose deploy option to app download instructions (BUNYIP-372)' (#370) from feat/BUNYIP-372-compose-download-instructions into main
    760905c fix(catalog): correct stale Mokosh app names and disable vervain-agent
    6edd143 feat(web): add a Docker Compose deploy option to app download instructions (BUNYIP-372)
    8466e47 Merge pull request 'feat(auth): alert users on a new-country login (BUNYIP-366)' (#369) from feat/BUNYIP-366-login-location-alerts into main
    bfed45e feat(auth): user-settable login-location opt-out, test alert decision
    1ed8542 feat(auth): alert users on a new-country login (BUNYIP-366)
    4226330 Merge pull request 'feat(applications): surface per-app release-notes link in the applications view (BUNYIP-343)' (#368) from feat/BUNYIP-343-application-release-notes into main
    3d21e04 feat(applications): surface per-app release-notes link in the applications view (BUNYIP-343)
    4ceefd3 Merge pull request 'feat(security): self-provision the bunyip_app NOBYPASSRLS role (BUNYIP-360)' (#365) from feat/BUNYIP-360-provision-app-role into main
    f351e7b Merge pull request 'feat(e2e): bunyip-e2e-bootstrap --enable-2fa enrolls a preset TOTP secret (BUNYIP-359)' (#367) from feat/BUNYIP-359-bootstrap-2fa into main
    20bc03b fix(e2e): refuse --enable-2fa under the all-zero dev TOTP key (BUNYIP-359 review)
    a84839c feat(e2e): bunyip-e2e-bootstrap --enable-2fa enrolls a preset TOTP secret (BUNYIP-359)
    b8275f2 Merge pull request 'feat(hub): step-by-step download/pull instructions in the OCI/Download modal (BUNYIP-358)' (#366) from feat/BUNYIP-358-download-instructions into main
    0f50ac3 feat(hub): step-by-step download/pull instructions in the OCI/Download modal (BUNYIP-358)
    2625fe8 feat(security): self-provision the bunyip_app NOBYPASSRLS role to activate per-user RLS (BUNYIP-360)
    13e8dd5 Merge pull request 'feat(security): route more self-service reads through begin_with_user (BUNYIP-344)' (#364) from feat/BUNYIP-344-route-remaining-selfservice-reads into main
    17d67b2 feat(security): route more self-service reads through begin_with_user (BUNYIP-344)
    1535a17 Merge pull request 'feat(security): per-user row level security on self-service tables (BUNYIP-344)' (#363) from feat/BUNYIP-344-rls-self-service-slice into main
    75b0d8f feat(security): per-user row level security on self-service tables (BUNYIP-344)
    7fe98c4 Merge pull request 'fix(api): resolve external client IP in tracing span and OIDC IP capture' (#362) from fix/BUNYIP-310-access-log-client-ip into main
    fcb0783 fix(api): resolve external client IP in tracing span and OIDC IP capture
    c5e1c56 Merge pull request 'feat(web): forward end-user client IP to bunyip-api' (#361) from feat/BUNYIP-311-web-forward-client-ip into main
    7d527a9 feat(web): forward end-user client IP to bunyip-api
    fe3dd22 Merge pull request 'docs(scaffold): update Postgres image ref to PG18' (#360) from chore/BUNYIP-349-docs-postgres-18 into main
    716aedc docs(scaffold): update Postgres image ref to PG18
    2c8c086 Merge pull request 'fix(oidc): use SHA-512 left-32 at_hash for EdDSA id_tokens' (#359) from fix/BUNYIP-352-at-hash-sha512-eddsa into main
    f8687e2 fix(oidc): use SHA-512 left-32 at_hash for EdDSA id_tokens
    0083c62 Merge pull request 'docs(backup): document MOKOSH_BACKUP_API_URL for teammates (BUNYIP-356)' (#358) from docs/BUNYIP-356-mokosh-backup-url-runbook into main
    994b5a2 docs(backup): document MOKOSH_BACKUP_API_URL for teammates (BUNYIP-356)
    18a5b0b Merge pull request 'feat(backup): wire the real Mokosh backup/restore client (BUNYIP-356)' (#357) from feat/BUNYIP-356-mokosh-backup-adapter into main
    3a92dfa feat(backup): wire the real Mokosh backup/restore client (BUNYIP-356)
    b3b96c5 Merge pull request 'feat(backup): account-level backup and restore behind the Backup add-on (BUNYIP-353)' (#356) from feat/BUNYIP-353-account-backup-restore into main
    c2a033a feat(backup): account-level backup and restore behind the Backup add-on (BUNYIP-353)
    93d81f3 Merge pull request 'feat(settings): regenerate 2FA recovery codes UI (BUNYIP-355 part 1)' (#355) from feat/BUNYIP-355-recovery-codes-ui into main
    f31f9a1 fix(2fa): revoke trusted devices and rate-limit on authenticator re-key confirm (BUNYIP-355)
    f39d1f5 feat(2fa): step-up-gated authenticator re-key with a staged pending secret (BUNYIP-355 part 2)
    e6cda1a feat(settings): regenerate 2FA recovery codes from the settings page (BUNYIP-355 part 1)
    1136345 Merge pull request 'feat(oidc): first-party consent skip + named third-party consent (BUNYIP-342 part 1)' (#354) from feat/BUNYIP-342-first-party-consent-skip into main
    e8cce8e fix(oidc-web): reject off-issuer consent continue_url (open redirect) (BUNYIP-342)
    84a2491 feat(oidc-web): named third-party consent screen and spec-compliant Deny (BUNYIP-342 part 2)
    fa9ee0c feat(oidc): skip consent for first-party clients, name the client for third-party (BUNYIP-342 part 1)
    3d77406 Merge pull request 'chore(compose): bump self-host Postgres to 18 (BUNYIP-350)' (#353) from chore/BUNYIP-350-postgres-18 into main
    65f9bfe chore(compose): bump dev Postgres 16 -> 18 for dev/prod parity (BUNYIP-350)
    d552171 chore(compose): bump self-host Postgres 16 -> 18 to match the deployed template (BUNYIP-350)
    0226b8c Merge pull request 'feat(admin): move Stripe checkout knobs into DB admin settings (BUNYIP-351)' (#352) from feat/BUNYIP-351-stripe-checkout-db-config into main
    6c735c9 Merge branch 'main' into feat/BUNYIP-351-stripe-checkout-db-config
    9d0364f Merge pull request 'feat(admin): move email/SMTP config into DB admin settings (BUNYIP-351)' (#351) from feat/BUNYIP-351-email-db-config into main
    9d5b6cd feat(admin): move Stripe checkout knobs into DB admin settings (BUNYIP-351)
    c622200 Merge remote-tracking branch 'origin/main' into feat/BUNYIP-351-email-db-config
    8f0999f feat(admin): move email/SMTP config into DB admin settings (BUNYIP-351)
    2cd43a5 Merge pull request 'feat(admin): move auto-ban config into DB admin settings (BUNYIP-351)' (#350) from feat/BUNYIP-351-auto-ban-db-config into main
    d0ce0c2 feat(admin): move auto-ban config into DB admin settings (BUNYIP-351)
    81305b0 Merge pull request 'feat(auth): bootstrap first admin from BOOTSTRAP_ADMIN_EMAIL (BUNYIP-290)' (#349) from feat/BUNYIP-290-bootstrap-admin-email into main
    4ff90cd feat(auth): bootstrap first admin from BOOTSTRAP_ADMIN_EMAIL (BUNYIP-290)

    Downloads