Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Capability matrix

Every operation CSM performs that needs privilege beyond reading its own files, or that writes outside its own directories, with the privilege it needs and the setting that stops it.

Print it on any host, before or after install:

csm privileges              # table
csm privileges --json       # machine-readable

The command prints a static inventory. It does not load CSM configuration or probe host privileges, so it can be used before installing the service. Output failures produce a nonzero exit status in text, JSON and Markdown formats.

How to read it

Needs is what the operation requires from the kernel. root means uid 0 rather than one capability: the operation reads or writes files owned by many different accounts, or drives a panel tool that assumes root. Today the daemon runs as a single root process; splitting it into a small privileged helper plus a reduced-privilege main process is planned, and this inventory is its first stage. Capability names describe the privileged kernel interfaces as well as the root filesystem access. For BPF, tracing and LSM programs need CAP_BPF plus CAP_PERFMON; cgroup socket programs need CAP_BPF plus CAP_NET_ADMIN. CAP_SYS_ADMIN is the broader fallback on older kernels. These requirements follow the kernel program-load checks.

Trigger is automatic when the daemon may start the operation on its own, and operator when it runs only in response to a command or a button. Not running the command is how an operator operation is turned off.

Writes lists what the operation writes while it runs, including writes made by a tool it invokes. Paths starting with / are filesystem paths; everything else is a resource named <kind>:<name>. “nothing (read-only)” means the operation only reads. Paths describe default locations; configured account roots, state, rule, log, spool and policy paths replace those defaults and may require service drop-ins. Shared CSM state and audit-log writes are grouped in the state rows. This is not a list of every possible path written by an external panel tool.

Turn it off is the config key and YAML value that stops the named operation. Dotted keys describe nested YAML mappings; they are not literal top-level keys. Apply changes before restarting the daemon: several controls are read only at startup. A row saying “not configurable” has no single config switch that stops all its callers. disabled_checks takes a list and only affects scheduled checks. Stopping new work does not undo installed rules, hooks, quarantines or blocks; use the subsystem removal commands for that. Disabling the forward guard removes its existing Exim configuration, which is itself a host write.

Action record says whether the operation writes to the action log. “no” does not mean the operation is silent; it means it is not on that stream yet and the daemon log is where it appears.

Without the privilege is what an operator loses by withholding it, so the row reads as a decision rather than a demand.

Relationship to the systemd sandbox

The daemon runs under ProtectSystem=strict with an explicit writable-path allow-list; see service confinement. The two lists are compared by tests: every declared in-daemon filesystem write must fit a packaged grant, and every grant must have an in-daemon writer. Empty inventories and grant lists fail. Paths are compared on directory boundaries, and an operation outside the sandbox cannot justify a daemon grant. The unit parser rejects invalid paths and unsupported syntax, including continuations, specifiers and directory flags, instead of guessing which locations are writable. Tests cannot discover omitted operations or prove the privilege and disable claims; those require tracing the runtime code.

Operations marked “outside the systemd sandbox” run as standalone operator commands or transient services forked by PID 1. The latter use direct execution on hosts without a reachable systemd service manager. Mixed operations have separate rows for their in-daemon writes, such as the AF_ALG marker repair and forward-guard lookup refresh. The service sandbox does not bound external tools.

Turning most of it off at once

mode: observe stops automatic remediation and integration deployment, and refuses configurations that enable those subsystems. It still maintains CSM state, loads temporary BPF capability probes in BPF builds, and invokes the KernelCare probe, which can update its own cache. It is not a guarantee of zero host writes. See observe mode.

The matrix

The risk tier says what can go wrong if an operation acts on the wrong target: 0 changes nothing outside CSM’s own directories, 1 records a recommendation or dry-run decision, 2 is a low-risk change such as a probe, challenge gate or mail hold, 3 quarantines, blocks or denies a target, and 4 signals processes, reloads services, or rewrites content or configuration. Rows describe maximum live effect, so preview-only tier 1 has no separate row today. A tier does not promise automatic rollback; see recovery gaps below and the current contracts in the JSON inventory. The TIER column of csm privileges and the JSON inventory use the same 0 to 4 numbers.

OperationNeedsTriggerRisk tierWritesTurn it offAction recordWithout the privilege
state.control_socket
create the private control socket used by operator commands
rootautomatic0/var/run/csmnot configurablenoCLI commands cannot reach the daemon
state.mail_relay_policies
load operator-supplied mailer classes and proxy ranges for the PHP-relay detector
noneautomatic0nothing (read-only)email_protection.php_relay.enabled: falsenoonly policy files readable by the daemon uid can be loaded
state.php_shield_events
receive PHP Shield events over a socket and append their local archive
rootautomatic0/var/log/csm-php-shieldphp_shield.enabled: falsenoPHP runtime events are not collected
state.sign_config
rewrite CSM’s own integrity hashes into csm.yaml after an approved change
rootoperator0/etc/csmdo not run the commandnothe integrity gate cannot be re-signed, so the next restart refuses to start after any config edit
state.update_forge
download and verify YARA Forge rules independently of YAML updates
rootautomatic0/opt/csm/rulessignatures.yara_forge.enabled: falsenoYARA Forge rules are not refreshed
state.update_signatures
download and signature-verify YAML malware rule updates
rootautomatic0/opt/csm/rulessignatures.update_url: ""nodetection freezes at the ruleset shipped with the installed package
state.write_deploy_script
refresh the embedded upgrade script in CSM’s own directory at startup
rootautomatic0/opt/csm/deploy.shmode: observenothe packaged upgrade helper is missing and upgrades are run by hand
state.write_logs
write the daemon log and the audit-log sinks that feed a SIEM
rootautomatic0/var/log/csmnot configurablenono local record of findings or actions
state.write_store
write the bbolt state database, baselines, incidents and scan reports
rootautomatic0/var/lib/csm, /opt/csm/statenot configurablenoCSM cannot run: without state there is no baseline, no dedup and no incident history
detect.account_databases
read account MySQL credentials and scan databases for injected content and stored objects
rootautomatic0nothing (read-only)not configurable: db_object_scanning only stops stored-object scans; content and requested scans remainnono database detection: injected admin users, poisoned options and malicious triggers stay invisible
detect.af_alg_sockets
deny AF_ALG sockets through BPF LSM, or observe socket use through the audit-log fallback
CAP_BPF, CAP_PERFMON, rootautomatic3kernel:AF_ALG socket denialdetection.af_alg_backend: nonenothe live monitor is gone; the periodic critical check still reports an exposed kernel
detect.audit_rules
query loaded audit rules with auditctl to check detection coverage
CAP_AUDIT_CONTROL, rootautomatic0nothing (read-only)not configurablenoaudit-rule coverage cannot be verified
detect.bpf_probe
load and briefly attach BPF LSM, tracepoint and cgroup programs to discover kernel support
CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, rootautomatic2kernel:temporary BPF programs and mapsnot configurable: capability discovery runs independently of monitor settings in BPF buildsnoBPF capabilities report unavailable; configured automatic backends use their fallbacks
detect.filesystem_events
fanotify stream over account roots and world-writable temp directories
CAP_SYS_ADMINautomatic0nothing (read-only)not configurablenono real-time file detection; scheduled scans still run, so a webshell lives until the next cycle
detect.kernel_livepatch_probe
run kcarectl –patch-info to see whether a KernelCare livepatch covers Copy Fail; kcarectl rewrites its own cache on every run
rootautomatic2/var/cache/kcarenot configurable: the startup kernel probe and hardening audits also invoke kcarectl, including in observe modenoa patched kernel reads as vulnerable, so the AF_ALG finding cannot be cleared
detect.kernel_oom
read the restricted kernel message buffer with dmesg to find recent OOM kills
CAP_SYSLOG, rootautomatic0nothing (read-only)not configurablenoswap statistics remain available, but OOM kills are not reported
detect.mail_queue_probe
query the Exim queue through a transient unit, because Exim opens its logs even to answer a read
rootautomatic2/var/log/exim_mainlog, /var/log/exim_paniclog, /var/log/exim4 (outside the systemd sandbox)disabled_checks: [mail_queue]noqueue depth is unknown, so a queue-size spam outbreak may go undetected
detect.outbound_connections
watch outbound connections through BPF cgroup hooks, or by polling /proc/net/tcp
CAP_BPF, CAP_NET_ADMIN, rootautomatic2kernel:BPF programs and mapsdetection.connection_tracker_backend: nonenoauto mode uses polling; an explicitly selected BPF backend stays unavailable
detect.pam_events
receive authentication attempts from the pam_csm.so hook over a private socket
rootautomatic0/var/run/csmnot configurablenono immediate brute-force or credential-stuffing block; log parsing lags by up to a minute
detect.process_exec
watch process execution through a BPF tracepoint, or by walking /proc
CAP_BPF, CAP_PERFMON, rootautomatic2kernel:BPF programs and mapsdetection.exec_monitor_backend: nonenoauto mode uses periodic /proc sampling; an explicitly selected BPF backend stays unavailable
detect.read_service_logs
read mail, authentication, web server and ModSecurity logs
rootautomatic0nothing (read-only)not configurablenono mail abuse, brute-force or WAF detection: these logs are root-readable only
detect.scan_account_files
read every account’s files for scheduled, real-time and on-demand scans
CAP_DAC_READ_SEARCH, rootautomatic0nothing (read-only)not configurable: disabled_checks only suppresses scheduled checks; realtime and requested scans remainnoonly files readable by CSM’s own uid are scanned, which on a shared host is close to nothing
detect.sensitive_file_writes
watch writes to /etc/shadow and comparable files through a BPF LSM hook
CAP_BPF, CAP_PERFMON, rootautomatic2kernel:BPF programs and mapsdetection.sensitive_files_backend: nonenosensitive-file changes are found by periodic hashing instead of at the moment of the write
integrate.auditd_rules
write CSM’s auditd rules and reload them, so audit-backed detection survives package upgrades
CAP_AUDIT_CONTROL, rootautomatic4/etc/audit, kernel:audit rulesmode: observenoaudit-backed detection layers stay inactive after an upgrade
integrate.challenge_port_gate
install the separate nftables port gate for the public challenge listener
CAP_NET_ADMIN, rootautomatic2nftables:challenge port gatechallenge.port_gate.enabled: falsenothe listener remains reachable without the challenge port filter
integrate.challenge_snippet
refresh the web server snippet and rewrite maps that route challenged visitors to CSM’s proof-of-work listener, and reload the web server when the snippet changed
rootautomatic4/etc/apache2/conf.d, /etc/apache2/conf-enabled, /etc/httpd/conf.d, /etc/nginx/conf.d, /usr/local/lsws/conf/templates, /var/cache/csm, service:web server reloadmode: observenosuspicious visitors are blocked outright instead of being offered a challenge
integrate.firewall_ruleset
build and load CSM’s nftables table, including the operator’s port policy and rate limits
CAP_NET_ADMIN, rootautomatic4nftables:csm tablefirewall.enabled: falseyesno firewall management; another tool owns the host’s packet policy
integrate.modsec_section
refresh the managed ModSecurity section at startup and during periodic WAF checks, preserving operator configuration
rootautomatic4/etc/apache2/conf.d, /usr/local/apache/confmode: observenoCSM’s virtual-patch WAF rules are not installed
integrate.panel_plugin
deploy the WHM plugin CGI and its AppConfig entry, and register it with the panel
rootautomatic4/usr/local/cpanel/whostmgr/docroot/cgi, /var/cpanelmode: observenono panel plugin; the web UI is still reachable on its own port
integrate.php_shield
install the PHP runtime hook and register its shared event directory for an operator-scheduled CageFS remount
rootoperator4/opt/csm, /var/log/csm-php-shield, /etc/cagefs, /etc/csm, /opt/cpanel, /opt/alt, /usr/local/lsws, php:runtime configuration (outside the systemd sandbox)do not run the commandnono PHP runtime blocking of uploads and temp-directory execution
integrate.waf_vendor_rules
ask the panel to update stale ModSecurity vendor rulesets when a periodic check finds them out of date
rootautomatic4/etc/apache2/conf.d, /usr/local/apache/conf, /var/cpanel, service:web server reloadmode: observenostale WAF rules are reported but not refreshed
operate.export_archives
read protected configuration, state or account evidence and export backup or forensic archives, temporary snapshots and checksum sidecars
rootoperator4filesystem:operator-selected archive destinations (outside the systemd sandbox)do not run the commandnoprotected configuration, state and account evidence cannot be exported completely
operate.harden_host
apply a supported CVE mitigation: a modprobe blacklist, or seccomp drop-ins for the services that need one
CAP_SYS_MODULE, rootoperator4/etc/modprobe.d, /etc/systemd/system, service:restart, kernel:modules (outside the systemd sandbox)do not run the commandnothe mitigation is applied by hand from the command the audit prints
operate.install_service
install or remove CSM itself: the systemd unit, the PAM hook, logrotate and the panel integrations
CAP_AUDIT_CONTROL, CAP_LINUX_IMMUTABLE, rootoperator4/opt/csm, /etc/csm, /var/lib/csm, /var/log/csm, /etc/systemd/system, /etc/pam.d, /etc/logrotate.d, /etc/audit, /usr/sbin/csm, /lib64/security, /usr/lib64/security, /lib/security, /lib/x86_64-linux-gnu/security, /usr/lib/x86_64-linux-gnu/security, /lib/aarch64-linux-gnu/security, /usr/lib/aarch64-linux-gnu/security, /usr/local/cpanel/whostmgr/docroot/cgi, /var/cpanel, service:csm and panel integrations, /etc/cron.d, /var/cache/csm, /opt/cpanel, /var/run/csm, /etc/apache2/conf.d, /etc/apache2/conf-enabled, /etc/httpd/conf.d, /etc/nginx/conf.d, /usr/local/apache/conf, /usr/local/lsws/conf/templates (outside the systemd sandbox)do not run the commandnoCSM cannot be installed as a service
operate.manual_firewall
block, allow, tempban or flush addresses on request, and roll a firewall apply back
CAP_NET_ADMIN, rootoperator3nftables:csm setsdo not run the commandyesfirewall changes are made with nft or the panel’s own tooling
operate.manual_remediation
clean or quarantine files and spool messages, truncate malicious crontabs, kill verified malware processes, or change database objects on request
CAP_KILL, rootoperator4/home, /tmp, /var/tmp, /dev/shm, /var/spool/cron, /var/spool/exim/input, /var/spool/exim4/input, /opt/csm/quarantine, mysql:account databases, process:signaldo not run the commandnoremediation is done by hand over SSH
operate.rehash
re-sign configuration, converge legacy config copies, set binary immutability and refresh the launcher, service and log rotation
CAP_LINUX_IMMUTABLE, rootoperator4/opt/csm, /etc/csm, /etc/systemd/system, /etc/logrotate.d, /usr/sbin/csm, service:daemon reload (outside the systemd sandbox)do not run the commandnohash signing and upgrade integration refresh cannot complete
operate.restore_backup
stage and restore protected configuration, drop-ins and state from a backup while the daemon is stopped
rootoperator4/etc/csm, /var/lib/csm, /opt/csm, /tmp (outside the systemd sandbox)do not run the commandnoconfiguration and state cannot be restored
operate.truncate_error_log
empty an account error log that has grown large enough to threaten the filesystem
rootoperator4/homedo not run the commandnoa bloated log is reported and truncated by hand
respond.af_alg_enforce
unload the AF_ALG kernel modules again when an opted-in mitigation marker is present
CAP_SYS_MODULE, rootautomatic4kernel:modules (outside the systemd sandbox)auto_response.disable_enforce_af_alg: truenoa module reload silently reopens the Copy Fail exposure
respond.af_alg_kill
kill a verified AF_ALG socket caller through the separate Copy Fail response setting
CAP_KILL, rootautomatic4process:signalauto_response.copy_fail_kill_process: falsenothe process is reported but remains running; this path is independent of kill_processes
respond.af_alg_marker
restore a changed AF_ALG mitigation marker after the operator has opted in
rootautomatic4/etc/modprobe.dauto_response.disable_enforce_af_alg: truenoa changed module blacklist is reported but cannot be repaired
respond.block_ip
add an attacker address or subnet to the firewall’s deny sets
CAP_NET_ADMIN, rootautomatic3nftables:csm setsauto_response.block_ips: falseyesattacks are reported but not stopped; dry-run records what would have been blocked
respond.bpf_deny_egress
deny matched outbound connections in the kernel through a BPF cgroup hook
CAP_BPF, CAP_NET_ADMIN, rootautomatic3kernel:bpf cgroup programbpf_enforcement.enabled: falsenodirect-to-MX spam egress is detected but not stopped at the source
respond.clean_file
strip injected code from a PHP or access file, keeping a pre-clean backup
rootautomatic4/home, /tmp, /var/tmp, /dev/shm, /opt/csm/quarantineauto_response.enabled: falseyesinjected files are reported and left in place
respond.database_cleanup
revoke a rogue CMS admin, sanitize poisoned options, and drop confirmed malicious stored objects after recording their definition
rootautomatic4mysql:account databasesauto_response.clean_database: falsenodatabase persistence survives file cleanup and re-infects the account
respond.enforce_permissions
chmod a world-writable or group-writable PHP file back to 644
rootautomatic3/homeauto_response.enforce_permissions: falsenowritable code files are reported only
respond.fix_wp_cron
disable WP-Cron for an account and install a per-user system cron entry instead
rootautomatic4/home, /var/spool/cron, /tmpauto_response.fix_wp_cron: falsenorunaway WP-Cron load is reported only
respond.forward_guard
install or remove the managed Exim block that holds forwarded spam and backscatter, and rebuild the Exim configuration
rootautomatic4/etc/exim.conf.local, /etc/exim.conf, /var/lib/csm, exim:rebuild artifacts and service reload (outside the systemd sandbox)mode: observenoforwarded spam keeps damaging the host’s sending reputation
respond.forward_guard_lookup
refresh the forward-guard bad-sender lookup inside the daemon sandbox
rootautomatic0/var/lib/csm/forward_guardemail_protection.forward_guard.enabled: falsenoExim continues using the last successfully written sender lookup
respond.freeze_mail
freeze queued Exim messages attributed to a confirmed PHP-relay finding
rootautomatic2/var/spool/exim/input, /var/spool/exim4/input, /var/log/exim_mainlog, /var/log/exim_paniclog, /var/log/exim4 (outside the systemd sandbox)auto_response.php_relay.freeze: falsenoa compromised script keeps sending until an operator freezes the queue
respond.hold_outgoing_mail
request a cPanel account outgoing-mail hold through whmapi1 after sustained mail abuse
rootautomatic2cpanel:account outgoing mail holdauto_response.enabled: falsenothe mail abuse finding is reported but the account can continue sending
respond.kill_process
signal a malicious process through a kernel process handle, never a recycled PID, never root
CAP_KILL, rootautomatic4process:signalauto_response.kill_processes: falseyesreverse shells and miners keep running until an operator kills them
respond.mail_delivery_gate
defer Exim delivery with fanotify permission responses when tempfail policy requires it
CAP_SYS_ADMIN, rootautomatic2fanotify:mail delivery decisionsemail_av.enabled: falsenomail AV falls back to notifications and cannot defer delivery on scan failures
respond.quarantine_file
move a confirmed malicious file out of an account tree into CSM’s quarantine, preserving owner, permissions and mtime
rootautomatic3/home, /tmp, /var/tmp, /dev/shm, /opt/csm/quarantineauto_response.quarantine_files: falseyesmalware is reported and left in place
respond.quarantine_mail
move an infected message out of the Exim spool after an antivirus match
rootautomatic3/var/spool/exim/input, /var/spool/exim4/input, /opt/csm/quarantineemail_av.quarantine_infected: falsenoinfected mail is reported and delivered
respond.restart_mail_auth
restart the panel’s mail authentication service after a sustained outage
rootautomatic4service:mail authenticationauto_response.mail_auth_recovery.restart_enabled: falsenoan authentication backend outage is alerted but not repaired
respond.virtual_patch
write a reversible deny rule into an account access file to close an exposed file
rootautomatic3/home, /opt/csm/quarantineauto_response.virtual_patch_exposed_files: offnoexposed backups, dumps and configs stay reachable until the account owner fixes them

Regenerate the table with go run ./cmd/csm privileges --markdown. A gate in internal/ci fails when the page and the inventory disagree.

Risk tiers and recovery coverage

csm privileges --json reports each operation’s risk tier as a number from 0 to 4. A row with no tier would report -1; the test suite refuses such an inventory, so a release never ships one. The tier is the operation’s maximum live effect on a wrong target. It is not the severity of the finding that triggered the operation.

Seven operations carry a safety contract in the JSON inventory: respond.block_ip, operate.manual_firewall, integrate.firewall_ruleset, integrate.challenge_port_gate, integrate.challenge_snippet, respond.quarantine_file and respond.clean_file. Each states the authority it needs, how the target is revalidated before the change, how the change is reversed, and the limit that bounds it. The contracts describe current behaviour, including what it does not cover. Every other operation that changes the host states the recovery this inventory does not yet cover:

OperationsRecovery gap
detect.bpf_probe, detect.outbound_connections, detect.process_exec, detect.sensitive_file_writes, detect.af_alg_sockets, respond.bpf_deny_egressThis inventory does not yet specify verified detach, map restoration and crash recovery for these kernel hooks.
detect.kernel_livepatch_probe, detect.mail_queue_probeThis inventory does not specify recovery of incidental external cache or log writes by probe commands.
respond.mail_delivery_gate, respond.hold_outgoing_mail, respond.freeze_mail, respond.quarantine_mailThis inventory does not yet specify identity checks for releasing or restoring mail, or recovery after a restart.
respond.af_alg_enforce, respond.af_alg_marker, respond.forward_guard, respond.fix_wp_cron, integrate.auditd_rules, integrate.modsec_section, integrate.panel_plugin, integrate.php_shield, integrate.waf_vendor_rules, operate.harden_host, operate.install_service, operate.rehash, operate.restore_backupThis inventory does not specify an action-wide snapshot and verified rollback of configuration, service and external-tool side effects.
respond.af_alg_kill, respond.kill_process, respond.restart_mail_authProcess termination and restart cannot restore lost process state; this inventory does not yet specify a full recovery contract.
respond.database_cleanup, respond.virtual_patch, respond.enforce_permissions, operate.manual_remediation, operate.truncate_error_logCurrent remediation may retain local recovery evidence, but per-operation identity-checked undo and partial-failure recovery are not specified by this inventory.
operate.export_archivesExport can replace an existing operator-selected archive; removing the new archive does not restore overwritten bytes.