We
Applications Azure

Wexflow on Ubuntu 24.04 on Azure User Guide

| Product: Wexflow on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Wexflow on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Wexflow is an open source workflow engine and automation platform published under the MIT licence.

Wexflow exists for the work that keeps a business running but that nobody wants to do by hand: move the files that arrived overnight, unpack and convert them, hash and encrypt them, push them somewhere over SFTP, call an API, run a query, wait for a person to approve the result, then tell somebody it is done. You assemble that out of ready made tasks in a browser, rather than writing and maintaining a pile of scripts.

A workflow is a list of tasks with settings. Wexflow ships more than one hundred of them covering file and folder operations, archives, encryption and hashing, HTTP calls, SQL queries, SSH and FTP transfers, image and document conversion, electronic mail and scripting. Workflows run on demand, on a cron or periodic schedule, or automatically when a file lands in a watched folder. An approval and records module lets a person sign off a step before the rest continues. Everything the interface can do is also available through a documented REST API.

The image ships the official upstream Wexflow 10.0 release, fetched from the project's own GitHub release and pinned by SHA-256. The exact artifact, its digest, its licence and the runtime it was built against are recorded on the image at /opt/wexflow/VERSION. Wexflow runs under systemd as wexflow.service under an unprivileged wexflow account, behind nginx on port 80.

A workflow engine that can prove it works. A sign in page that returns a web page tells you nothing about whether the engine can execute a task. So the image ships a small cloudimg authored workflow, cloudimg_Health_Check, that creates a file and copies it. Running it is a one click proof that the engine, the scheduler, the task library and the database are all working together, and it is the same proof this instance ran on itself during its first boot.

What is included:

  • Wexflow 10.0 (official upstream release, SHA-256 pinned, redistributed unmodified)
  • The complete upstream library of example workflows, one per task type, ready to open and copy
  • The cloudimg_Health_Check workflow, a one click end to end proof that the engine executes tasks
  • An embedded SQLite database, so there is no external database to provision or point at
  • nginx on port 80 as the single entry point, with an unauthenticated /healthz for load balancer probes
  • A unique administrator password, token signing key and certificate passphrase generated on first boot
  • The ASP.NET Core 10 runtime from the Ubuntu archive, so it keeps receiving security updates
  • Ubuntu 24.04 LTS, fully patched at build time, with unattended security updates left enabled
  • 24/7 cloudimg support

Key facts:

Item Value
Platform Ubuntu 24.04 LTS (Azure Gen2)
Default SSH user azureuser
Admin panel http://<vm-ip>/admin/
REST API base http://<vm-ip>/api/v1/
Services wexflow.service, nginx.service
Runs as wexflow (unprivileged, no login shell)
Application root /opt/wexflow
Database /opt/wexflow/Wexflow/Database/Wexflow.sqlite (embedded SQLite)
Credentials file /root/wexflow-credentials.txt (0600 root:root)
HTTP port 80
Engine port 8000 (behind the proxy; leave it closed in your network security group)

Prerequisites

Before deploying, ensure you have:

  1. An active Azure subscription
  2. An SSH key pair, or the Azure Portal ability to generate one
  3. Permission to create virtual machines, virtual networks and network security groups
  4. A network security group that allows inbound TCP 22 from your management network, and inbound TCP 80 from wherever the admin panel should be reachable

Recommended VM size: Standard_B2s (2 vCPU, 4 GiB). With the full example catalogue loaded the engine uses about 140 MiB of memory and the whole appliance about 600 MiB, so 4 GiB leaves a very large margin. Size up only for the workflows you intend to run in parallel and the files they handle.

Step 1: Deploy from the Azure Portal

  1. In the Azure Portal, choose Create a resource and search the Marketplace for Wexflow on Ubuntu 24.04 LTS by cloudimg.
  2. Select the offer and choose Create.
  3. On the Basics tab pick your subscription, resource group and region, set the VM name, and choose size Standard_B2s.
  4. Leave the authentication type as SSH public key and the username as azureuser.
  5. Under Inbound port rules allow SSH (22) and HTTP (80).
  6. Review and create. The VM is ready in about a minute. First boot then generates this instance's own administrator password and token signing key, and nothing listens on port 80 until it has.

Step 2: Deploy from the Azure CLI

az group create --name wexflow-rg --location eastus

az vm create \
  --resource-group wexflow-rg \
  --name wexflow-vm \
  --image cloudimg:wexflow:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

# the public address of the new VM
az vm show --resource-group wexflow-rg --name wexflow-vm \
  --show-details --query publicIps --output tsv

Then open the admin panel port:

az network nsg rule create --resource-group wexflow-rg \
  --nsg-name wexflow-vmNSG --name allow-http \
  --priority 1010 --destination-port-ranges 80 \
  --protocol Tcp --access Allow --direction Inbound

Step 3: Connect and read this instance's sign in details

ssh azureuser@<vm-ip>

Every instance generates its own administrator password on first boot and writes it to a root only file. Read it:

sudo cat /root/wexflow-credentials.txt

Expected output:

# Wexflow on Ubuntu 24.04 LTS by cloudimg — per-VM credentials
# Generated at first boot on 2026-08-07T21:31:08Z. Keep this file private.
#
# Deployment guide: https://www.cloudimg.co.uk/guides/wexflow-on-ubuntu-24-04-azure/

WEXFLOW_URL=http://20.124.233.51/admin/
WEXFLOW_ADMIN_USERNAME=admin
WEXFLOW_ADMIN_PASSWORD=<the unique password generated for your instance>

# Sign in at http://20.124.233.51/admin/ and change this password from Users in the admin panel.
# The JWT signing key and the HTTPS pfx passphrase were also generated uniquely for this
# instance and live in /opt/wexflow/Wexflow.Server/appsettings.json (root:wexflow 0640).

The address shown is your own instance's public address, and the password is unique to it. No cloudimg image ever ships a shared or published password.

Confirm both services are up, and check exactly which upstream artifact this image shipped:

systemctl is-active wexflow.service nginx.service
cat /opt/wexflow/VERSION
curl -s http://127.0.0.1/api/v1/hello

Expected output:

active
active
product=Wexflow
version=10.0
upstream=https://github.com/aelassas/wexflow
release=https://github.com/aelassas/wexflow/releases/download/v10.0/wexflow-10.0-linux-netcore.zip
release_sha256=4c7c051b12d2bea108ad4f1c819ad1849fe2daed14bdbdd1ef7e1974f406bf5a
licence=MIT (verbatim text at /opt/wexflow/LICENSE.txt)
runtime=aspnetcore-runtime-10.0 10.0.10-0ubuntu1~24.04.1 (Ubuntu archive, noble-updates/main)
datastore=SQLite (embedded, /opt/wexflow/Wexflow/Database/Wexflow.sqlite)
entry_point=http://<this-vm-public-ip>/admin/
built_by=cloudimg
{"message":"Wexflow Service is running..."}

The Wexflow engine and nginx both reporting active, the engine process owned by the unprivileged wexflow account rather than root, the ASP.NET Core 10 runtime resolved from the Ubuntu archive so it keeps receiving security updates, the unauthenticated service banner answering through the proxy, and the complete listening surface of the appliance

Step 4: Sign in to the admin panel

Open http://<vm-ip>/admin/ in a browser. The root of the site redirects there, so http://<vm-ip>/ works too.

The Wexflow sign in page served over the cloudimg reverse proxy, asking for a username and password with a stay connected option

Sign in with the username admin and the password from /root/wexflow-credentials.txt. You land on the Dashboard, which shows live counters for pending, running, completed, failed, warning, rejected and stopped jobs, and a searchable list of recent entries.

The Wexflow dashboard immediately after sign in, showing the live status counters across the top and the entries table below with the date range and search controls

Step 5: Browse the workflow catalogue

Choose Manager in the top navigation. This lists every workflow the engine has loaded from the embedded database, with its id, launch type, whether it is enabled, whether it needs approval, and its description.

The image ships the complete upstream example catalogue, one workflow per task type, plus the cloudimg health check. They are yours to open, copy and adapt.

The Wexflow manager listing the workflow catalogue loaded from the embedded database, with the job panel and the start, suspend, resume, stop, approve and reject controls above it, and the cloudimg health check workflow visible at the bottom of the list

To count them from the shell:

sudo sqlite3 /opt/wexflow/Wexflow/Database/Wexflow.sqlite 'select count(*) from workflows;'
ls /opt/wexflow/Wexflow/Workflows | head -6

Expected output:

