CIS HashiCorp Nomad Benchmark
Security configuration recommendations for HashiCorp Nomad workload orchestrator
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for HashiCorp Nomad clusters. It covers ACL system configuration, mTLS and gossip encryption, namespace isolation, Vault integration, Sentinel policies, service mesh networking, server/client hardening, and operational practices like snapshot management and safe deployments.
| Section | Area | Focus |
|---|---|---|
| 1 | Access Control | ACL bootstrapping and least-privilege token policies |
| 2 | Transport Security | mTLS encryption and gossip key rotation |
| 3 | Workload Isolation | Namespace separation and resource limits |
| 4 | Secrets & Audit | Vault integration and audit log delivery enforcement |
| 5 | Policy & Networking | Sentinel policy enforcement and Consul Connect mesh |
| 6 | Server & Client Hardening | Quorum configuration and task driver restrictions |
| 7 | Operations & Recovery | Raft snapshots and canary deployment strategies |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Nomad deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Access Control
▶1.1 ACL Configuration
▶This recommendation verifies that the ACL system is enabled and bootstrapped on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check if ACLs are enabled: nomad operator debug -interval 1s -duration 1s 2>/dev/null nomad acl bootstrap 2>&1 | grep -i 'already bootstrapped' # Verify ACL configuration: nomad agent-info | grep -A5 ACL
# Enable ACL system in server config:
cat >> /etc/nomad.d/acl.hcl << 'EOF'
acl {
enabled = true
}
EOF
# Bootstrap ACL system:
nomad acl bootstrap
# Store the Secret ID securely
# Create role-based tokens:
nomad acl policy apply developer /path/to/dev-policy.hcl
nomad acl token create -name='dev-token' -policy=developerThis recommendation verifies that ACL tokens follow least-privilege policies on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List ACL tokens: nomad acl token list # Check token policies: nomad acl token info $TOKEN_ACCESSOR # List ACL policies: nomad acl policy list
# Create least-privilege policy:
cat > /tmp/app-deploy.hcl << 'EOF'
namespace "production" {
policy = "read"
capabilities = ["submit-job", "read-logs"]
}
namespace "default" {
policy = "deny"
}
node {
policy = "read"
}
EOF
nomad acl policy apply app-deploy /tmp/app-deploy.hcl2 — Transport Security
▶2.1 Encryption
▶This recommendation verifies that mTLS is enabled for all RPC and HTTP traffic on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check TLS configuration: nomad agent-info | grep -i tls # Verify certificate validity: openssl s_client -connect nomad.example.com:4646 2>/dev/null | \ openssl x509 -noout -dates -subject
# Configure mTLS for all Nomad traffic:
cat > /etc/nomad.d/tls.hcl << 'EOF'
tls {
http = true
rpc = true
ca_file = "/etc/nomad.d/certs/ca.pem"
cert_file = "/etc/nomad.d/certs/server.pem"
key_file = "/etc/nomad.d/certs/server-key.pem"
verify_server_hostname = true
verify_https_client = true
}
EOF
systemctl restart nomadThis recommendation verifies that gossip encryption is enabled and keys are rotated on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check gossip encryption: nomad agent-info | grep -i encrypt # Verify keyring: nomad operator keyring list
# Generate gossip encryption key:
nomad operator gossip keyring generate
# Add to server/client config:
cat >> /etc/nomad.d/gossip.hcl << 'EOF'
server {
encrypt = "YOUR_GENERATED_KEY_HERE"
}
EOF
# Rotate gossip keys:
nomad operator gossip keyring install $NEW_KEY
nomad operator gossip keyring use $NEW_KEY
nomad operator gossip keyring remove $OLD_KEY3 — Workload Isolation
▶3.1 Namespace & Resource Controls
▶This recommendation verifies that namespaces are used for workload isolation on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check namespace configuration: nomad namespace list # Verify job namespace assignment: nomad job status -namespace=production
# Create isolated namespaces:
nomad namespace apply -description 'Production workloads' production
nomad namespace apply -description 'Staging environment' staging
nomad namespace apply -description 'Development' development
# Apply namespace-specific ACL policies:
cat > /tmp/prod-ns.hcl << 'EOF'
namespace "production" {
policy = "write"
capabilities = ["submit-job", "dispatch-job", "read-logs", "read-fs"]
}
namespace "staging" {
policy = "read"
}
EOF
nomad acl policy apply prod-team /tmp/prod-ns.hclThis recommendation verifies that resource limits and task driver restrictions are set on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check resource limits in job spec: nomad job inspect $JOB_NAME | jq '.Job.TaskGroups[].Tasks[].Resources' # Check task driver restrictions: nomad agent-info | grep -A10 driver
# Set resource limits in job spec:
job "web" {
group "app" {
task "server" {
resources {
cpu = 500
memory = 256
memory_max = 512
}
driver = "docker"
config {
image = "app:latest"
pids_limit = 100
readonly_rootfs = true
cap_drop = ["ALL"]
cap_add = ["NET_BIND_SERVICE"]
}
}
}
}4 — Secrets & Audit
▶4.1 Vault & Logging
▶This recommendation verifies that Vault integration is configured for secrets management on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Vault integration: nomad agent-info | grep -A5 vault # Verify Vault token configuration: grep -r vault /etc/nomad.d/
# Configure Vault integration:
cat > /etc/nomad.d/vault.hcl << 'EOF'
vault {
enabled = true
address = "https://vault.example.com:8200"
token = "" # Use Vault agent or task-specific tokens
create_from_role = "nomad-cluster"
tls_ca_file = "/etc/nomad.d/certs/vault-ca.pem"
}
EOF
# Use Vault secrets in job:
job "web" {
group "app" {
task "server" {
vault {
policies = ["web-app"]
change_mode = "restart"
}
template {
data = <<EOH
{{ with secret "secret/data/app" }}
DB_PASSWORD={{ .Data.data.password }}
{{ end }}
EOH
destination = "secrets/env.txt"
env = true
}
}
}
}This recommendation ensures that audit logging is enabled with enforced delivery on the Nomad workload orchestrator. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the Nomad workload orchestrator may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check audit logging: nomad agent-info | grep -i audit # Verify log file exists: ls -la /var/log/nomad/audit*
# Enable audit logging:
cat > /etc/nomad.d/audit.hcl << 'EOF'
audit {
enabled = true
sink "file" {
type = "file"
format = "json"
path = "/var/log/nomad/audit.log"
delivery_guarantee = "enforced"
rotate_duration = "24h"
rotate_max_files = 30
}
}
EOF
systemctl restart nomad
# Forward to SIEM:
# Configure rsyslog or Filebeat to ship audit logs5 — Policy & Networking
▶5.1 Sentinel & Service Mesh
▶This recommendation verifies that Sentinel policies enforce image and job restrictions on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Sentinel policies (Enterprise): nomad sentinel list 2>/dev/null # Verify job validation: nomad job validate /path/to/job.hcl
# Create Sentinel policy to enforce Docker images:
cat > /tmp/restrict-images.sentinel << 'EOF'
import "strings"
main = rule {
all job.task_groups as tg {
all tg.tasks as task {
strings.has_prefix(task.config.image, "registry.example.com/")
}
}
}
EOF
nomad sentinel apply -level=hard-mandatory \
restrict-images /tmp/restrict-images.sentinelThis recommendation verifies that Consul Connect service mesh is used for inter-service traffic on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check network mode in jobs: nomad job inspect $JOB | jq '.Job.TaskGroups[].Networks' # Verify Consul Connect usage: nomad job inspect $JOB | jq '.Job.TaskGroups[].Services[].Connect'
# Use Consul Connect (service mesh) in job:
job "web" {
group "app" {
network {
mode = "bridge"
port "http" { to = 8080 }
}
service {
name = "web"
port = "http"
connect {
sidecar_service {
proxy {
upstreams {
destination_name = "api"
local_bind_port = 9090
}
}
}
}
}
task "server" {
driver = "docker"
config {
image = "app:latest"
}
}
}
}6 — Server & Client Hardening
▶6.1 Configuration
▶This recommendation verifies that server cluster uses proper quorum and join configuration on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check server configuration:
grep -r 'server {' /etc/nomad.d/
# Verify bootstrap expect:
nomad operator raft list-peers# Configure proper server count and heartbeat:
cat > /etc/nomad.d/server.hcl << 'EOF'
server {
enabled = true
bootstrap_expect = 3
heartbeat_grace = "10s"
min_heartbeat_ttl = "10s"
server_join {
retry_join = ["nomad-1.example.com", "nomad-2.example.com", "nomad-3.example.com"]
retry_max = 5
}
default_scheduler_config {
scheduler_algorithm = "spread"
preemption_config {
system_scheduler_enabled = true
}
}
}
EOFThis recommendation verifies that client nodes restrict task drivers and capabilities on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check client configuration:
grep -r 'client {' /etc/nomad.d/
# Verify allowed drivers:
nomad node status -verbose $NODE_ID | grep -A5 'Driver'# Harden client configuration:
cat > /etc/nomad.d/client.hcl << 'EOF'
client {
enabled = true
max_kill_timeout = "30s"
host_volume "data" {
path = "/opt/nomad/data"
read_only = false
}
options {
"driver.whitelist" = "docker,exec"
"docker.privileged.enabled" = "false"
"docker.volumes.enabled" = "false"
"docker.caps.whitelist" = "NET_BIND_SERVICE"
}
}
EOF7 — Operations & Recovery
▶7.1 Backup & Deployment
▶This recommendation verifies that automated Raft snapshot backups are configured on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check snapshot status: ls -la /var/nomad/snapshots/ # Verify raft state: nomad operator raft list-peers
# Create automated Raft snapshots: nomad operator snapshot save /var/nomad/snapshots/backup-$(date +%Y%m%d).snap # Set up automated backups via cron: cat > /etc/cron.d/nomad-backup << 'EOF' 0 */4 * * * root nomad operator snapshot save \ /var/nomad/snapshots/backup-$(date +\%Y\%m\%d-\%H\%M).snap find /var/nomad/snapshots/ -mtime +7 -delete EOF
This recommendation verifies that job update strategies use canary and auto-revert on the Nomad workload orchestrator. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Nomad workload orchestrator vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check update strategy in job: nomad job inspect $JOB | jq '.Job.TaskGroups[].Update' # Verify job version history: nomad job history $JOB
# Configure safe update strategy:
job "web" {
update {
max_parallel = 1
health_check = "checks"
min_healthy_time = "30s"
healthy_deadline = "5m"
auto_revert = true
canary = 1
}
group "app" {
count = 3
task "server" {
# ...
}
}
}