Skip to content

Upgrade

This page covers the upgrade and rollback procedures for a self-hosted XTM One instance. Filigran SaaS instances are upgraded by Filigran.

Procedure

  1. Read the release notes.
  2. Apply the update based on your deployment option:

Pre-built images (Option B):

docker compose pull
docker compose up -d

Source-based (Option A):

git fetch --tags
git checkout <new-version-tag>
docker compose build --pull
docker compose up -d

Migrations run automatically on startup. Wait for /api/health/ready to return 200 before verifying.

Image tags follow the format <major>.<YYMMDD>.<patch> and are listed on Docker Hub.

Deprecated environment variables

Environment variables renamed by a release keep working under their old name for a while, so an upgrade does not silently change what your deployment does. While an old name is in use, XTM One logs a warning naming the replacement. Rename them in your compose files, Helm values and CI secrets before the removal date.

Old name New name Read until Notes
OPENGRC_API_URL OPENCRQ_API_URL 2026-12-31 Renamed with the OpenGRC -> OpenCRQ product rename. When both are set, OPENCRQ_API_URL wins. See Network reachability.

Version notes

Code interpreter sandbox workspace

From this release the code interpreter keeps a sandbox workspace per conversation and per assignment run. Nothing has to be done on upgrade: a migration adds two tables (sandbox_workspaces, sandbox_workspace_files), and a cell that worked before works unchanged.

  • Storage. No volume to provision: workspace files live in the platform bucket under sandbox-workspaces/, their manifest in PostgreSQL, so every backend replica and worker sees the same workspaces. Budget the bucket for the workspaces in use (2 GiB at most each by default, usually far less) and, with the local sandbox, the backend pods' temporary directory for the per-process cache (CODE_INTERPRETER_WORKSPACE_CACHE_MB, 2 GiB by default). See Storage sizing.
  • Clean-up. A sweep runs in the worker every hour (once for the whole install): it deletes the workspaces of archived or deleted conversations and deleted runs, the workspaces unused for CODE_INTERPRETER_WORKSPACE_IDLE_TTL_HOURS (7 days by default), and objects left under a prefix no workspace owns. Archiving or deleting a conversation from the chat also deletes its workspace at once.
  • Kernels. session=true runs a long-lived kernel: a child process of the backend on the local sandbox, a container of its own on OpenSandbox (kept for CODE_INTERPRETER_KERNEL_IDLE_SECONDS, 15 minutes by default, and found again from any replica).
  • Packages. Installs stay off until you set CODE_INTERPRETER_PACKAGE_ALLOWLIST (and, for a mirror, CODE_INTERPRETER_PACKAGE_INDEX_URL).
  • Graceful stops. During a deployment, a chat turn whose worker is stopping now ends at its next step once less than a minute (or half of GRACEFUL_TIMEOUT) of the grace is left, its completed tool calls kept for "Continue where you left off". A turn that would have finished within the grace is not affected.
  • Turning it off. CODE_INTERPRETER_WORKSPACE_ENABLED=false restores the stateless code interpreter.

Platform registration token (Docker Compose)

This note applies when PLATFORM_REGISTRATION_TOKEN is not set in your .env, or is set to xtm-default-registration-token: Docker Compose then runs XTM One with that published default, which authenticates nobody. After upgrading such a deployment:

  • The OpenCTI, OpenAEV and OpenCRQ platforms already registered keep their heartbeat, but the published default can no longer register a new platform, change the URL of a registered one, rename one or unregister one: a registered platform's URL is trusted to sign XTM One users in, and its name is what the agents bound to it read. Nor does its heartbeat change the intents and business vertical a platform declares (those of an upgraded platform are recorded once you set your own token), or replace a platform's license with anything but its renewal.
  • The XTM One license certificate is no longer sent to the connected platforms, so a platform whose Enterprise Edition comes from your XTM One license (a sub-license) cannot prove it. The registration answer says why: xtm_license_withheld_reason: registration_token_published_default.

To leave the published default:

  1. Generate a token: python -c "import secrets; print(secrets.token_urlsafe(32))".
  2. Set it as PLATFORM_REGISTRATION_TOKEN in the .env of XTM One, and set the same value as the registration token of every connected OpenCTI, OpenAEV and OpenCRQ platform. A platform still presenting the old value is refused.
  3. Restart XTM One (docker compose up -d) and the platforms.
  4. Check the security audit (Settings → Security, or GET /api/v1/security-audit): the platform registration token finding now reads pass. Then review the registered platforms and purge any you do not recognise: earlier releases let anyone holding the published default register one, and changing the token does not end the trust a registration carries. The integration catalog in Settings lists the OpenCTI, OpenAEV and OpenCRQ registrations; the security audit names any registration under another identifier with its id, which DELETE /api/v1/platform/registrations/{id}/purge removes.

Rollback

Warning

Migrations run automatically on startup and may alter the database schema. Once a migration has run, the previous application version may not work against the new schema. Rollback requires restoring the database and object storage from the same pre-upgrade recovery point.

  1. docker compose down
  2. Restore the database from the pre-upgrade backup.
  3. Restore Silo/S3 to the same recovery point.
  4. Revert image tags to the previous version.
  5. docker compose up -d