Skip to content

feat: bundle XTM One in the default stack#574

Closed
azubiolo-filigran wants to merge 2 commits into
OpenCTI-Platform:masterfrom
azubiolo-filigran:feat/xtm-one-default
Closed

feat: bundle XTM One in the default stack#574
azubiolo-filigran wants to merge 2 commits into
OpenCTI-Platform:masterfrom
azubiolo-filigran:feat/xtm-one-default

Conversation

@azubiolo-filigran
Copy link
Copy Markdown
Member

Objective

Adds XTM One alongside OpenCTI in the default Docker stack so docker compose up -d brings the full XTM One + OpenCTI experience by default.

Refs XTM-One-Platform/xtm-one#1011. Companion PRs:

Changes

New services

  • pgsql-copilot (pgvector/pgvector:pg17) — Postgres+pgvector instance dedicated to XTM One, with its own credentials.
  • xtm-one — exposes the XTM One UI/API on ${XTM_ONE_PORT} (default 4000), reuses the existing redis and minio.
  • xtm-one-worker — async worker, depends on xtm-one being healthy.

Inter-platform wiring

  • New PLATFORM_REGISTRATION_TOKEN shared secret.
  • opencti service now receives XTM__XTM_ONE_URL / XTM__XTM_ONE_TOKEN.
  • xtm-one service receives OPENCTI_* federation env vars (URL, internal API URL, admin token).

Documentation

  • .env.sample gets a new XTM ONE block documenting admin credentials, image tag, dedicated Postgres credentials, S3 bucket, optional license, and the shared PLATFORM_REGISTRATION_TOKEN.

Scope

  • Only docker-compose.yml is touched. docker-compose.dev.yml and docker-compose.opensearch.yml are intentionally left alone for now and will be handled in follow-ups if needed.

Verification