120
Workflow_Approval.xml
Workflow_Approval_Import.xml
Workflow_Approval_Reject.xml
Workflow_ApproveDocument.xml
Workflow_ApproveInvoice.xml
Workflow_ApproveTimesheet.xml

Three of the upstream examples launch themselves, one at every start up, one periodically and one on a cron schedule. They are shipped disabled so a new instance does not silently execute jobs and accumulate history before you have looked at it. Step 9 shows how to switch one on.

Step 6: Run a workflow and watch it finish

In Manager, click the row for cloudimg_Health_Check to select it, then click Start.

The cloudimg health check workflow selected in the manager with the start control active, the job panel above it and the workflow catalogue below

Go back to Dashboard. The Done counter has advanced and the run appears in the entries table with a green Done status, its id, its name and the time it finished.

The Wexflow dashboard after the health check workflow ran, with the Done counter advanced and completed runs listed in the entries table each showing a green Done status against the cloudimg health check workflow

The workflow did real work: it created a file and copied it. Confirm on the instance:

sudo ls -l /var/lib/wexflow/healthcheck/out/
sudo journalctl -u wexflow.service --no-pager | grep cloudimg_Health_Check | tail -6

Expected output:

total 0
-rw-r--r-- 1 wexflow wexflow 0 Aug  7 21:31 cloudimg-healthcheck.txt
2026-08-07 21:29:45,309  INFO [13] - [cloudimg_Health_Check / 6] [Touch] File /var/lib/wexflow/healthcheck/src/cloudimg-healthcheck.txt created.
2026-08-07 21:29:45,309  INFO [13] - [cloudimg_Health_Check / 6] [Touch] Task finished.
2026-08-07 21:29:45,309  INFO [13] - [cloudimg_Health_Check / 6] [FilesCopier] Copying files...
2026-08-07 21:29:45,309  INFO [13] - [cloudimg_Health_Check / 6] [FilesCopier] File copied: /var/lib/wexflow/healthcheck/src/cloudimg-healthcheck.txt -> /var/lib/wexflow/healthcheck/out/cloudimg-healthcheck.txt
2026-08-07 21:29:45,309  INFO [13] - [cloudimg_Health_Check / 6] [FilesCopier] Task finished.
2026-08-07 21:29:45,310  INFO [13] - [cloudimg_Health_Check / 6] Workflow finished.

The same proof runs as a single command, which is what this instance ran on itself during first boot. It also re-proves that every published upstream default credential is refused:

sudo /usr/local/sbin/wexflow-verify-workflow.sh

Expected output:

wexflow runtime verification
  ok  all five published upstream default credentials rejected with 401
  ok  the second seeded administrator account no longer exists
  ok  a token forged with the published upstream signing key is rejected
  ok  privileged endpoints reject unauthenticated calls
  ok  the per-VM admin password authenticates and returns a token
  ok  the token opens a privileged endpoint
  ok  workflow 900 started, instance 237462e8-6e02-4b44-92f6-28ee42d621a2
  ok  the workflow produced /var/lib/wexflow/healthcheck/out/cloudimg-healthcheck.txt
  ok  the engine's completed-workflow counter advanced 5 -> 6
WEXFLOW_VERIFY_OK

The full runtime verification on this instance: every published upstream default credential refused with 401, the second seeded administrator account confirmed absent, a token forged with the published upstream signing key refused, the per instance password accepted, and the health check workflow started through the API and proven to have produced its output file with the completed workflow counter advancing

Step 7: Build your own workflow in the designer

Choose Designer in the top navigation, click Browse, pick a workflow and click Open. The workflow renders as a diagram of its tasks in order. You can also switch the same workflow to the Graph, JSON or XML view, edit it there, and save.

The Wexflow visual designer with the cloudimg health check workflow open, showing its two tasks as connected blocks, a Touch task that creates the file and a FilesCopier task that copies it, with the diagram, graph, JSON and XML views and the new workflow, run and save controls

New workflow starts an empty one. Give it an id that is not already in use, a name and a description, choose a launch type, then add tasks from the palette and set their options. Save writes it to the database and the engine picks it up immediately. Run starts it without leaving the designer.

The example catalogue is the fastest way to learn a task: open the example named after it, read its settings, then copy the pattern into your own workflow. Every task is also documented in XML on the instance:

ls /opt/wexflow/Documentation | head -8
cat /opt/wexflow/Documentation/FilesCopier.xml

Step 8: Review history and approvals

History lists every run the engine has ever recorded, with its status, date, workflow and description, filtered by date range and free text. Dashboard shows the same information for the current period along with the live counters.

The Wexflow history view listing recorded runs with their status, date, workflow id, name, launch type and description, and the date range and search controls above the table

Approvals and Records are the human in the loop side of the product. A workflow marked as an approval workflow pauses at its Approval task until somebody approves or rejects it from the Approvals page. Records attach documents to that decision, and the records hot folder at /opt/wexflow/Wexflow/Records/_HotFolder picks up files dropped into it.

Step 9: Schedule a workflow

A workflow's launch type decides when it runs. Set it in the designer, in the workflow XML, or through the API.

Launch type When it runs
trigger Only when you start it, from the manager, the designer or the API
startup Once, every time the engine starts
periodic Every period, expressed as dd.hh:mm:ss
cron On a Quartz cron expression, for example 0 0/1 * * * ? for every minute

The three shipped examples that use the last three launch types are disabled. To look at one before enabling it:

sudo sqlite3 /opt/wexflow/Wexflow/Database/Wexflow.sqlite \
  "select XML from workflows where XML like '%Workflow_Cron%' limit 1;" | head -12

To enable it, open it in the designer, tick Enabled and save. Doing it that way rather than editing the database keeps the engine's in memory schedule in step with what is stored.

File triggered workflows are the other common pattern. A workflow whose first task is FileSystemWatcher starts itself when a file appears in the folder it watches, which is how most overnight file handling is wired up. cat /opt/wexflow/Documentation/FileSystemWatcher.xml documents its options.

Step 10: Use the REST API

Everything the interface does is available over HTTP. Sign in once to get a token, then send it as a bearer token. The <WEXFLOW_ADMIN_PASSWORD> below is the password from /root/wexflow-credentials.txt.

TOKEN=$(curl -s -X POST http://127.0.0.1/api/v1/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"<WEXFLOW_ADMIN_PASSWORD>","stayConnected":false}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1/api/v1/status-count
echo
curl -s -H "Authorization: Bearer $TOKEN" 'http://127.0.0.1/api/v1/search?s=cloudimg' \
  | python3 -m json.tool | head -12

Expected output:

{"PendingCount":0,"RunningCount":0,"DoneCount":2,"FailedCount":0,"WarningCount":0,"DisabledCount":3,"RejectedCount":0,"StoppedCount":0}
[
    {
        "DbId": "120",
        "Id": 900,
        "InstanceId": "3a344963-066d-4280-971b-bc9d4a4752f8",
        "Name": "cloudimg_Health_Check",
        "FilePath": null,
        "LaunchType": 1,
        "IsEnabled": true,
        "IsApproval": false,
        "EnableParallelJobs": true,

Start a workflow and read back the engine's counters:

TOKEN=$(curl -s -X POST http://127.0.0.1/api/v1/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"<WEXFLOW_ADMIN_PASSWORD>","stayConnected":false}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')

curl -s -X POST -H "Authorization: Bearer $TOKEN" 'http://127.0.0.1/api/v1/start?w=900'
echo
sleep 5
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1/api/v1/status-count
echo

A browsable description of the whole API is served at http://<vm-ip>/swagger. Replace 127.0.0.1 with your instance's address to call it from your own machine.

Step 11: Change the administrator password and add users

The generated password is a starting point, not a resting place. Change it from Users in the admin panel: select admin, set a new password and save. The same page adds further users.

Wexflow has three user profiles. A super administrator sees and controls every workflow. An administrator sees only the workflows assigned to them, which is set per user on the Users page. A restricted user has no manager access at all and is used for the approvals and records side of the product.

The account named admin is the one the engine looks up at start up, so keep that name. Change its password freely.

Step 12: Serve the admin panel over TLS

The image ships on plain HTTP so it works the moment it boots, with no certificate and no domain name required. For anything beyond a trial, put a certificate in front of it. nginx is already the entry point, so this is ordinary nginx work:

  1. Point a DNS name at the instance and open TCP 443 in the network security group.
  2. Install a certificate for that name, either your own or one from a certificate authority.
  3. Add a listen 443 ssl; server block to /etc/nginx/sites-available/wexflow with your certificate paths, keeping the same location blocks, and redirect port 80 to it.
  4. Reload with sudo nginx -t && sudo systemctl reload nginx.

The admin single page application addresses the API on the same origin it was loaded from, so it follows the change with no further configuration.

Server components

Component Version Purpose
Wexflow 10.0 The workflow engine, admin panel and REST API
ASP.NET Core runtime 10.0 The runtime the engine is built against, from the Ubuntu archive
nginx 1.24 Reverse proxy and the single public entry point on port 80
SQLite 3.45 The embedded database holding workflows, users, entries and records
Ubuntu Server 24.04 LTS Operating system, fully patched at build time

Filesystem layout

Path Size Purpose
/ 29 GB Root filesystem
/boot 881 MB Operating system kernel files
/boot/efi 100 MB UEFI boot partition (Gen2 Hyper V)
/mnt varies Azure temporary resource disk

Key directories:

Path Purpose
/opt/wexflow Application root
/opt/wexflow/Wexflow.Server The engine, its appsettings.json and the admin panel host
/opt/wexflow/Admin The admin single page application
/opt/wexflow/Wexflow/Database The embedded SQLite database
/opt/wexflow/Wexflow/Workflows Workflow definitions on disk
/opt/wexflow/Wexflow/Records Records, including the _HotFolder watched folder
/opt/wexflow/Wexflow/Temp Scratch space used during a run
/opt/wexflow/Documentation One XML reference page per task type
/opt/wexflow/WexflowTesting Sample input files the example workflows use
/var/lib/wexflow Working directory of the service account
/var/log/wexflow Engine log

Managing the services

sudo systemctl status wexflow.service --no-pager | head -6
sudo systemctl restart wexflow.service
sudo systemctl reload nginx

Expected output:

● wexflow.service - Wexflow workflow engine
     Loaded: loaded (/etc/systemd/system/wexflow.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-08-07 21:31:08 UTC; 30s ago
       Docs: https://www.cloudimg.co.uk/guides/wexflow-on-ubuntu-24-04-azure/
   Main PID: 9201 (dotnet)
      Tasks: 22 (limit: 4666)

Both units are enabled, so the appliance comes back on its own after a reboot.

Scripts and log files

Path Purpose
/usr/local/sbin/wexflow-firstboot.sh First boot bootstrap: mints this instance's secrets, then releases the services
/usr/local/sbin/wexflow-verify-workflow.sh The runtime proof used in Step 6, safe to re-run at any time
/usr/local/lib/cloudimg/wexflow_pwhash.py The password hashing helper first boot uses
/var/log/cloudimg-firstboot.log What first boot did on this instance
/var/log/wexflow/Wexflow.log Engine log, one file per day
/var/log/nginx/access.log Proxy access log
/etc/nginx/sites-available/wexflow The reverse proxy configuration
sudo tail -n 20 /var/log/cloudimg-firstboot.log
sudo tail -n 20 /var/log/wexflow/Wexflow.log

On startup

The first time an instance boots, wexflow-firstboot.service runs once. It generates a unique administrator password, a unique token signing key and a unique certificate passphrase, writes the password into /root/wexflow-credentials.txt with mode 0600, and only then creates the marker that releases the engine and nginx.

Both wexflow.service and nginx.service carry ConditionPathExists on that marker, so until first boot has finished nothing is listening on port 80 at all. There is no window in which a newly launched instance is reachable with a credential that came from the image.

The first boot gate on this instance: both the engine and nginx conditioned on the bootstrap ready marker, the marker and the completion sentinel present, the credentials file owned by root with mode 0600, the engine settings file readable only by root and the service account, and the per instance signing key reported by length with no placeholders remaining

First boot then proves the result before handing the instance over: every published upstream default credential is refused, a token forged with the published upstream signing key is refused, the new password works, and a real workflow runs to completion. If any of that fails the service is left down rather than handed over broken.

sudo systemctl is-active wexflow-firstboot.service
sudo test -f /var/lib/cloudimg/wexflow-firstboot.done && echo "first boot complete"

Expected output:

active
first boot complete

Troubleshooting

The admin panel does not load. Check that first boot finished and that both services are up:

sudo systemctl is-active wexflow-firstboot.service wexflow.service nginx.service
sudo test -f /var/lib/cloudimg/wexflow-bootstrap-ready && echo "bootstrap ready marker present"
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz

All three units report active, the marker is present and /healthz returns 200. If the units are inactive and the marker is missing, first boot did not finish: read /var/log/cloudimg-firstboot.log and sudo journalctl -u wexflow-firstboot.service.

It loads on the instance but not from my browser. That is the network security group. Port 80 has to be open inbound from wherever you are browsing. Port 8000 is the engine behind the proxy and should stay closed.

The password in the credentials file is rejected. The file is rewritten only on the very first boot. If the password was changed afterwards from the Users page, the file still shows the original one. Change it back from an account that can still sign in, or see the next item.

Nobody can sign in at all. Reset the account from the instance. This writes a new hash directly into the embedded database using the same scheme the engine uses. Replace <new-password> with the password you want, and note that it is read on standard input rather than passed as an argument so it never reaches the process list or the journal:

sudo systemctl stop wexflow.service
NEWHASH="$(printf '%s' '<new-password>' | sudo /usr/local/lib/cloudimg/wexflow_pwhash.py hash)"
sudo sqlite3 /opt/wexflow/Wexflow/Database/Wexflow.sqlite \
  "update users set PASSWORD='${NEWHASH}' where USERNAME='admin';"
sudo systemctl start wexflow.service

Sign in with the new password, then update /root/wexflow-credentials.txt or your own password store so the two agree again.

A workflow finished with a warning or failed. Open it from History, or read the engine log. Every task logs what it did and why it stopped:

sudo tail -n 40 /var/log/wexflow/Wexflow.log

A workflow cannot write where I told it to. The engine runs as the unprivileged wexflow account, not as root. It can write inside /opt/wexflow/Wexflow, /opt/wexflow/WexflowTesting and /var/lib/wexflow. For anywhere else, create the directory and give it to the service account:

sudo install -d -o wexflow -g wexflow -m 0750 /srv/my-workflow-data

Signed out pages work but signed in pages return 502. That is a proxy buffer that is too small for the signed in session cookie. The shipped configuration already raises it; if you have replaced /etc/nginx/sites-available/wexflow, keep the proxy_buffer_size 32k; and proxy_buffers 8 32k; lines.

Checking the appliance as a whole. The single command from Step 6 re-proves the sign in path, the credential hygiene and a real workflow run in one go:

sudo /usr/local/sbin/wexflow-verify-workflow.sh

Security notes

Every published upstream default credential probed against the real sign in endpoint and refused with 401, the single remaining application account confirmed to be the super administrator with the second seeded account gone, an unauthenticated call to a privileged endpoint refused, and a token forged with the published upstream signing key refused

  • No shared or published credential ships in the image. Upstream seeds two administrator accounts with the same published password. The second account is removed from the image entirely, and the stored hash of the remaining admin account is replaced at build time with a value nobody records, so the image contains no hash of any published password.
  • The token signing key is per instance. Wexflow signs its session tokens with an HMAC key from its settings file. The published upstream value would let anyone mint a valid token for any user without ever touching the sign in page, so it is replaced with a non functional placeholder in the image and generated freshly on every first boot. Step 6's verification proves a token signed with the published key is refused.
  • Nothing listens until the instance has its own secrets. Both services are gated on a marker that first boot creates only after every per instance secret is written and verified.
  • The engine runs unprivileged. It runs as the wexflow system account with no login shell and NoNewPrivileges, not as root.
  • Change the generated password from the Users page, and add a separate account per person rather than sharing admin.
  • Restrict the network security group. Allow SSH only from your management network, and port 80 only from where the admin panel needs to be reachable. Leave port 8000 closed.
  • Put TLS in front of it before using it over anything other than a trusted network, as in Step 12. Session tokens travel in a cookie, and on plain HTTP that cookie is readable on the wire.
  • Wexflow is an automation engine, and that is the point. Its task library deliberately launches processes, runs scripts and moves files. Treat access to the designer as equivalent to shell access on the instance, and give the designer only to people you would give that to.
  • Keep the operating system patched. Unattended security updates are enabled. Reboot when a kernel update lands.

Support

Wexflow is a trademark of its respective owners. cloudimg is not affiliated with, endorsed by or sponsored by the Wexflow project; the name is used nominatively to identify the open source software packaged in this image. Wexflow is distributed under the MIT licence, and the verbatim licence text is retained on the image at /opt/wexflow/LICENSE.txt.