Skip to main content

Upgrade to Enterprise

Activating the Enterprise edition does not reinstall CentralOps. You swap the Community images for the Enterprise images (the same product, with the paid modules compiled in) and provide your license. Without a valid license, the Enterprise features stay blocked (the image keeps running as Community) — so the upgrade and the downgrade are reversible.

Changing edition ≠ changing version

This page is about changing edition (Community → Enterprise). To update from one version to a newer one (e.g. 1.1.01.2.0), see Upgrade to a newer version.

What you will need

The license comes as two files, and both are required:

FileWhat it isWhere it goes
segark-pipeline-license-<kid>.jwtThe signed (EdDSA) license token.CENTRALOPS_LICENSE_TOKEN (or the Settings → License screen).
key.prod.pemThe public key the product uses to verify the token offline.A directory pointed to by CENTRALOPS_LICENSE_KEYS_DIR.
Without the public key, the license won't activate

The token alone is not enough: without key.prod.pem in the keyring, the product can't verify the signature and answers unknown key id: 'key.prod' — staying on Community by design. Always download both files.

Overview

segark.com portal Registry Run
┌───────────────────┐ ┌────────────────┐ ┌──────────────────────────┐
│ License page: │ ───▶ │ docker login → │ ───▶ │ start the EE images with │
│ token + key.pem │ │ pull EE images │ │ token + mounted keyring │
└───────────────────┘ └────────────────┘ └───────────┬──────────────┘

edition=enterprise ✅

1. Download the license from the portal

  1. Subscribe to a plan on the portal (segark.com). The license is issued to your account.
  2. Sign in to the portal and open the License page.
  3. Download both files:
    • Download token (.jwt) — the signed license token.
    • Download key (key.prod.pem) — the public keyring key.

The page itself shows the "How to activate" summary with these steps.

2. Authenticate to the registry

The Enterprise images are private on the GitHub Container Registry: ghcr.io/segark-oficial/centralops-ee (API/workers) and ghcr.io/segark-oficial/centralops-ee-frontend (frontend). Use the pull credential provided with your subscription (portal install bundle, or support@segark.com):

echo "<credential password>" | \
docker login ghcr.io -u "<credential username>" --password-stdin

The token goes through stdin so it never lands in your shell history.

Security

The pull credential only controls the image download. The real feature activation is the license, verified offline inside the product.

3. Start with the Enterprise images

EE tags follow the Core version: vX.Y.Z-ee tracks the release (e.g. v1.0.1-ee) and vX.Y.Z-ee.<sha> is immutable (e.g. v1.0.1-ee.2e8917dprefer this one in production).

Docker Compose

Put the public key next to the compose files and configure compose/.env:

mkdir -p compose/license-keys
cp ~/Downloads/key.prod.pem compose/license-keys/

In compose/.env, add:

CENTRALOPS_LICENSE_TOKEN=<contents of the .jwt file>
LICENSE_KEYS_DIR=./license-keys
CENTRALOPS_EE_IMAGE=ghcr.io/segark-oficial/centralops-ee:v1.0.1-ee
CENTRALOPS_WEB_EE_IMAGE=ghcr.io/segark-oficial/centralops-ee-frontend:v1.0.1-ee

And start CE + the Enterprise overlay (from the project root):

docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml pull
docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml up -d
The Enterprise overlay is not "sticky"

Compose only applies docker-compose.ee.yml when it is passed with -f — and that holds for every future command. A docker compose up -d (or pull, or any recreation) with only the base file silently downgrades the stack to Community: the image goes back to CE, the keyring mount disappears and the next activation fails with unknown key id. To make the overlay permanent, set in compose/.env:

COMPOSE_FILE=docker-compose.yml:docker-compose.ee.yml

With that, a plain docker compose up -d (run from inside compose/, no -f) already applies the overlay, and day-2 commands won't downgrade the stack.

Prefer activating through the UI?

With key.prod.pem mounted (the LICENSE_KEYS_DIR above), you can leave CENTRALOPS_LICENSE_TOKEN out and paste the token on the product's Settings → License screen as an administrator. The license is stored (encrypted) in the database and survives restarts.

The License screen also exists — and accepts the paste — on a Community stack brought up without the overlay; in that case the container's keyring is empty and the activation fails with exactly unknown key id: 'key.prod'. Before pasting, confirm the key is visible inside the container:

docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml \
exec centralops ls /licensing
# key.prod.pem

Kubernetes (Helm)

Create the image pull secret (the chart uses ghcr-secret by default) and upgrade pointing at the images, token and keyring:

kubectl -n centralops create secret docker-registry ghcr-secret \
--docker-server=ghcr.io \
--docker-username="<credential username>" \
--docker-password="<credential password>"

helm upgrade centralops kubernetes/helm/centralops -n centralops \
--set image.repository=ghcr.io/segark-oficial/centralops-ee \
--set image.tag=v1.0.1-ee \
--set frontendImage.repository=ghcr.io/segark-oficial/centralops-ee-frontend \
--set frontendImage.tag=v1.0.1-ee \
--set secrets.licenseToken="<contents of the .jwt file>" \
--set-file "secrets.licenseKeyring.key\.prod\.pem=./key.prod.pem" \
-f values.override.yaml

The chart mounts the keyring on every pod and sets CENTRALOPS_LICENSE_KEYS_DIR automatically. For GitOps/ExternalSecrets, use secrets.existingSecret and secrets.existingLicenseKeyring instead of the inline values.

4. Verify

At boot, the API logs the resolved edition:

docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml \
logs centralops | grep edition=
# edition=enterprise plan=mssp features=3

You can also check it in the UI, under Settings → License (shows the edition, plan and active features).

If you see edition=community, the license wasn't found or couldn't be verified:

  • unknown key id: 'key.prod' — the keyring the container sees is empty or does not contain key.prod.pem. Follow the walkthrough below.
  • Missing/expired token — check CENTRALOPS_LICENSE_TOKEN (or re-activate through the License screen) and the validity on the portal.

An Enterprise install whose license does not cover a feature (a plan that doesn't include it, a missing license, or one expired beyond the grace period) refuses the corresponding action with the license_required state — for example, when syncing a partner's tenants. In that case the fix is not the keyring: check the plan and the validity under Settings → License or on the portal.

Fixing unknown key id

The dominant cause is an empty keyring inside the container — usually because the stack was brought up (or recreated) without the Enterprise overlay. The key.prod.pem can be perfectly fine on the host and still never reach the container. Diagnose from the inside out:

1. Image and mount — is the API container running the EE image, with the /licensing mount?

docker inspect --format '{{.Config.Image}} {{json .Mounts}}' \
$(docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml ps -q centralops)

2. What the process sees — the variable and the directory inside the container:

docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml \
exec centralops sh -c 'echo $CENTRALOPS_LICENSE_KEYS_DIR; ls -la /licensing'

3. Permissions — the API runs as uid 10001: the .pem must be readable by it (file 0644, directory 0755). A key.prod.pem with 0600 root:root is silently ignored.

4. Keyring logs — the boot logs what was (or wasn't) loaded:

docker compose -f compose/docker-compose.yml -f compose/docker-compose.ee.yml \
logs centralops | grep -iE 'skipping|license keyring'

If the mount or the variable is missing, recreate the containers with both -f files (up -d) — docker compose restart does not apply new mounts or environment variables. With the keyring fixed, paste the token again on the License screen without restarting anything: the keyring is re-read on every activation (and on every periodic refresh). On Helm, check secrets.licenseKeyring and the /licensing mount on the pods.

Downgrade

Go back to the Community images (or remove CENTRALOPS_LICENSE_TOKEN) and start again — the platform falls back to Community by design, without losing data.

Need help?

Talk to support@segark.com.