> ## Documentation Index
> Fetch the complete documentation index at: https://omniflow-vpn.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Compatibility and upgrades

> The supported version matrix, how release artifacts are versioned and signed, the upgrade window, and the deprecation policy

This page is the compatibility contract: what Omniflow is tested against, how a
release is identified and verified, how far behind an installation may fall
before upgrading, and how a deprecated capability is retired instead of
silently removed.

## Compatibility matrix

| Component | Supported | Notes |
| - | - | - |
| Remnawave | 3.2.x | Targets the 3.2.2 API surface; asserted in `internal/remnawave/contract_test.go`. |
| PostgreSQL | 18.x | The only durable store. Shipped images pin the matching PostgreSQL 18 client tools for `pg_dump`/`pg_restore`. |
| Valkey | 9.x | Cache, rate limits, locks, and disposable state only — never a source of truth. |
| Go | 1.26 | Build-time only. Contributors building from source need it; the shipped Docker images already contain a compiled binary. |
| Bun / Node.js | Bun 1.3, Node ≥ 26 | Build-time only, for the frontend workspace. Not required to run the shipped `web` image. |
| Browsers | [`browserslist` `defaults`](https://browsersl.ist/#q=defaults) | Roughly the last 2 versions of evergreen Chrome, Firefox, Safari, and Edge, plus Firefox ESR; excludes Internet Explorer. Enforced at build time in `apps/web/package.json`. |

> [!NOTE]
>
> Go and Bun are contributor requirements, not operator requirements. An
> installation runs the images published to `ghcr.io/kewldan/omniflow/*` and
> never needs a Go or Bun toolchain on the host.

This table describes what the current `main` line is tested and built
against. A future 1.x release that changes a supported version updates this
row, and a version bump that removes support for something in this table is
called out in `CHANGELOG.md` rather than silently dropped — see
[Deprecation policy](#deprecation-policy).

## Versioning and release artifacts

Releases follow [Semantic Versioning](https://semver.org/) and are cut by
[Release Please](https://github.com/googleapis/release-please) from
[Conventional Commits](https://www.conventionalcommits.org/), which also
generates `CHANGELOG.md` — nothing is hand-written after the fact.

Each tagged release publishes four multi-arch (`linux/amd64`,
`linux/arm64`) container images to GitHub Container Registry:

```text theme={null}
ghcr.io/kewldan/omniflow/api:vX.Y.Z
ghcr.io/kewldan/omniflow/bot:vX.Y.Z
ghcr.io/kewldan/omniflow/worker:vX.Y.Z
ghcr.io/kewldan/omniflow/web:vX.Y.Z
```

Every image is also tagged `X.Y` so a deployment can track a minor line
without floating on `latest`.

### SBOM, provenance, and signatures

Every image build attaches an SBOM and SLSA-style build provenance
(`docker/build-push-action`'s `sbom: true` and `provenance: mode=max`), and is
then signed keyless with [cosign](https://docs.sigstore.dev/cosign/overview/)
using the release workflow's own GitHub Actions OIDC identity — there is no
signing key to manage, rotate, or leak. The signature is recorded in the
public Rekor transparency log.

Verify an image before deploying it:

```bash theme={null}
cosign verify \
  --certificate-identity-regexp 'https://github.com/kewldan/omniflow' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/kewldan/omniflow/api:vX.Y.Z
```

Inspect the attached SBOM and provenance with `docker buildx imagetools
inspect --format '{{ json .SBOM }}' ghcr.io/kewldan/omniflow/api:vX.Y.Z` (and
`.Provenance` for the build provenance).

## Upgrade testing

CI's `migrations` job proves every supported upgrade path before a change
merges: it applies the schema from an empty database through every prefix of
the migration history to head, and confirms re-applying head a second time is
a no-op. That is what "automated upgrade tests" means in practice — a
migration that only compiles is unverified, so this runs against a real
PostgreSQL on every change, not only at release time.

The step-by-step upgrade, rollback, and PostgreSQL major-version upgrade
procedures live in
[Backup, restore, and disaster recovery](https://omniflow-vpn.mintlify.site/operations/backup-restore.md#upgrading-omniflow)
rather than being duplicated here.

## Migration policy and supported upgrade window

* Migrations are **forward-only**. Omniflow does not ship down-migrations; a
  schema rollback is a restore from the backup taken immediately before the
  upgrade, as described in
  [Rolling back](https://omniflow-vpn.mintlify.site/operations/backup-restore.md#rolling-back).
* A migration is never edited after it has shipped in a release. A schema
  change always ships as a new migration, and its checksum in
  `database/migrations/atlas.sum` is generated by `atlas migrate hash`, never
  hand-edited.
* Upgrades apply **sequentially** through released versions — the supported
  upgrade window is exactly what CI's `migrations` job tests as a baseline:
  every prefix of the migration history to head. There is no supported path
  that skips applying an intermediate release's migrations; the `migrate`
  service applies whatever has not yet run, in order, every time the stack
  starts.
* Applying migrations twice is always safe: Atlas records what has already
  run and a re-apply is a no-op.

## Deprecation policy

A deprecation is announced before it is removed, and removal is always a
`CHANGELOG.md` entry — never a silent behavior change.

* **API.** A deprecated OpenAPI operation or field is marked `deprecated:
  true` in `api/openapi.yaml` and keeps working for at least one further
  minor release before it can be removed.
* **Environment variables.** A deprecated variable keeps working, its
  replacement is documented alongside it for at least one minor release, and
  its eventual removal is called out in `CHANGELOG.md` rather than causing a
  silent startup-behavior change.
* **Database behavior.** A behavior change ships additively first — a new
  column or table alongside the old one — rather than rewriting existing
  behavior in the same release that introduces its replacement. The
  transition itself, not just the endpoint, is a reviewed migration.
* **Integrations.** A Remnawave or payment-provider adapter supports the
  versions actually exercised by its contract tests, published in the
  [compatibility matrix](#compatibility-matrix) above. Dropping support for a
  version is a `CHANGELOG.md` entry, not a silent contract-test change.

## Related

> **[Deployment](https://omniflow-vpn.mintlify.site/operations/deployment.md)**
>
> Compose topology, volumes, and the images this matrix describes.

> **[Backup, restore, and disaster recovery](https://omniflow-vpn.mintlify.site/operations/backup-restore.md)**
>
> The step-by-step upgrade, rollback, and PostgreSQL major-version upgrade procedures.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.