Skip to content

Commit d31754e

Browse files
docs(custom-actions): document runArgs whitelist + integration test
Adds a new 'Passing Docker run flags with runArgs' subsection under the local execution-mode docs covering the whitelist, the accepted --flag=value form, and a security warning about bind mounts and privileged mode. Includes a worked example that mounts the host's ADC credentials into a google/cloud-sdk container. Introduces an integration example at integration/examples/custom-actions-runargs/ demonstrating a hardened action (non-root user, dropped cap) and a gcloud credential-passthrough action. Extends TestExec_LocalActions with an 'action with runArgs overlay' case that asserts --user=1000:1000 pins uid=1000 inside the container and -e=SENTINEL=from-runargs reaches the process env.
1 parent 9030dba commit d31754e

4 files changed

Lines changed: 98 additions & 1 deletion

File tree

docs-v2/content/en/docs/custom-actions.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,53 @@ A Custom Action has an execution mode associated with it that indicates Skaffold
109109

110110
This is the default configuration when no [`customActions[].executionMode`]({{< relref "/docs/references/yaml/#customActions-executionMode" >}}) is specified. With this execution mode, Skaffold will run every container associated to a given Custom Action with a Docker daemon.
111111

112+
##### Passing Docker run flags with `runArgs`
113+
114+
When an action needs to reach host resources (for example your local
115+
`~/.config/gcloud` credentials) or to tighten its runtime (dropping
116+
capabilities, pinning a non-root user), use
117+
[`customActions[].executionMode.local.runArgs`]({{< relref
118+
"/docs/references/yaml/#customActions-executionMode-local-runArgs" >}}).
119+
Skaffold parses each entry with a whitelist and overlays the result on
120+
the Docker `HostConfig`/`Config` used to start the container:
121+
122+
| Flag | Effect |
123+
| --- | --- |
124+
| `--network=<mode>` | Sets `HostConfig.NetworkMode`. Accepts `host`, `bridge`, `none`, or a named network. |
125+
| `-v=<src>:<dst>[:opts]`, `--volume=<src>:<dst>[:opts]` | Appends to `HostConfig.Binds`. |
126+
| `-e=<KEY>=<VALUE>`, `--env=<KEY>=<VALUE>` | Appends to `Config.Env`. |
127+
| `--user=<uid[:gid]>` | Sets `Config.User`. |
128+
| `--add-host=<host>:<ip>` | Appends to `HostConfig.ExtraHosts`. |
129+
| `--tmpfs=<path>[:opts]` | Merges into `HostConfig.Tmpfs`. |
130+
| `--privileged` | Sets `HostConfig.Privileged=true`. |
131+
| `--cap-add=<CAP>`, `--cap-drop=<CAP>` | Appends to `HostConfig.CapAdd`/`CapDrop`. |
132+
133+
Only the `--flag=value` form is accepted — space-separated values and
134+
unknown flags are rejected at load time so typos fail loudly rather
135+
than silently dropping settings.
136+
137+
```yaml
138+
customActions:
139+
- name: reuse-local-adc
140+
executionMode:
141+
local:
142+
runArgs:
143+
- "-v=/root/.config/gcloud:/root/.config/gcloud:ro"
144+
- "--network=host"
145+
- "-e=CLOUDSDK_CORE_PROJECT=my-project"
146+
containers:
147+
- name: gcloud
148+
image: google/cloud-sdk:slim
149+
command: ["gcloud"]
150+
args: ["auth", "list"]
151+
```
152+
153+
> **Security note:** `runArgs` bypasses Skaffold's sandbox and hands
154+
> raw flags to the host Docker daemon. Avoid committing `--privileged`,
155+
> broad bind mounts (`-v=/:/host`) or secret values to source control.
156+
> Prefer deploy parameters or environment files for per-invocation
157+
> overrides.
158+
112159
#### Remote (K8s job)
113160

114161
With this execution mode, Skaffold will create a K8s job for each container associated with the given action. For the following configuration:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
apiVersion: skaffold/v4beta15
2+
kind: Config
3+
metadata:
4+
name: custom-actions-runargs
5+
6+
customActions:
7+
- name: hardened-action
8+
executionMode:
9+
local:
10+
runArgs:
11+
- "--user=1000:1000"
12+
- "--cap-drop=NET_RAW"
13+
- "-e=SENTINEL=hardened"
14+
containers:
15+
- name: hardened
16+
image: alpine:3.20
17+
command: ["/bin/sh"]
18+
args: ["-c", "echo uid=$(id -u) && echo sentinel=$SENTINEL"]
19+
20+
- name: gcloud-auth-list
21+
executionMode:
22+
local:
23+
runArgs:
24+
- "-v=/root/.config/gcloud:/root/.config/gcloud:ro"
25+
- "--network=host"
26+
containers:
27+
- name: gcloud
28+
image: google/cloud-sdk:slim
29+
command: ["gcloud"]
30+
args: ["auth", "list"]

integration/exec_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ func TestExec_LocalActions(t *testing.T) {
6767
"[task7] bye-from-env-file",
6868
},
6969
},
70+
{
71+
description: "action with runArgs overlay",
72+
action: "action-runargs",
73+
expectedMsgs: []string{
74+
"[runargs-task] uid=1000",
75+
"[runargs-task] sentinel=from-runargs",
76+
},
77+
},
7078
}
7179

7280
for _, test := range tests {

integration/testdata/custom-actions-local/skaffold.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,16 @@ customActions:
7676
image: localtaks
7777
env:
7878
- name: FOO
79-
value: from-local-img
79+
value: from-local-img
80+
81+
- name: action-runargs
82+
executionMode:
83+
local:
84+
runArgs:
85+
- "--user=1000:1000"
86+
- "-e=SENTINEL=from-runargs"
87+
containers:
88+
- name: runargs-task
89+
image: alpine:3.15.4
90+
command: ["/bin/sh"]
91+
args: ["-c", "echo uid=$(id -u) && echo sentinel=$SENTINEL"]

0 commit comments

Comments
 (0)