paas-charm 2.0 release notes

20 October 2026

These release notes cover new features and changes in paas-charm version 2.0 and its extended support into Charmcraft and Rockcraft.

paas-charm 2.0b1 is the first beta of 2.0. Features and interfaces may still change before the stable release.

This is a beta of a major release that introduces backwards-incompatible changes. See Upgrade to paas-charm 2.0 for migration instructions.

For more detailed information on Charmcraft and Rockcraft, see their dedicated release notes:

See our Release policy and schedule.

Requirements and compatibility

paas-charm 2.0 requires Python 3.12 or greater, and the following software:

  • charmlibs-interfaces-oauth 1.2.0

  • charmlibs-interfaces-openfga 1.0.0

  • charmlibs-interfaces-tracing 1.0.0

  • cosl 1.11.3

  • dpcharmlibs-interfaces 1.2.2

  • Jinja2 3.1.6

  • jsonschema 4.26.0

  • ops 3.9.0

  • pydantic 2.14.1

Building Ubuntu 26.04 LTS rocks requires Rockcraft 1.21 or later. Building Ubuntu 26.04 LTS charms requires a Charmcraft release that includes the updated 12-factor extension contract. Until then, use the latest/edge channel of the Charmcraft snap.

All charms and rocks must be rebuilt for Ubuntu 26.04 LTS. Rocks use either base: ubuntu@26.04 or base: bare with build-base: ubuntu@26.04. Charms use base: ubuntu@26.04.

Charmcraft’s Ubuntu 24.04 LTS profiles keep the earlier generated contract and pin paas-charm 1.x. They are not a supported path to paas-charm 2.0.

For a complete new-app walkthrough, follow the Ubuntu 26.04 LTS tutorials for Django, Express, FastAPI, Flask, Go, or Spring Boot.

Upgrade instructions

This release requires a manual project migration; charmcraft pack alone does not migrate an existing Ubuntu 22.04 LTS or Ubuntu 24.04 LTS project.

Before refreshing a deployment:

  1. Migrate and rebuild every rock with an Ubuntu 26.04 LTS base or build base.

  2. Migrate and rebuild every charm with base: ubuntu@26.04, the uv plugin, pyproject.toml, a uv.lock file that you generate with uv lock, and a compatible dependency such as paas-charm>=2.0.dev1,<3.

  3. Check that the packed charm has the app container, the app-image resource, the peers relation and a secret-typed app-secret-key option. The framework extension provides them, so don’t redeclare app-secret-key in charmcraft.yaml. Keep paas-config.yaml, if you use one, in the charm project directory: the extension packs it automatically.

  4. Review the Backwards-incompatible changes before refreshing the deployment.

See Upgrade to paas-charm 2.0 for complete instructions and links to the current Charmcraft and Rockcraft migration references.

Updates

paas-charm

Framework configuration through paas-config.yaml

Application and metrics endpoints are now configured through top-level port, metrics-port, and metrics-path fields in the charm-owned paas-config.yaml file, alongside the existing structured logging and Prometheus sections. The charm always exposes the resolved framework defaults to the workload, and the resolved metrics-port and metrics-path are published as the framework Prometheus scrape job. This configuration applies to all supported frameworks, including Go. See paas-config.yaml and Prometheus configuration for details.

Custom Prometheus scrape jobs

Additional Prometheus jobs can be declared under prometheus.scrape_configs without replacing the framework scrape job. Custom targets do not configure the workload listener; you must ensure each target is actually served. See Prometheus configuration for details.

Environment variable names for config options

Config options and secret entries can be renamed in the workload environment through config.options in paas-config.yaml, including framework outputs and generated secret keys.

Custom relations

The public paas_charm.relations.CustomRelation API lets charm authors add their own Juju relations to a 12-factor charm, covering environment variables, readiness and blocking, and reconcile. The built-in Valkey relation is declared directly with this framework.

Application secret key stored in a Juju secret

The generated application secret key is now stored in a Juju application-owned secret instead of the peer relation databag. The secret-storage peer relation (and its interface) is renamed to peers, and the peer relation is now used only for peer coordination such as PEER_FQDNS. The key can be rotated with the rotate-secret-key action. See Secrets for details.

Standardized app-secret-key configuration

Secret key configuration is standardized across all frameworks as a single app-secret-key option of type secret that accepts a Juju user secret ID. This replaces the previous string app-secret-key and app-secret-key-id options and the framework-specific flask-secret-key/django-secret-key options. Framework-prefixed workload variables such as FLASK_SECRET_KEY and DJANGO_SECRET_KEY are preserved. See Secrets for details.

OAuth integration migrated to charmlibs

The deprecated charms.hydra.v0.oauth charm library is replaced with the maintained charmlibs.interfaces.oauth package. This is API-compatible with the previous library. See the OAuth interface documentation for details.

OpenFGA and tracing integrations migrated to charmlibs

The OpenFGA and tracing integrations now use their maintained charmlibs interfaces. See the OpenFGA interface documentation and tracing interface documentation for details.

Custom relations API

The public paas_charm.relations.CustomRelation API lets charm authors add their own Juju relations to a 12-factor charm, including environment variables, readiness, and reconcile behavior. See Add a custom relation and Custom relations for details.

Environment variable names for config options

Environment variables generated from charm configuration options and secrets can be renamed with config.options in paas-config.yaml. See paas-config.yaml for details.

Valkey integration uses the custom relations framework

The Valkey integration is migrated to the custom relations framework.

OpenFGA store uses the charm application name

The OpenFGA store name is now derived from the charm application name instead of a fixed value.

Rockcraft

See Charm architecture for the workload layout, and the Rockcraft extension reference for framework-specific configuration.

  • Flask and Django application files are placed in /app with the Gunicorn configuration in /var/lib/gunicorn on the Ubuntu 26.04 LTS base. (Pull request #1348)

  • Ubuntu 26.04 LTS framework support includes rocks with a bare base and an Ubuntu 26.04 LTS build base. (Pull request #1320)

  • Ubuntu 26.04 LTS framework rocks provide /app-data as a writable application data directory owned by the _daemon_ workload user. (Pull request #1332)

  • Gunicorn dependencies were updated for Ubuntu 26.04 LTS. (Pull request #1303)

  • Extension part names may use the '.' separator on bases that disallow /. (Pull request #1345)

  • Bare-base framework rocks stage /tmp from the base-files_tmp slice. (Pull request #1387)

Charmcraft

See the Charmcraft framework extension reference for the generated charm contract, and Migrate your 12-factor charm to use the uv plugin for dependency management.

Until Ubuntu 26.04 LTS framework support is promoted from experimental in the current tools, set ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 when invoking Rockcraft and CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 when invoking Charmcraft.

Backwards-incompatible changes

The following are breaking changes introduced in paas-charm. See Upgrade to paas-charm 2.0 for migration instructions.

paas-charm

Application secret key regeneration

On upgrade, a fresh application secret key is generated because existing values are not migrated from the former peer databag. Applications that use this key for session signing (including Flask, Django, FastAPI, ExpressJS, and Spring Boot) may invalidate existing sessions. To provide your own key, set the app-secret-key option to a Juju secret ID. (Pull request #345)

secret-storage relation renamed to peers

The secret-storage peer relation and its interface are renamed to peers. Charm metadata consumers must use the new endpoint and interface names. (Pull request #345)

app-secret-key configuration option

The string app-secret-key and separate app-secret-key-id options, as well as flask-secret-key/django-secret-key, are replaced by a single app-secret-key option of type secret that accepts a Juju user secret ID. Reapply any existing secret key configuration as a Juju secret. (Pull request #367)

Removal of the paas_app_charmer import path

The deprecated paas_app_charmer import path is removed. Use paas_charm instead. (Pull request #369)

Flask and Django application layout and resource names

The Flask and Django application root directory is now /app (matching FastAPI and ExpressJS), with the mutable gunicorn.conf.py moved to /var/lib/gunicorn. Access and error logs continue to use stdout and stderr. Flask and Django rocks must be rebuilt for Ubuntu 26.04 LTS.

The Flask workload container and image resource change from flask-app and flask-app-image to app and app-image. The Django names similarly change from django-app and django-app-image to app and app-image. Update deployment commands and automation that supply the image resource; existing applications may need --resource app-image=<image> when refreshed. (Pull request #352)

Rockcraft extension part-name separator

Extension-generated Rockcraft part names use . instead of / with an Ubuntu 26.04 LTS effective build base, including bare rocks whose build-base is Ubuntu 26.04 LTS. Update custom part overrides and references to use the newly expanded names, such as flask-framework.dependencies instead of flask-framework/dependencies. Entries in the prime key of the install-app part must also start with app on Ubuntu 26.04 LTS, for example app/app.py instead of flask/app/app.py.

Application port configured only through paas-config.yaml

The application port of the FastAPI, Go, ExpressJS, and Spring Boot charms is read only from port in paas-config.yaml, and the framework default applies otherwise. The webserver-port, app-port, and port charm configuration options are ignored. Workload environment variables are unchanged. (Pull request #388)

Charm state directory

All frameworks store charm state, such as the database migration status, in /tmp/paas-charm instead of /tmp/<framework>/state or /app/state. Rocks no longer need to provide /app/state. (Pull request #388)

Redis replaced with Valkey

Redis examples and tests are replaced with Valkey. Consumers that still relate through the redis endpoint or call /redis/* must move to the valkey relation and /valkey/* endpoints. The REDIS_DB_* environment variables are no longer set; use VALKEY_DB_* instead. (Pull request #347)

Loki loki_push_api v0 removal

Support for the v0 version of the loki_push_api library is removed. Charms must use the v1 library. (Pull request #374)

Bug fixes

paas-charm

  • Use OpenTelemetry auto-instrumentation for metrics in the FastAPI example.

  • Serve ExpressJS Prometheus metrics on the configured METRICS_PORT.

Charmcraft

No bug fixes to report.

Rockcraft

No bug fixes to report.

Deprecated features

The following features and interfaces are removed in this release:

  • The paas_app_charmer import path.

  • The charms.hydra.v0.oauth charm library.

  • The v0 loki_push_api charm library.

  • Redis integration in examples and tests.

Thanks to our contributors

@alithethird, @javierdelapuente, @Thanhphan1147, @weiiwang01, @erinecon