TheHive Flow Security Maintenance#
6.0 One
Keeping a TheHive Flow deployment patched relies on the image versions StrangeBee pins in versions.env, at the root of the StrangeBee Docker Compose repository, and on the upgrade route of each component.
Docker Compose deployment
The settings and procedures below apply to the Docker Compose deployment of TheHive Flow. On a Kubernetes deployment, see Configuration and operations on Kubernetes instead.
Component upgrade route#
Every image of the stack is pinned by tag in versions.env. StrangeBee moves the pins, and the upgrade procedure applies them: git pull, then bash ./scripts/init.sh to copy the new versions into .env, then docker compose up -d. The constraints below decide what else the upgrade of a component involves.
| Component | Variable in versions.env |
Constraint |
|---|---|---|
| TheHive Flow | thehive_flow_image_version |
Database migrations run at startup and are forward-only. Rolling back doesn't revert the schema: undoing a schema change requires restoring the backup taken before the upgrade |
| Nginx | nginx_image_version |
No schema and no state, so fully independent |
| PostgreSQL, minor or patch version | postgresql_image_version |
Data is preserved in ./postgresql/data. Minor and patch versions are safe |
| PostgreSQL, major version | postgresql_image_version |
Breaking change requiring pg_upgrade or a dump and restore procedure outside the stack, before the pin moves |
| Temporal, patch version | temporal_image_version |
The temporalio/server and temporalio/admin-tools images share the pin and always move together |
| Temporal, minor version | temporal_image_version |
Requires the Temporal schema upgrade before the new server starts, one minor version at a time |
| SeaweedFS object storage | seaweedfs_image_version |
The s3-store and init-s3-store services share the pin. Data is preserved in ./s3-store/data. Stop the thehive-flow service before recreating the store, because recreating it under a running instance makes workflow steps fail 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 moving the Temporal pin yourself. 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#
The patched version of an image usually reaches versions.env with the next release: run the upgrade procedure to apply it. To apply a patch before StrangeBee publishes the pin, move the pin yourself in versions.env, run bash ./scripts/init.sh to copy it into .env, then recreate the affected service as described below. Without a custom certificate, each run of init.sh also generates a new self-signed certificate: see TLS certificate renewal. The next git pull then reports a conflict on versions.env: discard your local change with git checkout -- ../versions.env before pulling, since the upstream pin is at least as recent.
CVE in TheHive Flow binary#
Move thehive_flow_image_version, run init.sh, then recreate the service:
docker compose up -d thehive-flow
Downtime is brief. Database migrations, if the new version carries any, run at startup.
CVE in nginx#
Move nginx_image_version, run init.sh, then recreate nginx only:
docker compose up -d nginx
Docker recreates the nginx container, which is the only entry point of the stack. TheHive requests and webhook calls are refused for a few seconds, and long-running requests still in progress are cut. The other services keep running.
CVE in the object storage#
Move seaweedfs_image_version, run init.sh, then stop the thehive-flow service, recreate the store, and provision it again:
docker compose stop thehive-flow
docker compose up -d init-s3-store
docker compose up -d thehive-flow
Blobs survive: they live in ./s3-store/data, 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. A failed provisioning therefore shows up as a non-zero exit rather than as a thehive-flow service that crash-loops later. To check the result, read the container logs:
docker compose logs --tail=50 init-s3-store
CVE in PostgreSQL#
For a minor or patch version, move postgresql_image_version, run init.sh, then recreate the service:
docker compose up -d postgresql
The ./postgresql/data directory is preserved. Expect a brief downtime while TheHive Flow and Temporal reconnect.
CVE in Temporal#
For a patch version, move temporal_image_version, run init.sh, then recreate the server:
docker compose up -d temporal
Temporal retries in-flight workflow tasks automatically after the restart. For a new minor version, follow the Temporal schema upgrade first.
CVE in a base OS image#
The maintainers of the PostgreSQL, Temporal, nginx, and SeaweedFS images rebuild them with OS patches under the same tag. Because the pins are tags, pulling the image again fetches the rebuilt one:
docker compose pull <service>
docker compose up -d <service>
Version pinning policy#
Every image of the stack is pinned by tag in versions.env, and init.sh copies the pins into .env, which docker-compose.yml reads. The latest tag is never used.
- StrangeBee maintains the pins. Operators move them by pulling the repository, not by editing image references in
docker-compose.yml. - The image of TheHive Flow follows TheHive releases: TheHive and TheHive Flow are released together and carry the same version number.
- A pin moved by hand, as described in Respond to a CVE, is a temporary measure until the next release.
Check that the running stack matches the pins:
grep _image_version ../versions.env
grep _image_version .env
docker compose images
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 the certificate before it expires, as described in 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.
- The pins in
.envmatch the ones inversions.env, and the repository clone is up to date with the latest release - The
nginx/certs/server.crtexpiry is more than 60 days away - The
.envpermissions are 600:ls -la .env - The
thehive-flow/secret/thehive-api-keyandnginx/certs/server.keypermissions are 600, andbash ./scripts/check_permissions.shreports no deviation nginx_thehive_addressesin.envlists only the addresses TheHive currently calls from, and the40-thehive-allow.shlines ofdocker compose logs --no-log-prefix nginxshow what nginx allows and skips- No secrets appear in the
docker compose logsoutput - The Temporal namespace retention matches
modules.runs.retention:docker compose --profile admin run --rm temporal-admin temporal operator namespace describe -n default --address temporal:7233 - Docker log rotation is configured:
docker inspect thehive-flow | jq '.[0].HostConfig.LogConfig' - Backup folders exist and are recent:
ls -lt /opt/backups/thehive-flow | head -5