The same configuration has been validated end-to-end inside the unified xtm-docker stack (companion PR FiligranHQ/xtm-docker#15): all services reach healthy, OpenCTI and XTM One register successfully via PLATFORM_REGISTRATION_TOKEN, and cross-platform features work as expected.

Notes

  • OPENCTI_ENCRYPTION_KEY must be a 32-byte base64 string (openssl rand -base64 32), not a UUID. The placeholder in .env.sample already hints at this; happy to add a more explicit comment if reviewers want.
  • The xtm-one yaml here is a convenience copy of what lives in FiligranHQ/xtm-docker (canonical source). Keeping it minimal so future syncs stay easy.

@github-actions
Copy link
Copy Markdown

Thank you for your contribution, but we need you to sign your commits. Please see https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

Adds XTM One alongside OpenCTI in the default compose:

- New pgsql-copilot service (pgvector/pgvector:pg17) for XTM One's
  vector store, with dedicated credentials.
- New xtm-one + xtm-one-worker services on port 4000, sharing the
  existing redis and minio.
- PLATFORM_REGISTRATION_TOKEN shared secret plumbed into the opencti
  service (XTM__XTM_ONE_URL / XTM__XTM_ONE_TOKEN) and into XTM One
  (OPENCTI_* federation env vars).
- .env.sample documents the new XTM ONE block.

Refs XTM-One-Platform/xtm-one#1011
- Set APP__BASE_URL=http://opencti:8080 so OpenCTI validates the JWT
  audience claim correctly (was using the external URL which doesn't
  match what XTM One puts in the token).
- Set BASE_URL=http://xtm-one:4000 so the JWT issuer claim points to
  the internal Docker hostname (OpenCTI fetches JWKS from {iss}/xtm/auth/jwks).
- Align XTM_ONE_ADMIN_EMAIL with OPENCTI_ADMIN_EMAIL so the JWT email
  claim resolves to an existing user in OpenCTI.
- Use lowercase 'changeme' for XTM_ONE_ADMIN_PASSWORD to match OpenCTI convention.
@azubiolo-filigran
Copy link
Copy Markdown
Member Author

azubiolo-filigran commented May 28, 2026

✅ Tested: OpenCTI + XTM One Docker Setup

Clean docker compose up -d from scratch — verified end-to-end.

Steps to reproduce

# 1. Clone repos side-by-side
git clone git@github.com:OpenCTI-Platform/docker.git opencti-docker
git clone git@github.com:XTM-One-Platform/xtm-one.git xtm-one
cd opencti-docker
git checkout feat/xtm-one-default

# 2. Create .env from sample (only 3 values MUST be changed)
cp .env.sample .env
sed -i "s/OPENCTI_ADMIN_TOKEN=ChangeMe_UUIDv4/OPENCTI_ADMIN_TOKEN=$(uuidgen)/" .env
sed -i "s|OPENCTI_ENCRYPTION_KEY=ChangeMeWithGeneratedBase64Key|OPENCTI_ENCRYPTION_KEY=$(openssl rand -base64 32)|" .env
sed -i "s/XTM_ONE_SECRET_KEY=ChangeMeWithGeneratedRandomString/XTM_ONE_SECRET_KEY=$(openssl rand -hex 32)/" .env

# 3. Build and start
docker compose up -d --build

# 4. Wait (~1-2 min) then verify
docker compose ps  # all services healthy

Note: The compose file has build: context: ../xtm-one directives for xtm-one and xtm-one-worker services. This requires the xtm-one repo cloned adjacent to this repo. Alternatively, remove the build: blocks and pull a pre-built image.

Credentials

Service URL Email Password
OpenCTI http://localhost:8080 admin@opencti.io changeme
XTM One http://localhost:4000 admin@opencti.io changeme

What was verified

  • All 23 services start healthy (infra, OpenCTI, connectors, workers, XTM One, XTM Composer)
  • OpenCTI auto-registers with XTM One (status=active, heartbeat flowing)
  • XTM One integration shows status=connected, base_url=http://opencti:8080
  • JWT auth from XTM One → OpenCTI GraphQL works (iss=http://xtm-one:4000, aud=http://opencti:8080)
  • JWKS endpoint reachable cross-container

Key fixes in this commit

  1. APP__BASE_URL=http://opencti:8080 — JWT audience validation must match the internal hostname
  2. BASE_URL=http://xtm-one:4000 — JWT issuer + JWKS fetch must use internal hostname
  3. XTM_ONE_ADMIN_EMAIL=admin@opencti.io — must match OpenCTI admin so JWT email resolves
  4. Build directivesbuild: context: ../xtm-one for local builds without registry access

Dependency

Requires XTM-One-Platform/xtm-one#1070 (fix/platform-registration-api-url-override) — adds OPENCTI_API_URL env var support so the registration stores the internal Docker URL in the integration config instead of the platform-reported external URL.

@azubiolo-filigran
Copy link
Copy Markdown
Member Author

azubiolo-filigran commented May 28, 2026

Updated: Build from local XTM One clone

The compose file now includes build: context: ../xtm-one directives for xtm-one and xtm-one-worker services. Updated steps:

# Clone both repos side-by-side
git clone git@github.com:OpenCTI-Platform/docker.git opencti-docker
git clone git@github.com:XTM-One-Platform/xtm-one.git xtm-one
cd opencti-docker
git checkout feat/xtm-one-default

# Create .env and start
cp .env.sample .env
sed -i "s/OPENCTI_ADMIN_TOKEN=ChangeMe_UUIDv4/OPENCTI_ADMIN_TOKEN=$(uuidgen)/" .env
sed -i "s|OPENCTI_ENCRYPTION_KEY=ChangeMeWithGeneratedBase64Key|OPENCTI_ENCRYPTION_KEY=$(openssl rand -base64 32)|" .env
sed -i "s/XTM_ONE_SECRET_KEY=ChangeMeWithGeneratedRandomString/XTM_ONE_SECRET_KEY=$(openssl rand -hex 32)/" .env

# Build and start
docker compose up -d --build

Note: Requires xtm-one repo cloned at ../xtm-one (adjacent to this repo). Alternatively, remove the build: blocks if you have access to the registry images.

@azubiolo-filigran
Copy link
Copy Markdown
Member Author

Closing in favor of a new PR from the upstream branch (same changes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant