Managing Container Capabilities in act with --container-cap-add and --container-cap-drop
Use --container-cap-add to grant kernel capabilities and --container-cap-drop to remove them from every container act launches, enabling precise security control for your GitHub Actions workflows.
The nektos/act tool lets you run GitHub Actions locally using Docker containers. When workflows require specific Linux kernel privileges or need to run with hardened permissions, managing container capabilities directly from the command line becomes essential for maintaining both functionality and security.
How act Processes Capability Flags
The capability flags flow through six distinct stages from user input to Docker runtime execution. Understanding this path helps debug permission issues and verify that your security policies are correctly applied.
CLI Flag Definition
In cmd/root.go (lines 93-94), act declares the --container-cap-add and --container-cap-drop flags on the root command. These accept string slices that users can specify multiple times or as comma-separated values.
Input Struct Population
The flag values are stored in the Input struct defined in cmd/input.go (lines 41-42). The struct fields containerCapAdd and containerCapDrop capture the user-specified capability lists before the runner starts.
Runner Configuration
When the runner initializes in pkg/runner/runner.go (lines 51-52), the input values are copied into the runner's Config struct as ContainerCapAdd and ContainerCapDrop. This makes the capabilities available throughout the runner's lifecycle.
Step Execution
During Docker step execution, the code in pkg/runner/step_docker.go (line 80) passes these capability slices to the container factory. This occurs for every container act creates, including job containers, step containers, and action containers.
Docker Host Configuration
The container factory in pkg/container/docker_cli.go (lines 61-62) constructs the Docker HostConfig. Here, the capability slices are assigned directly to the CapAdd and CapDrop fields, which correspond to Docker's native --cap-add and --cap-drop options.
Runtime Application
Finally, the Docker engine receives the HostConfig and applies the requested kernel capabilities to the container process when starting the container. This affects the security context of every command executed inside the container.
Why Manage Container Capabilities
Controlling capabilities allows you to balance functionality with security:
- Grant extra privileges – Add
SYS_PTRACEto enable process debugging tools likestraceinside workflow steps. - Remove dangerous defaults – Drop
NET_ADMINorNET_RAWto prevent network configuration changes when workflows do not require networking privileges. - Fine-tune security – Combine both flags to achieve least-privilege access, ensuring containers have only the specific capabilities required for the job.
Command-Line Examples
Adding a Capability
Grant the SYS_PTRACE capability to all containers to enable debugging:
act --container-cap-add SYS_PTRACE
Combining Add and Drop Operations
Remove raw socket access while adding system administration capabilities:
act \
--container-cap-drop NET_RAW \
--container-cap-add SYS_ADMIN
Targeting Specific Jobs
Apply capability restrictions to a single job while maintaining global container settings:
act -j build \
--container-cap-add SYS_TIME \
--container-cap-drop MKNOD
Integration with Other Options
Combine capability management with container reuse for faster workflow testing:
act -j test \
--reuse \
--container-cap-add CHOWN \
--container-cap-drop SETUID
Deprecation Notice
Older versions of act emitted warnings that these flags map to Docker's native capability options. While the functionality remains stable, the codebase in cmd/root.go (line 598) still logs a deprecation warning for backward compatibility when these flags are used.
Summary
- Capability flags are global:
--container-cap-addand--container-cap-dropaffect every container act launches during a run, including job containers and nested action containers. - Source code flow: Values travel from
cmd/root.go→cmd/input.go→pkg/runner/runner.go→pkg/runner/step_docker.go→pkg/container/docker_cli.gobefore reaching the Docker engine. - Security use cases: Use these flags to enable debugging tools, remove unnecessary privileges, or implement least-privilege security models for your local GitHub Actions workflows.
Frequently Asked Questions
Can I set different capabilities for individual steps in a workflow?
No. The --container-cap-add and --container-cap-drop flags are global settings that apply to all containers created during the act execution. According to the implementation in pkg/runner/step_docker.go, every Docker step receives the same capability configuration from the runner's Config struct. To vary capabilities, you must run act multiple times with different flag combinations.
Do these flags work with pre-existing containers when using --reuse?
No. When you use the --reuse flag to restart existing containers, Docker does not apply new capability settings during container restart. Capabilities are configured in pkg/container/docker_cli.go as part of the HostConfig during initial container creation. For capability changes to take effect, you must remove existing containers and allow act to create fresh ones.
What capabilities can I add or drop?
You can specify any Linux kernel capability supported by your Docker installation, such as SYS_PTRACE, NET_ADMIN, SYS_TIME, CHOWN, SETUID, or MKNOD. The values are passed directly to Docker's HostConfig as implemented in pkg/container/docker_cli.go, so any capability valid for docker run --cap-add or --cap-drop will work with act.
Are these flags available in all act versions?
These flags have been available for several versions, though early implementations logged deprecation warnings. As of recent versions, the functionality remains in cmd/root.go (lines 93-94) and is fully supported, with the deprecation warning at line 598 retained only for backward compatibility purposes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →