Skip to content

Commit 2b6f166

Browse files
cklinCopilot
andcommitted
Align worker container with runner ownership
Run the inference container with the host runner's UID/GID so it can write the checkout and result bind mounts after all capabilities are dropped. Set HOME to /tmp for writable CLI and package caches. Cover the launcher identity and privilege settings with a stub Docker executable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d63bcb34-3969-4d14-b422-33728176ec03
1 parent e60aeae commit 2b6f166

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

‎.github/dependabot-automation/controller.test.cjs‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,56 @@ test("rechecks provenance, labels, CI, and head immediately before merging", asy
12251225
}
12261226
});
12271227

1228+
test(
1229+
"container worker uses runner identity and writable home without elevated capabilities",
1230+
{ skip: process.platform === "win32" },
1231+
(t) => {
1232+
const workspace = temporaryWorkspace(t);
1233+
const trusted = path.join(
1234+
workspace,
1235+
"trusted/.github/dependabot-automation",
1236+
);
1237+
fs.mkdirSync(trusted, { recursive: true });
1238+
for (const name of ["task", "dependency", "bin"]) {
1239+
fs.mkdirSync(path.join(workspace, name));
1240+
}
1241+
for (const name of ["prompt.txt", "worker.cjs", "repair-protocol.cjs"]) {
1242+
fs.copyFileSync(path.join(__dirname, name), path.join(trusted, name));
1243+
}
1244+
const callsFile = path.join(workspace, "docker-calls.jsonl");
1245+
fs.writeFileSync(
1246+
path.join(workspace, "bin/docker"),
1247+
'#!/usr/bin/env node\nconst fs = require("node:fs");\nfs.appendFileSync(process.env.DOCKER_CALLS, JSON.stringify(process.argv.slice(2)) + "\\n");\n',
1248+
{ mode: 0o755 },
1249+
);
1250+
execFileSync("bash", [path.join(__dirname, "run-worker.sh")], {
1251+
cwd: workspace,
1252+
env: {
1253+
...process.env,
1254+
PATH: `${path.join(workspace, "bin")}${path.delimiter}${process.env.PATH}`,
1255+
DOCKER_CALLS: callsFile,
1256+
GITHUB_TOKEN: "test-token",
1257+
},
1258+
});
1259+
const calls = fs
1260+
.readFileSync(callsFile, "utf8")
1261+
.trim()
1262+
.split("\n")
1263+
.map((line) => JSON.parse(line));
1264+
assert.equal(calls.length, 2);
1265+
assert(!calls[0].includes("GITHUB_TOKEN"));
1266+
const worker = calls[1];
1267+
assert.equal(
1268+
worker[worker.indexOf("--user") + 1],
1269+
`${process.getuid()}:${process.getgid()}`,
1270+
);
1271+
assert(worker.includes("HOME=/tmp"));
1272+
assert(worker.includes("GITHUB_TOKEN"));
1273+
assert(worker.includes("--cap-drop=ALL"));
1274+
assert(worker.includes("--security-opt=no-new-privileges"));
1275+
},
1276+
);
1277+
12281278
test("worker collects tracked edits, new tests, and deletions", (t) => {
12291279
const work = temporaryWorkspace(t);
12301280
const git = (...args) =>

‎.github/dependabot-automation/run-worker.sh‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ docker run --rm \
1010
npm install --prefix /task/cli @github/copilot@1.0.104
1111

1212
docker run --rm --init --cpus=2 --memory=6g \
13+
--user "$(id -u):$(id -g)" \
1314
--cap-drop=ALL --security-opt=no-new-privileges \
14-
-e GITHUB_TOKEN -e COPILOT_HOME=/tmp/copilot \
15+
-e GITHUB_TOKEN -e HOME=/tmp -e COPILOT_HOME=/tmp/copilot \
1516
-e GIT_CONFIG_COUNT=1 -e GIT_CONFIG_KEY_0=safe.directory \
1617
-e GIT_CONFIG_VALUE_0=/work \
1718
-e PATH=/task/cli/node_modules/.bin:/usr/local/bin:/usr/bin:/bin \

0 commit comments

Comments
 (0)