TheHive Flow Security Maintenance#
6.0 One
Keeping a TheHive Flow deployment patched relies on updating each component independently.
Docker Compose deployment
This page describes the Docker Compose deployment of TheHive Flow. On a Kubernetes deployment, see Configuration and operations on Kubernetes.
Component update independence#
Each component can be updated independently, with the constraints noted below. The detailed procedures live in Maintain TheHive Flow.
| Component | Update path | Constraint |
|---|---|---|
| TheHive Flow | Edit ORCHESTRATOR_VERSION in .env, then run ./scripts/update.sh |
Forward-compatible migrations are the intended contract but aren't yet enforced: verify schema compatibility before rolling back across a migration boundary |
| Nginx | Edit the image tag in docker-compose.yml, then run docker compose up -d nginx |
No schema and no state, so fully independent |
| PostgreSQL, minor patch | Edit the image tag in docker-compose.yml, then run docker compose up -d postgresql |
Data is preserved in the named volume. Minor patches are safe |
| PostgreSQL, major version | pg_upgrade or a dump and restore procedure |
Breaking change requiring a coordinated procedure outside the stack |
| Temporal, minor patch | Edit the image tag in docker-compose.yml, then run docker compose up -d temporal |
Verify schema compatibility before upgrading |
| Temporal, minor version with schema change | ./scripts/upgrade-temporal.sh, a dry run by default, with --apply to execute |
Runs schema migrations before recreating the server, and steps automatically through every intermediate minor version recorded in the bundled version manifest |
| SeaweedFS object storage | Edit the image tag and digest on both s3-store and init-s3-store in docker-compose.yml, then run docker compose up -d init-s3-store |
Both services must be bumped together: they deliberately share one image, so no second pin can drift. Data is preserved in the orchestrator-s3-data volume. Stop the orchestrator service first, because recreating the store under a running instance surfaces as workflow steps failing on blob reads |
Version coupling between Temporal and TheHive Flow#
The Temporal Server version must be compatible with the Temporal SDK version embedded in TheHive Flow binary. Check TheHive Flow release notes before bumping Temporal Server. Upgrading Temporal independently is safe as long as the server stays within the SDK supported range, typically within two minor versions.
Respond to a CVE#
CVE in TheHive Flow binary#
Edit .env and set ORCHESTRATOR_VERSION to the patched tag, then pull and redeploy:
./scripts/update.sh
Downtime is under 30 seconds, with no database changes required.
CVE in nginx#
Edit docker-compose.yml to bump the nginx image tag and digest, then redeploy nginx only:
docker compose up -d nginx
The other services see no downtime. The nginx reload is graceful: in-flight requests complete before the old worker exits.
CVE in the object storage#
Edit docker-compose.yml to bump the tag and digest on both s3-store and init-s3-store, which deliberately share one image reference. Then stop the orchestrator service, recreate the store, and provision it again:
docker compose stop orchestrator
docker compose up -d init-s3-store
docker compose up -d orchestrator
Blobs survive: they live in the orchestrator-s3-data volume, not in the image. Downtime lasts as long as the store restart plus provisioning. The init-s3-store container asserts that the identity and the bucket exist before exiting 0, so a failed provisioning shows up as a non-zero exit rather than as an orchestrator service that crash-loops later:
docker compose logs --tail=50 init-s3-store
CVE in PostgreSQL#
For a minor patch, edit docker-compose.yml to bump the PostgreSQL image tag and digest, then restart:
docker compose up -d postgresql
The orchestrator-postgres-data volume is preserved. Expect 10 to 30 seconds of downtime while TheHive Flow and Temporal reconnect.
CVE in Temporal#
For a minor patch without a schema change, edit docker-compose.yml to bump the Temporal image tag and digest, then restart:
docker compose up -d temporal
In-flight workflow tasks are retried automatically after the restart.
CVE in a base OS image#
The PostgreSQL, Temporal, and nginx images are rebuilt by their maintainers with OS patches. When a new digest is published for the same tag, update docker-compose.yml with the new digest and redeploy the service.
Version pinning policy#
Every image in docker-compose.yml is pinned by both tag and immutable digest, in the form image: name:tag@sha256:…. The latest tag is never used.
ORCHESTRATOR_VERSIONin.envis the only operator-tunable pin. It must always be a released tag, neverlatestor a branch name.- The other image versions are maintained in the deployment bundle by StrangeBee. Operators update them by deploying a refreshed bundle, not by editing image references directly.
Verify that no image is missing its digest:
grep 'image:' docker-compose.yml | grep -v '@sha256:'
The only expected output is the orchestrator image, which is pinned by tag through ORCHESTRATOR_VERSION.
TLS certificate expiry#
Self-signed certificates generated by init.sh are valid for 365 days. Monitor the expiry:
openssl x509 -in ./nginx/certs/server.crt -noout -dates
Renew before expiry: see TLS certificate renewal.
For production deployments, use certificates signed by a trusted certificate authority (CA) and integrate with your certificate lifecycle management tooling, such as certbot or Vault PKI.
Audit checklist#
Run the following checks periodically. Monthly is recommended.
- All image digests in
docker-compose.ymlmatch the current published digests ORCHESTRATOR_VERSIONis set to the latest stable release- The
nginx/certs/server.crtexpiry is more than 60 days away - The
.envpermissions are 600:ls -la .env - The
orchestrator/secret/thehive-api-keypermissions are 644 - No secrets appear in the
docker compose logsoutput - The Temporal namespace retention matches
modules.runs.retention:temporal operator namespace describe -n default - Docker log rotation is configured:
docker inspect orchestrator | jq '.[0].HostConfig.LogConfig' - Backup files exist and are recent:
ls -lht ./backups/ | head -5