OpenRelik
Overview
OpenRelik is an open source platform for collaborative digital forensics and incident response. Investigators create a folder for a case, upload the evidence they have collected, and run processing workflows over it from the browser. Processing runs on a pool of independent Celery workers. A long job, such as building a Plaso super timeline, runs in the background while the team carries on working, and the results land back in the same case folder for everyone to review.
This guide covers deploying and configuring OpenRelik on Ubuntu 24.04 using the SecureAnyCloud images on the Azure Marketplace. The image ships the free and open source, Apache-2.0 licensed OpenRelik server, web UI, mediator, metrics exporter and four processing workers. They run the officially supported way, as the upstream containers pinned by image digest. All eleven containers are captured into the VM, so your instance starts without pulling several gigabytes.
Because this platform holds evidence, nothing ships with a known secret. The PostgreSQL password, the session secret, the JWT signing key and the administrator password are all generated for each VM on first boot, before the application is reachable. Google single sign-on ships deliberately unconfigured and closed rather than open.
OpenRelik is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by OpenRelik or Google LLC. It ships the free and open source Apache-2.0 licensed software, unmodified.
What you get:
- OpenRelik server 0.7.0 (the Apache-2.0 licensed FastAPI backend), pinned by image digest
- OpenRelik web UI 0.7.0 (the Apache-2.0 licensed Vue application), pinned by image digest
- The OpenRelik mediator and Celery metrics exporter, pinned by image digest
- Four processing workers: Plaso (super timelining), strings, grep and archive/disk-image extraction
- PostgreSQL 17 for application data, and Valkey 8 (BSD-3-Clause) as the Celery broker and result backend
- Prometheus for task queue metrics
- Docker Engine, with the backend and UI published to the loopback interface only, fronted by nginx on port
80at/(UI),/api/(REST API) and/auth/(local sign-in) openrelik.service,openrelik-firstboot.service,openrelik-postboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A per-instance PostgreSQL password, session secret, JWT signing key and administrator password, generated per VM on first boot and never baked into the image
- No default login, no shipped OAuth client secret, and an empty database on first boot
- Ubuntu 24.04 LTS with the latest security patches applied at build time
- The Azure Linux Agent for cloud integration and SSH key injection
- 24/7 SecureAnyCloud support with a guaranteed 24 hour response SLA
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the OpenRelik listing on the Azure Marketplace
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) runs the whole stack and is the size this image is validated on. For real casework, and especially for Plaso super timelining over large disk images, use Standard_D4s_v5 or larger and attach a data disk for evidence.
Configure the NSG to allow inbound 22/tcp from your management network and 80/tcp for the web UI from the networks your analysts use.
Deploy from the Azure Portal
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OpenRelik by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Then select Review + create and Create.
Deploy from the Azure CLI
RG="openrelik-prod"; LOCATION="eastus"; VM_NAME="openrelik-01" IMAGE_URN="sac1647283583153:openrelik-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name openrelik-vnet --address-prefix 10.100.0.0/16 --subnet-name openrelik-subnet --subnet-prefix 10.100.1.0/24 az network nsg create -g "$RG" --name openrelik-nsg az network nsg rule create -g "$RG" --nsg-name openrelik-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name openrelik-nsg --name allow-http --priority 110 \
--source-address-prefixes "<your-analyst-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:openrelik-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name openrelik-vnet --subnet openrelik-subnet --nsg openrelik-nsg --public-ip-sku StandardConnect to your VM
Connect as azureuser, using the public IP address of your VM:
ssh azureuser@<vm-ip>Confirm the services are running
The platform runs as eleven containers under one openrelik.service, fronted by nginx. Confirm that the services are active and list the containers:
sudo systemctl is-active docker openrelik nginx
sudo docker compose --env-file /opt/openrelik/config.env -f /opt/openrelik/docker-compose.yml psThe services report active, and all eleven containers report running.
The backend (127.0.0.1:8710) and the web UI (127.0.0.1:8711) are bound only to the loopback interface. PostgreSQL, Valkey, Prometheus, the mediator, the metrics exporter and the four Celery workers publish no host port at all and are reachable only on the private container network. nginx on :80 is the single public front door.
Verify the listener isolation
Because this platform holds evidence, only the intended ports should face the network. List every listening TCP socket on the VM:
sudo ss -tlnOnly 22 (SSH) and 80 (nginx) are bound to a routable address. Everything else is on 127.0.0.1 or on the private container bridge.
An automated check asserts this at build time. The check first proves itself against a deliberate public bind before it trusts its own verdict.
Read the per-instance credentials
On first boot, before any container started, this VM generated a unique PostgreSQL password, session secret and JWT signing key. It then seeded an administrator account with a random password. Read them:
sudo cat /root/openrelik-credentials.txtThe file (mode 0600 root:root) holds ADMIN_USERNAME and ADMIN_PASSWORD, which are the account you sign in to the web UI with, plus WEB_URL and API_URL.
None of these ship in the image. Every value is unique to this VM, so no two instances share a credential and there is no default login to change.
Verify the security model
The web UI loads without authentication, but every API endpoint that reads or writes case data requires a valid session. Confirm that an unauthenticated write is rejected, that a forged token is rejected, and that the per-instance administrator credential authenticates the same call:
sudo /usr/local/sbin/openrelik-roundtrip.shThe bundled prover reports OK after it checks four things:
- A complete, well-formed folder creation request is rejected with
401when unauthenticated, and again when sent with a forged signing key. - The byte-identical request then succeeds with
201using a real session from the per-instance administrator. - A wrong password and an empty password are both rejected.
The positive control is the important half. It proves that the rejections were authentication failures and not a malformed request.
Prove a workflow really runs
Status codes do not prove that a forensics platform works. The image ships an end-to-end prover that does the following:
- Creates a real case folder and uploads a real evidence file that contains a randomly generated marker.
- Runs the real strings workflow on a real Celery worker and waits for it to finish.
- Downloads the artefact the worker produced and asserts that the marker is inside it.
Run it:
sudo /usr/local/sbin/openrelik-workflow-proof.shIt reports WORKFLOW_OK with the folder, evidence, workflow and artefact identifiers, and it tidies up the case it created.
Open the web UI and sign in
Browse to http://<vm-ip>/ to reach OpenRelik. Sign in with the ADMIN_USERNAME and ADMIN_PASSWORD from Step 6.
There is no self-registration and no default account. You create additional users from the command line in Step 14.
Create a case folder
After you sign in, you land on the folder list, which is your case list. Choose New folder and name it for the incident you are working on.
Folders are the unit of collaboration in OpenRelik. Evidence, workflows and results all live in a folder, and you can share a folder with colleagues from the Share button.
Upload evidence and run a workflow
Open the case folder and choose Upload files to add the artefacts you collected. Then choose Create workflow, select the uploaded file, and add a task such as Strings, Grep, Extract files from archives or Plaso Log2Timeline.
Run the workflow, and OpenRelik dispatches the task to the matching Celery worker. Workflows are named Untitled workflow until you rename them.
Review the results
When the task completes, it writes its output back into the case as a new file. Open the file to read the artefact the worker produced directly in the browser, or choose Download to save it locally.
In the example case, the strings worker processed the collected artefact and produced a byte-offset-indexed listing. The suspicious indicators are immediately readable in it: a staging URL, a persistence registry key, a command and control address, and an encoded PowerShell invocation.
Call the API from your own machine
Everything the UI does is backed by the REST API. Sign in to obtain a session cookie and a CSRF token, then call an endpoint. Run this on the VM:
COOKIES=$(mktemp)
ADMIN_USERNAME=$(sudo grep '^ADMIN_USERNAME=' /root/openrelik-credentials.txt | cut -d= -f2-)
ADMIN_PASSWORD=$(sudo grep '^ADMIN_PASSWORD=' /root/openrelik-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -c "$COOKIES" -X POST http://localhost/auth/local \
--data-urlencode "username=$ADMIN_USERNAME" --data-urlencode "password=$ADMIN_PASSWORD"
CSRF=$(awk '/csrf_token/{print $7}' "$COOKIES" | tail -1)
curl -s -b "$COOKIES" -H "X-CSRF-Token: $CSRF" http://localhost/api/v1/folders/ | head -c 400 echo
curl -s -b "$COOKIES" -H "X-CSRF-Token: $CSRF" http://localhost/api/v1/taskqueue/tasks/registered | head -c 400 rm -f "$COOKIES"The first call lists your case folders. The second lists every processing task registered on the queue. From your own workstation, use http://<vm-ip>/ in place of http://localhost/.
Manage user accounts
Manage accounts with the server's admin.py utility. For example, add an analyst:
cd /opt/openrelik
sudo docker compose --env-file config.env -f docker-compose.yml exec openrelik-server \
python admin.py create-user analyst --password '<choose-a-strong-password>'Add --admin to grant administrator rights. Change the seeded administrator password the same way, with python admin.py change-password admin.
Every new user automatically joins the built-in Everyone group. You control folder sharing for each folder from the UI.
Enable Google single sign-on (optional)
This image ships with local authentication only. Google single sign-on is deliberately disabled and closed: client_id and client_secret are empty, the allowlist is empty and public_access is false. SecureAnyCloud never ships an OAuth client secret.
To enable it, create an OAuth client in your own Google Cloud project. Then edit /opt/openrelik/config/settings.toml and set client_id, client_secret, and either workspace_domain or an explicit allowlist of permitted email addresses. Add google to OPENRELIK_AUTH_METHODS on the openrelik-ui service in /opt/openrelik/docker-compose.yml, then restart:
sudo systemctl restart openrelikLeave public_access = false unless you intend to let anyone with a Google account sign in.
Scale the worker pool
The image ships a worker concurrency tuned to fit a 2 vCPU appliance. On a larger VM, you can raise it.
Edit /opt/openrelik/docker-compose.yml and increase --concurrency on the worker services (openrelik-worker-strings, openrelik-worker-grep, openrelik-worker-plaso, openrelik-worker-extraction). Then restart the stack with sudo systemctl restart openrelik.
Plaso and extraction are the memory-hungry workers. Raise those last, and watch memory as you do.
Server components
Components, with version and detail:
Backend OpenRelik server 0.7.0 (FastAPI, pinned by image digest)
Web UI OpenRelik UI 0.7.0 (Vue, pinned by image digest)
Orchestration bridge OpenRelik mediator 0.7.0
Processing workers Plaso 0.5.0, strings 0.3.0, grep 0.2.0, extraction 0.5.0
Application database PostgreSQL 17 (created empty on first boot)
Task broker Valkey 8 (BSD-3-Clause), Celery broker and result backend
Metrics OpenRelik metrics exporter 0.7.0 with Prometheus v3
Front door nginx on :80 routing / to the UI, /api/ and /auth/ to the backend
Evidence store /opt/openrelik/data/artifacts
Per-instance secrets DB password, session secret and JWT key, generated on first boot into /opt/openrelik/config.env and /opt/openrelik/config/settings.toml
Admin account Per-instance random password, seeded on first boot into /root/openrelik-credentials.txt
Operating system Ubuntu 24.04 LTS (patched at build)
License Apache-2.0 (OpenRelik)
Manage the service
Check the service status and show the latest backend logs:
sudo systemctl status openrelik --no-pager | head -12 sudo docker compose --env-file /opt/openrelik/config.env -f /opt/openrelik/docker-compose.yml logs --tail 40 openrelik-serverRestart the whole stack with sudo systemctl restart openrelik. Follow a worker live with ... logs -f openrelik-worker-plaso. The configuration is in /opt/openrelik/config.env, /opt/openrelik/config/settings.toml and /opt/openrelik/docker-compose.yml. After you change the configuration, restart the service to apply it.
Use your own domain and HTTPS (production)
The image serves the UI and API over plain HTTP on port 80, which is convenient behind a load balancer or on a private network. Because this platform carries evidence and credentials, terminate TLS in front of it for any real deployment:
- Front the VM with Azure Application Gateway, a load balancer with a managed certificate, or a CDN, and forward to nginx on port
80. - Or install your own certificate. Add a TLS
serverblock to/etc/nginx/sites-available/openrelikthat references your certificate and key, open443/tcpon the NSG, then runsudo systemctl reload nginx. - Point a DNS name you control at the VM public IP. The UI and backend read their public address at first boot from the resolved public IP, so use a stable public IP. Otherwise, update
OPENRELIK_SERVER_URLin/opt/openrelik/config.env, andapi_server_url/ui_server_url/allowed_originsin/opt/openrelik/config/settings.toml, to your domain and restart.
Security recommendations
- Restrict the NSG. Allow TCP 80 only from your analysts' networks and TCP 22 only from your management network. Evidence should never be reachable from the open internet.
- Terminate TLS in front of the app (Step 19) so that credentials, evidence and results are encrypted in transit.
- Rotate the seeded administrator password after your first sign-in, and create a named account for each analyst (Step 14) so that actions are attributable.
- Keep single sign-on closed unless you configure it deliberately, and never set
public_access = truewithout an allowlist or workspace domain. - Keep the supporting services private. PostgreSQL, Valkey, Prometheus and the workers publish no host port. Keep it that way, and never expose the container ports directly.
- Put evidence on a dedicated encrypted disk for real casework, and back up
/opt/openrelik/dataalongside the PostgreSQL volume. - Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Support and licensing
OpenRelik and its workers are distributed under the Apache License 2.0. This SecureAnyCloud image bundles the unmodified official open source releases.
SecureAnyCloud provides the packaging, the single nginx front door, the per-instance secret and administrator generation, the listener isolation checks, the paired deployment guide, and 24/7 support with a guaranteed 24 hour response SLA.
Valkey is used in place of Redis as the Celery broker, so the image carries only permissively licensed components. OpenRelik is an independent open source project, and this image is not affiliated with or endorsed by it.
Deploy on Azure
Launch OpenRelik on Ubuntu 24.04 LTS by SecureAnyCloud from the Azure Marketplace, and follow this guide to a working digital forensics and incident response platform in minutes.
Deploy on Azure
Launch OpenRelik on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com