Back to blog
2026-10-27 Thijs Creemers

Release candidate: v1.1.0-rc-1 — permissions, roles and scopes


The first release candidate for 1.1. 1.0.1 is still the stable release, and the installer still installs it. Try the rc on a branch and tell us what breaks before 1.1.0 ships.

New: authorization with permissions, roles and scopes

Modules declare permissions and roles. Groups hold roles, optionally limited to a scope (a key your module declares). Routes check them under :wagoe/authorization:

  • :off (the default): nothing changes.

  • :report: logs each refusal :enforce would make. Run this first.

  • :enforce: refuses those requests. wagoe new apps start here.

The admin gets pages to manage it. Access explain shows why a user may or may not use a permission. The grant wizard gives a user one permission and nothing more. Every group or role change previews who gains and loses rights before it saves. Memberships can end on a set date.

Start with the Authorization guide. Admins should read Managing access.

New libraries

  • wagoe-webhooks: sends bus events to subscriber URLs, signed and retried as jobs.

  • wagoe-test: with-test-system, a Ring client with session and CSRF, sign-in-as! and create-user!.

That brings the suite to 33 published artifacts.

Also in this release

  • Jobs: recurring jobs on a cron schedule, :unique-key deduplication, and :expect-success alerts when a job type stops succeeding.

  • Sign-in: OpenID Connect sign-in, a per-login MFA decision, and self-registration can be switched off.

  • Admin: a dashboard with counts and recent activity, a record drawer, lookups instead of raw IDs, and many-to-many edits.

  • Platform: MySQL 8, OpenAPI 3.1, opt-in virtual threads, a #secret config reader, a transactional outbox, and htmx updates over server-sent events.

Security fixes

Upgrade soon if any of these apply to you:

  • A stolen session could turn MFA off. Turning MFA off now needs the password or a current code.

  • Any signed-in user could read every workflow instance through the API, across tenants.

  • An audience filter could name any users column, including password hashes.

  • The login response carried the hashes of spent MFA backup codes.

  • Guava 33.6.0 (CVE-2026-102554) is replaced by 33.7.2 in wagoe-push and wagoe-storage.

Before you upgrade

Most apps need only steps 1 to 3. The rest of the list is in UPGRADING.md.

  1. Pin 1.1.0-rc-1 for every com.wagoe/* dependency, then run bb migrate up.

  2. Run wagoe upgrade. It shows a diff of the rewrites it can make (--apply writes them) and lists the rest for you to do by hand.

  3. Check :role in your code. It is now :admin or nil. (= :user (:role u)) never matches, so check a permission instead.

  4. Expect daisyUI, not pico: the :base CSS bundle is gone, and default-layout pages render with :pilot.

  5. Point API clients at /openapi.json. The docs are OpenAPI 3.1, and /swagger.json serves the 3.1 document too.

  6. If your own repository or service implements a Wagoe port and boot stops with WGE-107, implement the protocol it names.

To move an existing app to :enforce, run bb upgrade authorization check. It names every user who would lose access. The upgrade guide walks through the rest.

{:deps {com.wagoe/wagoe-platform {:mvn/version "1.1.0-rc-1"}
        com.wagoe/wagoe-user     {:mvn/version "1.1.0-rc-1"}
        com.wagoe/wagoe-admin    {:mvn/version "1.1.0-rc-1"}}}