Specification
This reference documents the complete security policy schema. Policies are JSON documents that define permitted runtime operations for your pipelines.
Policy Structure
A security policy is a JSON object with the following top-level structure:
{
"mode": "observe",
"container": { ... },
"path": { ... },
"ip": { ... },
...
}The only required field is mode. All other sections are optional and define permitted operations for their respective domains.
Common Patterns
Before diving into specific policy sections, understand these patterns used throughout:
The all Wildcard
The string "all" matches any value for that position in a rule:
"connect": ["all"]This permits any connection. Use with caution—it grants broad access.
Pipe-Delimited Rules
Most rules use pipes (|) to separate components:
component1|component2|component3For example:
/usr/bin/curl|api.example.com|443Brace Expansion
Use braces to match multiple values:
{value1,value2,value3}Examples:
{80,443}— matches port 80 or 443{/bin,/usr/bin}/bash— matches/bin/bashor/usr/bin/bash{http,https}://example.com— matches either protocol
The %workspace% Variable
The %workspace% variable expands to the current job’s workspace directory:
%workspace%/build/outputThis is essential for CI/CD pipelines where workspaces vary per build.
Mode
Required field.
{
"mode": "observe"
}| Value | Description |
|---|---|
derive | Monitor all behavior and auto-generate policy rules. The Sensor outputs a derived policy when the job completes. |
observe | Log violations without blocking. Use for testing and refinement. |
enforce | Block unauthorized operations. Builds fail when violations occur. |
Container Operations
Control container runtime operations.
container.run
Specifies which container images can be executed.
Format: image|tag
"container": {
"run": [
"docker.io/nginx|latest",
"gcr.io/myproject/myapp|v1.0",
"quay.io/podman/hello|all"
]
}| Example | Description |
|---|---|
"all" | Allow all container images |
"docker.io/nginx|latest" | Specific image and tag |
"gcr.io/myproject/myapp|v1.0" | Specific image and tag |
"all|production" | Any image with ‘production’ tag |
"quay.io/podman/hello|all" | Specific image, any tag |
container.socket
Controls privileged socket exposure to containers.
Format: image|tag
"container": {
"socket": [
"docker.io/library/docker|latest",
"gcr.io/myproject/builder|all",
"all|production"
]
}| Example | Description |
|---|---|
"all" | Allow all containers to access sockets |
"docker.io/library/docker|latest" | Docker-in-Docker image with latest tag |
"gcr.io/myproject/builder|all" | Builder image with any tag |
"all|production" | Any image with production tag |
/var/run/docker.sock) grants container escape capabilities. Only enable when explicitly required.File System Operations
Control file and directory operations through the path section.
path.execute
Specifies which programs can be executed.
Format: parent_path|interpreter_path|target_path
The three-part format tracks the execution chain for attack detection:
- parent_path: The process that initiated the execution
- interpreter_path: The interpreter or loader executing the target
- target_path: The actual program being executed
"path": {
"execute": [
"/bin/sudo|/bin/bash|/usr/bin/whoami",
"all|/bin/bash|%workspace%/scripts/build.sh",
"{/bin,/usr/bin}/bash|all|{/bin,/usr/bin}/{ls,cat,grep}"
]
}| Example | Description |
|---|---|
"all" | Allow any execution |
"/bin/bash|/bin/bash|/usr/bin/ls" | Bash running ls |
"all|/bin/bash|%workspace%/script.sh" | Any parent, bash executing workspace script |
"all|all|<anonymous>" | Fileless/memfd execution |
"{/bin,/usr/bin}/node|all|all" | Node.js from either location |
The special value <anonymous> matches fileless execution via memfd_create.
path.create
Controls file and directory creation.
Format: process_path|target_path
"path": {
"create": [
"/bin/touch|/var/log/app.log",
"/usr/bin/mkdir|%workspace%/build",
"all|/tmp"
]
}| Example | Description |
|---|---|
"all" | Allow any process to create files anywhere |
"/bin/touch|%workspace%" | touch can create files in workspace |
"/usr/bin/mkdir|/tmp" | mkdir can create directories in /tmp |
"all|%workspace%" | Any process can create in workspace |
"%workspace%/build.sh|all" | Build script can create files anywhere |
Monitors for persistence mechanisms including cron jobs, rc scripts, and service files.
path.delete
Controls file and directory deletion.
Format: process_path|target_path
"path": {
"delete": [
"/bin/rm|%workspace%/build",
"/usr/bin/make|%workspace%/obj",
"all|/tmp"
]
}| Example | Description |
|---|---|
"all" | Allow any process to delete files anywhere |
"/bin/rm|%workspace%" | rm can delete files in workspace |
"all|/tmp" | Any process can delete in /tmp |
"%workspace%/cleanup.sh|all" | Cleanup script can delete anywhere |
Monitors for evidence destruction, log tampering, and ransomware activity.
path.open
Controls file read access.
Format: process_path|file_path
"path": {
"open": [
"/bin/cat|/etc/passwd",
"/usr/bin/app|/var/lib/app/config.yaml",
"all|%workspace%"
]
}| Example | Description |
|---|---|
"all" | Allow any process to read files anywhere |
"/bin/cat|/etc/passwd" | cat can read /etc/passwd |
"/usr/bin/app|/var/lib/app" | App can read its data directory |
"all|%workspace%" | Any process can read workspace files |
"{/bin,/usr/bin}/bash|all" | Bash can read any file |
Monitors access to sensitive files such as /etc/shadow, SSH keys, and credentials.
path.write
Controls file modification.
Format: process_path|file_path
"path": {
"write": [
"/usr/bin/gcc|%workspace%/build/output.o",
"/usr/bin/npm|%workspace%/node_modules",
"all|/tmp"
]
}| Example | Description |
|---|---|
"all" | Allow any process to write files anywhere |
"/usr/bin/gcc|%workspace%" | gcc can write to workspace |
"all|/tmp" | Any process can write to /tmp |
"%workspace%/build.sh|all" | Build script can write anywhere |
"/usr/bin/app|/var/log/app.log" | App can write its log file |
Monitors tampering with system files, configuration files, and binaries.
path.quota
Controls disk quota operations.
Format: process_path|superblock_path|quota_command
"path": {
"quota": [
"/usr/bin/quota|/|getquota",
"all|/home|setquota"
]
}path.pivot
Controls pivot_root operations that change the filesystem root.
Format: process_path|old_root_path|new_root_path
"path": {
"pivot": [
"/usr/bin/runc|/tmp/old|/tmp/new",
"/usr/bin/containerd|all|all"
]
}path.chroot
Controls chroot operations.
Format: process_path|chroot_path
"path": {
"chroot": [
"/usr/sbin/sshd|/var/chroot/ssh",
"/usr/bin/app|all"
]
}IP Networking
Control TCP/IP socket operations for both IPv4 and IPv6.
ip.bind
Specifies which processes can listen for inbound connections.
Format: executable_path|ip_address/CIDR|port
"ip": {
"bind": [
"/usr/bin/nginx|0.0.0.0/0|{80,443}",
"/usr/bin/node|0.0.0.0/0|3000",
"all|::/0|8080"
]
}| Example | Description |
|---|---|
"all" | Allow all bind operations |
"/usr/bin/nginx|0.0.0.0/0|{80,443}" | Nginx on HTTP(S) ports |
"/usr/bin/app|::/0|8080" | IPv6 bind to port 8080 |
"all|0.0.0.0/0|8080" | Any app binding to port 8080 |
ip.connect
Specifies which outbound connections are permitted.
Format: executable_path|ip_address_or_hostname/CIDR|port
"ip": {
"connect": [
"/usr/bin/curl|example.com|443",
"all|140.82.112.0/20|443",
"/usr/bin/apt-get|archive.ubuntu.com|{80,443}"
]
}| Example | Description |
|---|---|
"all" | Allow all outbound connections |
"/usr/bin/curl|api.example.com|443" | Curl to specific host |
"all|192.168.0.0/16|all" | Any app to private network |
"/usr/bin/npm|registry.npmjs.org|443" | npm to registry |
IP Addresses vs Hostnames
The Sensor operates at the IP address level. While hostnames are supported, CIDR notation is preferred for reliability.
When a hostname is provided, the Sensor attempts to resolve all associated IP addresses, but this is not always technically possible (e.g., DNS round-robin, CDNs, geo-distributed services). This can result in false positive violations when a build connects using an IP address the Sensor could not discover.
Built-in Cloud Provider Support: The Sensor maintains up-to-date CIDR ranges for major cloud services: AWS, CloudFlare, Fastly, GCP, and GitHub. When connecting to managed services from these providers (e.g., api.github.com), the Sensor uses its internal CIDR list rather than DNS resolution, ensuring accurate policy enforcement.
Unix Domain Sockets
Control local inter-process communication.
unix.bind
Specifies which processes can create Unix sockets.
Format: process_path|socket_path
"unix": {
"bind": [
"/usr/bin/app|/tmp/app.sock",
"/usr/bin/postgres|/var/run/postgresql/.s.PGSQL.5432"
]
}unix.connect
Specifies which processes can connect to Unix sockets.
Format: process_path|socket_path
"unix": {
"connect": [
"/usr/bin/docker|/var/run/docker.sock",
"/usr/bin/psql|/var/run/postgresql/.s.PGSQL.5432"
]
}| Example | Description |
|---|---|
"all" | Allow all Unix socket connections |
"/usr/bin/docker|/var/run/docker.sock" | Docker CLI to daemon |
"all|/tmp/app.sock" | Any process to specific socket |
Advanced Socket Operations
Control raw sockets and packet manipulation—features commonly used by network tools and potentially by attack tools.
socket.packet
Controls packet-level network access at the data link layer.
Format: process_path
"socket": {
"packet": [
"/usr/bin/tcpdump",
"/usr/bin/wireshark"
]
}Provides raw Ethernet frame access. Used by packet capture tools.
socket.raw
Controls raw IP socket creation.
Format: process_path
"socket": {
"raw": [
"/usr/bin/ping",
"/usr/bin/traceroute"
]
}Used for ICMP tools, port scanning, and custom protocols. Bypasses the TCP/UDP layer.
socket.inject
Controls packet injection capabilities.
Format: process_path
"socket": {
"inject": [
"/usr/bin/hping3",
"/usr/bin/nmap"
]
}Enables IP header modification, broadcast, and TX ring operations.
socket.sniff
Controls promiscuous mode (network sniffing).
Format: process_path
"socket": {
"sniff": [
"/usr/bin/tcpdump",
"/usr/bin/tshark"
]
}Netlink Sockets
Control kernel-userspace communication for network configuration.
netlink.bind
Specifies which processes can create netlink sockets.
Format: process_path
"netlink": {
"bind": [
"/usr/bin/ip",
"/usr/bin/ss",
"/usr/sbin/NetworkManager"
]
}Used by network tools like ip, ss, and network managers for kernel communication.
Virtual Sockets (vsock)
Control VM-to-host and VM-to-VM communication.
vsock.bind
Specifies which processes can bind vsock ports.
Format: process_path|port
"vsock": {
"bind": [
"/usr/bin/app|1234",
"/usr/bin/app|all"
]
}vsock.connect
Specifies which processes can connect via vsock.
Format: process_path|port
"vsock": {
"connect": [
"/usr/bin/app|1234"
]
}Used in VMware, KVM, and Firecracker for VM-host communication.
Process Hooks and Debugging
Control debugging tools and code injection mechanisms—commonly abused in attacks.
hook.ptrace
Controls process tracing operations.
Format: tracer_path|target_path
"hook": {
"ptrace": [
"/usr/bin/strace|all",
"/usr/bin/gdb|/usr/bin/myapp"
]
}| Example | Description |
|---|---|
"all" | Allow any ptrace operation |
"/usr/bin/strace|all" | strace can trace any process |
"/usr/bin/gdb|/usr/bin/app" | gdb can debug specific app |
"all|/usr/bin/app" | Any tracer can attach to app |
Used by debuggers (gdb, strace, ltrace) and potentially for process injection attacks.
hook.mem
Controls direct process memory access.
Format: accessor_path|target_path
"hook": {
"mem": [
"/usr/bin/gdb|all",
"all|/usr/lib/systemd/systemd"
]
}Detects process_vm_readv/process_vm_writev operations used in process injection attacks.
Memory Operations
Control memory-related operations.
mmap.file
Controls memory-mapped file operations.
Format: process_path|mapped_file_path
"mmap": {
"file": [
"/usr/bin/app|/lib/x86_64-linux-gnu/libc.so.6",
"/usr/bin/app|<anonymous>"
]
}The special value <anonymous> matches anonymous memory mappings.
mprotect.wx
Controls writable and executable memory (W+X).
Format: process_path
"mprotect": {
"wx": [
"/usr/bin/java",
"/usr/bin/node",
"/usr/bin/python3"
]
}Kernel Operations
Control highly privileged kernel-level operations.
kernel.ebpf
Specifies which processes can load eBPF programs.
Format: process_path
"kernel": {
"ebpf": [
"/usr/bin/bpftrace",
"/usr/bin/bpftool"
]
}Used for kernel tracing, packet filtering, and security monitoring.
kernel.module
Controls kernel module loading.
Format: process_path|module_name
"kernel": {
"module": [
"/sbin/modprobe|nfs",
"/usr/sbin/ip|dummy",
"all|overlay"
]
}| Example | Description |
|---|---|
"all" | Allow any process to load any module |
"/sbin/modprobe|nfs" | modprobe can load NFS module |
"/usr/sbin/ip|dummy" | ip command can load dummy network module |
"all|overlay" | Any process can load overlay module |
"/usr/bin/runc|all" | Container runtime can load any module |
kernel.read
Controls direct kernel memory access and module loading operations.
Format: process_path|module_path
"kernel": {
"read": [
"/sbin/insmod|/lib/modules/*/kernel/drivers/net/dummy.ko",
"/usr/bin/kmod|%workspace%/mymodule.ko",
"all|/lib/modules"
]
}| Example | Description |
|---|---|
"all" | Allow any process to perform kernel read operations |
"/sbin/insmod|/lib/modules" | insmod can load modules from standard path |
"/usr/bin/kmod|%workspace%/module.ko" | kmod can load workspace module |
"all|/lib/modules" | Any process can load from /lib/modules |
Detects rootkit-style memory reading via /dev/mem and /dev/kmem.
IOCTL Operations
Control low-level device operations.
ioctl.cmd
Specifies permitted IOCTL commands.
Format: process_path|device_path|command_number
"ioctl": {
"cmd": [
"/usr/bin/app|/dev/tty|all",
"all|/dev/null|{21523,21584}",
"/usr/bin/app|all|12345"
]
}Controls low-level device operations, often exploited in kernel attacks.
Privilege Escalation
Control capability changes and privilege escalation.
privilege.escalate
Specifies which processes can acquire capabilities.
Format: executable_path|{capabilities}
"privilege": {
"escalate": [
"/usr/bin/sudo|{setuid,setgid}",
"/usr/bin/ping|{net_admin,net_raw}",
"/usr/sbin/nginx|{net_bind_service}"
]
}Common Linux capabilities:
| Capability | Description |
|---|---|
setuid | Change user ID |
setgid | Change group ID |
net_admin | Network administration |
net_raw | Use raw sockets |
net_bind_service | Bind to privileged ports (<1024) |
sys_admin | System administration (very broad) |
sys_ptrace | Trace processes |
dac_override | Bypass file permission checks |
Task/Process Management
Control process lifecycle and resource operations.
task.kill
Specifies which processes can terminate others.
Format: killer_path|target_path
"task": {
"kill": [
"/usr/bin/kill|all",
"/usr/bin/systemctl|all",
"/usr/bin/app|/usr/bin/app"
]
}Monitors attempts to kill security tools and critical processes.
task.rlimit
Controls resource limit modifications.
Format: current_path|target_path|resource_type
"task": {
"rlimit": [
"/usr/bin/systemd|all|nofile",
"/usr/bin/app|all|{nofile,nproc}"
]
}Resource types:
| Resource | Description |
|---|---|
nofile | Maximum open file descriptors |
nproc | Maximum number of processes |
memlock | Maximum locked memory |
fsize | Maximum file size |
cpu | CPU time limit |
as | Address space limit |
stack | Stack size limit |
task.schedule
Controls scheduling priority modifications.
Format: current_path|target_path
"task": {
"schedule": [
"/usr/bin/chrt|all",
"/usr/bin/app|all"
]
}task.nice
Controls nice value (CPU priority) modifications.
Format: current_path|target_path
"task": {
"nice": [
"/usr/bin/nice|all",
"/usr/bin/renice|all"
]
}Nice values range from -20 (highest priority) to +19 (lowest priority).
task.pgroup
Controls process group modifications.
Format: current_path|target_path
"task": {
"pgroup": [
"/bin/bash|all",
"/usr/bin/app|/usr/bin/app"
]
}System V IPC
Control System V inter-process communication.
sysv.shmem
Controls shared memory operations.
Format: process_path|memory_key
"sysv": {
"shmem": [
"/usr/bin/postgres|5432",
"/usr/bin/app|123456",
"all|789012"
]
}| Example | Description |
|---|---|
"all" | Allow any process to use any shared memory |
"/usr/bin/postgres|5432" | Postgres can use shared memory key 5432 |
"/usr/bin/app|all" | App can use any shared memory segment |
"all|123456" | Any process can use shared memory 123456 |
sysv.msgqueue
Controls message queue operations.
Format: process_path|message_key
"sysv": {
"msgqueue": [
"/usr/bin/app|123456",
"/usr/bin/worker|all",
"all|789012"
]
}| Example | Description |
|---|---|
"all" | Allow any process to use any message queue |
"/usr/bin/app|123456" | App can use message queue with key 123456 |
"/usr/bin/worker|all" | Worker can use any message queue |
"all|789012" | Any process can use queue 789012 |
Complete Schema Reference
Below is the complete list of all policy sections and their operations:
| Section | Operations |
|---|---|
mode | (required) observe, enforce, derive |
container | run, socket |
path | execute, create, delete, open, write, quota, pivot, chroot |
ip | bind, connect |
unix | bind, connect |
socket | packet, raw, inject, sniff |
netlink | bind |
vsock | bind, connect |
hook | ptrace, mem |
mmap | file |
mprotect | wx |
kernel | ebpf, module, read |
ioctl | cmd |
privilege | escalate |
task | kill, rlimit, schedule, nice, pgroup |
sysv | shmem, msgqueue |