Agent configuration
Pepper uses strict TOML configuration: unknown fields are rejected. Paths are interpreted relative to the agent's working directory unless absolute.
Complete example
[node]
name = "node-1" # default: pepper-node
listen_addr = "127.0.0.1:9001" # default: 127.0.0.1:9000
# advertise_addr = "10.0.0.10:9001"
# failure_domain = "rack-a"
[node.placement_labels]
# region = "us-east"
# zone = "us-east-1a"
# rack = "rack-a"
# disk_class = "ssd"
[data]
path = "/var/lib/pepper" # default: ./.pepper
[identity]
key_path = "/var/lib/pepper/node.key" # default: <data.path>/node.key
generate_if_missing = true # default: true
[api]
bind_addr = "127.0.0.1:9080" # loopback required
[[storage.locations]]
path = "/srv/pepper"
max_capacity_bytes = 100000000000
[network]
bootstrap_peers = ["10.0.0.11:9000"]
[replication]
default_factor = 3
repair_interval_seconds = 30
[erasure]
enabled = false
min_size_bytes = 67108864
data_shards = 6
parity_shards = 3
[compute]
enabled = true
runtime = "firecracker"
max_concurrent_jobs = 1
work_dir = "/var/lib/pepper/compute"
firecracker_binary = "/usr/local/bin/firecracker"
firecracker_jailer_binary = "/usr/local/bin/jailer"
firecracker_enable_jailer = false
firecracker_jailer_uid = 65534
firecracker_jailer_gid = 65534
firecracker_jailer_chroot_base = "/srv/jailer"
firecracker_strict_sandbox = true
firecracker_allow_untrusted_rootfs = false
firecracker_allowed_rootfs_cids = []
# firecracker_kernel_image = "/var/lib/pepper/vmlinux"
firecracker_memory_mib = 128
firecracker_vcpu_count = 1
firecracker_max_input_bytes = 1073741824
firecracker_max_output_bytes = 1073741824
firecracker_cgroup_enabled = true
firecracker_cgroup_base = "/sys/fs/cgroup/pepper"
[auth]
# Required for a non-loopback P2P listener; file must be >=32 bytes.
# cluster_secret_path = "/etc/pepper/cluster.secret"
# api_bearer_token = "replace-with-a-secret"
[limits]
max_block_bytes = 67108864
max_object_bytes = 1073741824
max_compute_timeout_seconds = 600
http_requests_per_minute = 6000
rpc_requests_per_minute = 6000
erasure_repair_max_concurrent_shards = 2
# erasure_repair_bytes_per_second = 10485760
[logging]
format = "pretty" # pretty or json
Validation and security rules
- api.bind_addr must be loopback.
- node.advertise_addr is required when node.listen_addr uses an unspecified address such as 0.0.0.0.
- A non-loopback P2P listener requires auth.cluster_secret_path. The secret must contain at least 32 bytes and have mode 0600 or stricter on Unix.
- At least one unique storage location with nonzero capacity is required.
- replication.default_factor is 1–64; repair_interval_seconds is 5–86400.
- Erasure data and parity counts must be nonzero, parity cannot exceed data, and their sum cannot exceed 32.
- compute.runtime must be firecracker. Input and output limits must each be 1 byte–16 GiB.
- Jailer UID and GID must be nonzero when the jailer is enabled.
- limits.max_block_bytes cannot exceed 64 MiB; max_object_bytes cannot exceed 1 TiB.
- logging.format is pretty or json.
Sections
[node]name; listen_addr; optional advertise_addr and failure_domain; placement_labels table.
[data]path for metadata, default identity, and node state.
[identity]optional key_path and generate_if_missing.
[api]loopback-only bind_addr.
[[storage.locations]]Repeatable path and max_capacity_bytes.
[network]bootstrap_peers socket-address array.
[replication]default_factor and repair_interval_seconds.
[erasure]enabled, minimum object size, data_shards, and parity_shards.
[compute]Firecracker runtime, concurrency, binaries, jailer, rootfs policy, VM size, I/O limits, and cgroups.
[auth]cluster_secret_path and API bearer token.
[limits]Block/object/job, HTTP/RPC, and erasure-repair limits.
[logging]pretty or json format.
Firecracker rootfs policy
Each job supplies rootfs_cid. By default it must appear in firecracker_allowed_rootfs_cids. Setting firecracker_allow_untrusted_rootfs=true is an explicit development-only opt-out because host tooling parses the ext4 image before VM boot. The rootfs must contain an executable /pepper-guest-agent.