User Guide¶
This guide covers everything you need to know to use ZViz effectively.
Overview¶
ZViz uses security profiles to define what containers can and cannot do. Profiles are declarative YAML files that get compiled into enforcement rules for the kernel.
Key Concepts¶
Profiles¶
A profile defines the security policy for a container:
name: my-profile
version: 1.0
syscalls:
allow:
- read
- write
- exit
deny:
- mount
- bpf
filesystem:
readonly: ["/usr", "/lib", "/etc"]
writable: ["/tmp", "/work"]
network:
egress:
allow: ["10.0.0.0/8"]
deny: ["0.0.0.0/0"]
resources:
memory_max: "256M"
pids_max: 100
Enforcement Layers¶
ZViz applies five enforcement layers:
| Layer | Mechanism | What it Controls |
|---|---|---|
| A | Namespaces + Capabilities | Resource visibility |
| B | Seccomp-BPF + Broker | Syscall access |
| C | LSM (AppArmor/SELinux/Landlock) | File/object access |
| D | cgroups v2 | Resource limits |
| E | Network namespace + nftables | Network access |
The Broker¶
For syscalls that need argument inspection (like openat), ZViz uses a broker process that:
- Receives the syscall via
SECCOMP_RET_USER_NOTIF - Validates arguments against the profile
- Either performs the operation on behalf of the container or denies it
User Guide Contents¶
-
Profiles
Understanding and using security profiles
-
Profile Authoring
Create custom profiles for your workloads
-
Built-in Profiles
Pre-configured profiles for common use cases
-
CLI Reference
Complete command-line interface reference
-
Troubleshooting
Diagnose and fix common issues
Quick Examples¶
Run with a Built-in Profile¶
# CI runner profile - optimized for build workloads
sudo zviz run --profile ci-runner build-job . /bin/sh -c "npm install && npm test"
# Minimal profile - maximum security
sudo zviz run --profile minimal restricted-job . /bin/sh -c "cat /etc/passwd"
Run with Custom Profile¶
# Compile your profile
zviz compile my-profile.yaml
# Run with the profile
sudo zviz run --profile my-profile custom-job . /bin/sh -c "my-app"
Run with Inline Options¶
# Resource limits
sudo zviz run --memory 256M --cpus 0.5 limited-job . /bin/sh
# Network restrictions
sudo zviz run --network-allow 10.0.0.0/8 internal-job . /bin/sh
# Read-only filesystem with specific writable paths
sudo zviz run --readonly --writable /tmp job . /bin/sh
Common Workflows¶
Development¶
# Quick iteration with debug logging
sudo zviz --log-level debug run dev-container . /bin/sh
# With audit mode to see what's being blocked
sudo zviz run --audit dev-container . /bin/sh
CI/CD¶
# Run a build with strict isolation
sudo zviz run \
--profile ci-runner \
--memory 2G \
--timeout 30m \
build-$BUILD_ID . /bin/sh -c "make build && make test"
Production¶
# Multi-container workload
for i in $(seq 1 10); do
sudo zviz run \
--profile web-server \
--detach \
web-$i . /bin/sh -c "nginx -g 'daemon off;'"
done
Best Practices¶
1. Start Restrictive, Add Permissions¶
Begin with a minimal profile and add permissions as needed:
# Start with nothing allowed
syscalls:
allow: []
deny: ["*"]
# Then add what you need
syscalls:
allow:
- read
- write
- openat
- close
2. Use Built-in Profiles When Possible¶
Built-in profiles are tested and optimized: