Running act in Privileged Docker Mode: A Complete Guide to the `--privileged` Flag
The --privileged flag in act grants workflow containers full Linux capabilities (device access, kernel module loading, and unrestricted syscalls) by passing the setting through Cobra CLI parsing → runner configuration → Docker SDK HostConfig.
Running act in privileged Docker mode is essential when your GitHub Actions workflows require low-level system operations that standard container security policies block. This open-source CLI tool (available at nektos/act) executes workflows locally by spinning up Docker containers, and the --privileged flag ensures those containers receive the same extended privileges as Docker's native --privileged runtime option. Understanding the internal data flow—from command-line parsing in cmd/root.go to the final Docker SDK invocation—helps you debug permission failures and secure your local CI/CD pipeline.
Architecture: How --privileged Flows Through the Codebase
The flag travels through six distinct layers before reaching the Docker Engine, each handled by specific source files in the repository.
CLI Flag Definition and Parsing
In cmd/root.go at line 90, the Cobra framework registers the flag:
rootCmd.Flags().BoolVar(&input.privileged, "privileged", false, "use privileged mode")
This binds the command-line argument to the Input struct field, making the value available during runner initialization.
Configuration Propagation
The parsed value moves into pkg/runner/runner.go at line 44, where the Config struct defines:
Privileged bool // use privileged mode
When act initializes a new run, this Config object embeds into RunContext (defined in pkg/runner/run_context.go), ensuring every workflow step can access the privileged setting via rc.Config.Privileged.
Container Creation for docker:// Steps
When executing a step that uses uses: docker://, the newStepContainer function in pkg/runner/step_docker.go (line 30) constructs the container input:
Privileged: rc.Config.Privileged
This bridges the runner configuration with the container abstraction layer.
Docker SDK Integration
The flag passes through two critical files in the container package:
-
CLI Options (
pkg/container/docker_cli.go, line 10): Exposes the flag to internal Docker option parsing withflags.BoolVar(&copts.privileged, "privileged", false, "Give extended privileges to this container") -
Runtime Execution (
pkg/container/docker_run.go, line 465): Translates the boolean into Docker'sHostConfig:
Privileged: input.Privileged,
This final assignment tells the Docker Engine to launch the container with unrestricted capabilities.
Practical Usage Examples
Running Full Workflows with Privileged Containers
Execute your entire workflow with elevated privileges when you need operations like modprobe or device mounting:
act --privileged -P ubuntu-latest=nektos/act-environments-ubuntu:20.04
The -P flag specifies a custom runner image, while --privileged ensures any step requiring kernel-level access succeeds without Operation not permitted errors.
Privileged Mode for Specific docker:// Steps
Target privileged mode for individual container steps in your workflow YAML:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Mount tmpfs filesystem
uses: docker://alpine
with:
args: sh -c "mount -t tmpfs none /mnt && echo 'Success'"
Then invoke act with:
act --privileged
The implementation in pkg/runner/step_docker.go automatically forwards the privileged flag to these transient containers.
Programmatic Configuration (Library Usage)
When embedding act as a Go library, enable privileged mode explicitly in the configuration struct:
cfg := &runner.Config{
Privileged: true, // Maps to pkg/runner/runner.go line 44
Workdir: "./my-project",
}
r, err := runner.New(cfg)
if err != nil {
log.Fatal(err)
}
This directly sets the Privileged field analyzed in pkg/runner/runner.go, bypassing CLI parsing while maintaining identical runtime behavior.
Key Implementation Files
cmd/root.go: Root command flag registration using Cobra; defines the--privilegedswitch and binds it to theInputstructpkg/runner/runner.go: Defines the canonicalConfigstruct with thePrivileged boolfield (line 44) that serves as the single source of truthpkg/runner/step_docker.go: Constructscontainer.NewContainerInputand mapsrc.Config.Privilegedto the container definition (line 30)pkg/container/docker_cli.go: Parses Docker-specific CLI options, including the privileged flag for container runtime settings (line 10)pkg/container/docker_run.go: Final translation layer that assignsPrivileged: input.Privilegedto the Docker SDKHostConfig(line 465)
Summary
- The
--privilegedflag propagates fromcmd/root.gothroughrunner.Configto the Docker SDK'sHostConfig.Privilegedfield - Use it when workflows require kernel module loading, device access, or mounting filesystems that standard containers cannot perform
- Implementation spans six source files across the CLI, runner, and container packages, ensuring type-safe boolean propagation
- Security warning: Privileged mode grants the container the same power as the host root user—only enable it for trusted workflows
- Library users can set
runner.Config.Privileged = truedirectly without using command-line arguments
Frequently Asked Questions
What does the --privileged flag do in act?
The flag grants workflow containers full Linux capabilities by setting Privileged: true in the Docker SDK HostConfig, equivalent to Docker's native --privileged runtime option. According to the source in pkg/container/docker_run.go, this allows the container to access all host devices, load kernel modules, and bypass standard syscall restrictions.
Is it safe to run act with --privileged?
Running act in privileged Docker mode exposes your host system to the same risks as running any privileged container—workflow steps gain root-equivalent access to your kernel and hardware. Only enable this flag when executing trusted workflows that specifically require capabilities like modprobe or device mounting, as implemented in pkg/runner/step_docker.go.
Why would I need privileged mode for GitHub Actions?
You need this mode when workflows perform low-level system operations that Docker's default seccomp profile blocks, such as mounting filesystems, accessing /dev devices, or loading kernel modules. The act tool forwards this requirement through runner.Config.Privileged to ensure local execution matches GitHub-hosted runner capabilities.
How do I verify that privileged mode is active?
Check the container runtime configuration by inspecting the HostConfig passed to the Docker client in pkg/container/docker_run.go. When Privileged is true, the Docker Engine logs will show "Privileged": true in the container creation JSON, and operations like mount -t tmpfs will succeed without permission errors inside the workflow step.
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 →