Temporal is a modern workflow orchestration engine used by Uber, Netflix, Snap, and thousands of other companies to build reliable distributed applications. Its default security posture has important gaps: the gRPC frontend service on port 7233 requires no authentication by default β any client that can reach this port can list, start, signal, and terminate workflows across all namespaces; Temporal's namespace isolation relies on the namespace name supplied by the client, not server-enforced access control, meaning any authenticated (or unauthenticated) client can access any namespace; the Temporal Web UI on port 8080 exposes workflow inputs, outputs, and execution history including sensitive business data in activity parameters; worker processes register on task queues and receive workflow tasks from any client submitting to the same namespace and queue β a rogue worker can intercept tasks; and Temporal Cloud and self-hosted mTLS configurations are commonly disabled during development and accidentally deployed to production. This guide covers systematic Temporal security assessment.
# Temporal ports:
# 7233 β gRPC frontend (main API)
# 7234 β gRPC internal (inter-node)
# 7235 β gRPC history
# 7239 β gRPC matching
# 8080 β Web UI
# 8233 β HTTP gateway (Temporal Cloud, proxies gRPC)
# Check Temporal gRPC service (using grpc_cli or temporal CLI)
# Install temporal CLI: https://docs.temporal.io/cli
# Check cluster info (no auth required on default deployments)
temporal operator cluster describe --address temporal.example.com:7233 2>/dev/null | head -10
# List all namespaces (no auth required)
temporal operator namespace list --address temporal.example.com:7233 2>/dev/null | \
grep -E "(Name|Status)" | head -20
# Using grpcurl if temporal CLI not available
grpcurl -plaintext temporal.example.com:7233 temporal.api.operatorservice.v1.OperatorService/ListNamespaces 2>/dev/null | \
python3 -c "
import json,sys
data = json.load(sys.stdin)
namespaces = data.get('namespaces', [])
print(f'Namespaces: {len(namespaces)}')
for ns in namespaces:
info = ns.get('namespaceInfo', {})
print(f\" {info.get('name','?')} state={info.get('state','?')}\")
" 2>/dev/null
# Temporal stores complete workflow execution history including all activity inputs/outputs
# This history is accessible to all namespace members and persists for the retention period
# List recent workflow executions (no auth on default deployments)
temporal workflow list --address temporal.example.com:7233 \
--namespace production 2>/dev/null | head -20
# Get complete history of a workflow (contains all inputs, outputs, and intermediate states)
temporal workflow show --address temporal.example.com:7233 \
--namespace production \
--workflow-id 2>/dev/null | head -50
# Output includes: workflow input parameters (may contain PII, credentials, payment data)
# Activity inputs/outputs: API responses, database query results, etc.
# Extract sensitive data from workflow history via the gRPC API
grpcurl -plaintext -d "{\"namespace\":\"production\",\"execution\":{\"workflowId\":\"payment-processing-123\"}}" \
temporal.example.com:7233 \
temporal.api.workflowservice.v1.WorkflowService/GetWorkflowExecutionHistory 2>/dev/null | \
python3 -c "
import json,sys
data = json.load(sys.stdin)
events = data.get('history', {}).get('events', [])
for e in events[:10]:
attrs = e.get('workflowExecutionStartedEventAttributes', {})
if attrs:
print('Workflow input:', str(attrs.get('input',''))[:200])
" 2>/dev/null
authorizer interface to enforce namespace-level RBAC; the default noop authorizer allows all access| Security Test | Method | Risk |
|---|---|---|
| gRPC frontend accessible without authentication | temporal workflow list --address :7233 β lists all workflows without credentials | Critical |
| Cross-namespace workflow access | Specify any namespace in gRPC calls β client-provided namespace not server-validated | High |
| Workflow history contains sensitive data | temporal workflow show β activity inputs may contain PII, API keys, payment data | High |
| Worker task queue hijacking | Register rogue worker on production task queue β intercepts workflow tasks before legitimate workers | High |
| Unauthenticated workflow termination | temporal workflow terminate --namespace prod βworkflow-id X β kills production workflow | High |
| mTLS disabled in production deployment | Connect with plaintext gRPC client β if accepted, mTLS is not enforced | Medium |
Ironimo tests Temporal workflow deployments for unauthenticated gRPC frontend access allowing workflow enumeration and manipulation, cross-namespace workflow access via client-provided namespace parameters, workflow history data exposure containing sensitive business inputs and activity outputs, worker task queue hijacking by rogue worker registration, unauthenticated workflow termination disrupting production jobs, and mTLS enforcement gaps allowing plaintext gRPC connections.
Start free scan