Upgrade Notes & Breaking Changes
This page is the canonical, per-release reference for changes that affect operators running a Rise installation: breaking changes, required actions, and new or changed configuration. Read the section for the version you are upgrading to before upgrading.
Impact legend
Section titled “Impact legend”| Badge | Meaning |
|---|---|
| Breaking | Requires action or behavior changes incompatibly; upgrading without reading may break installs. |
| Action required | Upgrade succeeds, but an operator action is needed to get correct/expected behavior. |
| Config change | New or changed configuration is available; defaults preserve existing behavior. |
Unreleased
Section titled “Unreleased”Changes merged to develop but not yet in a tagged release, plus in-flight PRs
proposed for the next train. Moved into a version section at tag time.
In-flight PRs with operator impact (not yet merged):
-
Action required if conflicts exist — identity resource activation (#421). Rise now activates the eight reserved
rise.dev/v1alpha1identity resource kinds in the PostgreSQL resource store. Before upgrading, remove any legacy ResourceDefinitions that claim those reserved group/kind or collection identities, and migrate or remove any stored identity rows whose structural parents do not match the built-in hierarchy. Startup fails closed when such conflicts exist and reports the total plus a bounded sample; use the previous Rise version to remove the conflicting definitions and rows, then recreate custom resources under a non-reserved identity if needed. Installations with no reported conflicts require no action.Worth knowing before you start: the reservation is wider than the eight identity kinds. The whole
rise.devAPI group is now closed to external ResourceDefinitions, as are the eight identity collection names in any group (collection names have always been globally unique). The activation runs in one transaction, so an upgrade rejected by the audit leaves the database exactly as it was — clean up the conflicts it names under the previous Rise version and retry. -
Action required if conflicts exist — policy resource activation. Rise activates the four reserved
rise.dev/v1alpha1policy resource kinds —RoleandRoleBindingunder an Organization,PlatformRoleandPlatformRoleBindingat the root — in the PostgreSQL resource store. The same fail-closed pattern as the identity activation above applies: before upgrading, remove any stored rows in therise.devgroup using those four Kind names, and any ResourceDefinition claiming one of the four collection names (roles,rolebindings,platformroles,platformrolebindings) in any group. Startup reports the total plus a bounded sample and leaves the database unchanged, so clean up under the previous Rise version and retry. Installations with no reported conflicts require no action.Nothing yet consults these resources: writing a
RoleBindinggrants no access, and/api/v1/resourcesremains operator-gated. Bindings are validated at write time, so creating one requires itsroleReftarget, itsscopetarget, and any literalsubjectit names to already exist — create the Role before the RoleBinding that references it. -
Behavior change — workload identity on the Docker backend (#378). The Docker controller now delivers the same workload-identity material as Kubernetes — the bootstrap credential and one token file per
[identity].audiencesentry — to/var/run/secrets/rise/identity/inside each app container (via the Docker archive API), and refreshes the token files before they expire. No new configuration; this closes a parity gap, so a Docker app that sets[identity].audiencesnow receives its tokens instead of nothing. Identity files are delivered when a container is created, and the controller also self-heals already-running containers that lack them on the next reconcile, so apps running before the upgrade pick up their identity material without a redeploy (mirroring the Kubernetes controller re-establishing it on each sync). -
Behavior change — workload identity token refresh on Kubernetes (#390). The Kubernetes controller now runs a leader-elected loop that re-mints each deployment’s pre-minted identity token files before they expire. The sync webhook records a per-deployment due time (~2/3 of
deployment_controller.identity_token_ttl_secondsafter each mint); the loop resyncs aRiseProjectonly when one of its deployments is due. Metacontroller does not resync a steady project on its own, so previously a long-lived pod’s identity file token could expire without being refreshed (the on-demand token-exchange endpoint was unaffected). No new configuration and no action required; the only operational change is arise.dev/triggerannotation write per due deployment (so projects are touched only when a refresh is needed, and the work is naturally staggered) and one more background lease (rise-identity-refresh). Docker already refreshed via its own reconcile loop, so this closes the gap on Kubernetes. The per-project re-mint due time is tracked on theRiseProjectCR’sstatus.identityRefreshDueAt(written by the sync webhook), so there is no deployments-table schema change. -
Action required — raw external token deprecation signal (#374). While
auth.allow_raw_external_tokensistrue, each accepted raw-token request now emits one metric-shapedtracingevent (target=rise::deprecation,metric=raw_external_token) carrying the validatedissuer/sub. Aggregate it in your log pipeline (count, group byissuer/sub) to find which CI workload identities still present raw external tokens: the default flips tofalsein 0.25.0, after which those callers must pre-exchange atPOST /api/v1/auth/token. No config change; migrate CI before upgrading to 0.25.0. -
Config change — auth token exchange (phase 1) (#367). Adds the RFC 8693 exchange endpoint and a Rise
Accesstoken kind. Purely additive; existing token flows are unchanged, legacy in-handler verification remains the fallback. SeeROADMAP.md§ “Workstream 2 — Authentication & Token Exchange”. -
Config change — Docker deployment backend (#358). Selectable via
deployment_controller.type = "docker". Single-host; Kubernetes remains the default, so existing installs are unaffected unless they opt in. A new deployment rolls over via Traefik health checks, with old and new overlapping in one load-balanced service (a rolling update, vs. Kubernetes’ atomic blue/green). Probing is opt-in: nohealth_checkmeans ready-when-running; a sethealth_checkis a 2xx–3xx check. Operator-relevant settings on the Docker controller (env-driven; the shipped standalone compose sets working defaults):traefik_api_url(default in-networkhttp://rise-traefik:8080) — the rolling gate reads Traefik’sserverStatus, the authoritative readiness signal for health-checked containers (no fallback). The standalone Traefik enables its API internally (--api.insecure=true, port not published). If you run your own Traefik and any project uses ahealth_check, you must expose its API to the backend over the internal network (optionally with basic-auth embedded in the URL); without it a health-checked deployment never becomes Healthy. It may be left unset only when no project uses health checks.- Replicas: the Docker config raises
deployment_constraints.max_replicasto 10 (RISE_MAX_REPLICAS); the controller additionally hard-caps at 50. The deployment-backend feature matrix, the Docker operator pages, and the cutover/health-check docs ship with this PR.
-
Action required — reserved
RISE_env-var prefix (#355). User-supplied environment variable keys beginning withRISE_are rejected at the API and at deploy time (project env vars and per-container[containers.X.env]). If any of your users’ apps setRISE_*keys, rename them before upgrading.
0.23.0
Section titled “0.23.0”First release of the generic resource substrate (compatibility phase). None of these change behavior for existing installs by default; the items below are the configuration knobs they introduce.
- Config change — Operator role (
auth.operator_users). The generic resource API (/api/v1/resources) is gated to a new, separately configured Operator role.auth.admin_usersdo not receive Operator access. No action needed unless you want operators to manage generic resources. SeeROADMAP.md. - Config change — default Organization / Kubernetes
controller_class_name. Backend startup bootstraps a single default Organization and backfills existing users, teams, and projects to it under an advisory lock. Existing installs resolve to the same namespace names as before (rise-prefix →rise-myapp). The Kubernetes controller’scontroller_class_namedefaults to a stable value for existing installs if unset.
Watch for later (not yet released)
Section titled “Watch for later (not yet released)”These are tracked as finalization gates and will land in a future release — listed here so operators can anticipate them:
- Breaking (future) — multi-tenancy phase 2. Tightening
organization_resource_uidtoNOT NULLafter backfill, and migrating typed tables onto the generic resource model. Tracked in #372. - Breaking (0.25.0, behind operator toggle) — removal of the legacy auth path.
auth.allow_raw_external_tokensdefaults tofalsestarting in 0.25.0, and auth token-exchange phase 3 removes the legacy in-handler verification path. Therise::deprecationraw-external-token metric (above) tells you when raw-token traffic has drained and it is safe to upgrade. Tracked in #374.