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_PTRACE to enable process debugging tools like strace inside workflow steps.
  • Remove dangerous defaults – Drop NET_ADMIN or NET_RAW to 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-add and --container-cap-drop affect 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.go before 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →