Skip to main content
https://catalogartifact.azureedge.net/publicartifacts/lynxroute.temporal-4ab07dc8-ef07-4760-b632-cc5802d6d852/image3_Azureready.png

Temporal - Hardened Durable Execution and Workflow Engine

by Lynxroute

Temporal 1.31.1 - CIS Level 1 hardened durable execution & workflow engine on Ubuntu 24.04 LTS

What is Temporal

Temporal is an open-source durable execution platform for orchestrating long-running, fault-tolerant application workflows. Developers write workflows and activities as ordinary code (with Go, Java, Python, TypeScript, .NET, and PHP SDKs) and the Temporal Server guarantees they run to completion despite process crashes, restarts, or infrastructure failures - persisting every step and driving automatic activity retries, durable timers, signals, queries, schedules, and child workflows. The server is written in Go and runs four services (frontend, history, matching, worker); a separate Web UI provides workflow visibility, search, and history inspection. This image bundles a local PostgreSQL for event history and advanced (searchable) visibility, so the whole platform runs on one VM with no external dependencies. MIT license, no vendor lock-in.

Why self-host Temporal

Running Temporal on a VM you control keeps your workflow definitions, payloads, and full execution history - which often carry sensitive business and customer data - inside your own tenant rather than a managed execution service. Self-hosting suits teams with data residency requirements, organisations operating under GDPR, HIPAA or ISO 27001, and any product where orchestration state must stay within your own perimeter with no per-action fees. Temporal is MIT-licensed, fully auditable, with no vendor lock-in.

What this VM image adds

Security hardening:

  • Unique Web UI password and PostgreSQL password generated per instance at first launch - no default credentials - stored in /root/temporal-credentials.txt (mode 0600)
  • Web UI behind an nginx TLS reverse proxy with HTTP Basic Auth - TLS terminated on port 443, the Web UI served from loopback, gated by the generated credential
  • gRPC frontend (7233) bound to 127.0.0.1 only - never exposed; attach workers from your own VPC explicitly by opening 7233 to your VPC CIDR only
  • Bundled PostgreSQL bound to 127.0.0.1 only - the persistence store is never reachable from outside the VM
  • Self-signed TLS certificate generated at first launch and replaceable with your own CA-signed certificate (certbot is pre-installed)
  • UFW firewall - TCP 443 open externally for buyer use, TCP 22 for SSH; all other inbound dropped; Azure IMDS and WireServer egress pre-configured
  • fail2ban - SSH brute-force protection
  • AppArmor - mandatory access control
  • CVE scan - every image is scanned with Trivy before release

OS hardening (CIS Level 1):

  • CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
  • auditd for system call auditing of critical paths
  • SSH hardening - PasswordAuthentication disabled, key-only access, PermitRootLogin no, LoginGraceTime 60
  • Kernel hardening - SYN cookies, ASLR, rp_filter, kexec disabled, IPv6 off
  • /tmp as tmpfs with nosuid, nodev, noexec

Compliance artifacts (inside the VM):

  • SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json with Temporal pinned by version, PURL, MIT license, supplier, and hash
  • CIS Conformance Report at /etc/lynxroute/cis-report.html (OpenSCAP, Azure tailoring profile, 0 FAIL rules)
  • Tailored CIS profile at /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
  • Operator credentials file at /root/temporal-credentials.txt (mode 0600) with the Web UI username and password, the PostgreSQL password, and the Web UI HTTPS URL

Quick Start

  1. Deploy VM from Azure Marketplace (Standard_D2s_v3 recommended)
  2. Open NSG: TCP 443 from your trusted sources, TCP 22 from your management IPs only
  3. SSH: ssh -i key.pem azureuser@<PUBLIC_IP>, then sudo cat /root/temporal-credentials.txt for the Web UI password
  4. Open https://<PUBLIC_IP>/ in your browser and accept the self-signed certificate warning
  5. Log in with the Web UI username and password from the credentials file (HTTP Basic Auth gates the Web UI)

The default namespace is registered at first boot and the bundled temporal CLI is on PATH (for example: temporal workflow list --namespace default). The Web UI runs on 127.0.0.1:8080 and the gRPC frontend on 127.0.0.1:7233; nginx is the TLS and Basic Auth perimeter on port 443 - do not expose 8080 or 7233 directly. To run remote workers, open TCP 7233 to your VPC CIDR only, never to 0.0.0.0/0. Replace the self-signed certificate with a CA-signed one for production, then run sudo systemctl reload nginx.