mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:40:44 +00:00
fix(docker): require single primary key before Docker apt GPG pin (#74254)
Merged via squash.
Fixes #74234.
Prepared head SHA: c09ca96153
Reviewed-by: @sallyom
This commit is contained in:
@@ -239,9 +239,16 @@ RUN --mount=type=cache,id=openclaw-bookworm-apt-cache,target=/var/cache/apt,shar
|
||||
ca-certificates curl gnupg && \
|
||||
install -m 0755 -d /etc/apt/keyrings && \
|
||||
# Verify Docker apt signing key fingerprint before trusting it as a root key.
|
||||
# Require exactly one primary key (`pub` in --with-colons; subkeys use `sub`) so we
|
||||
# never pin the first fingerprint while apt trusts extra keys from the same file.
|
||||
# Update OPENCLAW_DOCKER_GPG_FINGERPRINT when Docker rotates release keys.
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg.asc && \
|
||||
expected_fingerprint="$(printf '%s' "$OPENCLAW_DOCKER_GPG_FINGERPRINT" | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]')" && \
|
||||
docker_gpg_pub_count="$(gpg --batch --show-keys --with-colons /tmp/docker.gpg.asc | awk -F: '$1 == "pub" { c++ } END { print c+0 }')" && \
|
||||
if [ "$docker_gpg_pub_count" != "1" ]; then \
|
||||
echo "ERROR: Docker apt key must contain exactly one public key (found $docker_gpg_pub_count); refusing a multi-key file." >&2; \
|
||||
exit 1; \
|
||||
fi && \
|
||||
actual_fingerprint="$(gpg --batch --show-keys --with-colons /tmp/docker.gpg.asc | awk -F: '$1 == "fpr" { print toupper($10); exit }')" && \
|
||||
if [ -z "$actual_fingerprint" ] || [ "$actual_fingerprint" != "$expected_fingerprint" ]; then \
|
||||
echo "ERROR: Docker apt key fingerprint mismatch (expected $expected_fingerprint, got ${actual_fingerprint:-<empty>})" >&2; \
|
||||
|
||||
@@ -146,6 +146,24 @@ describe("Dockerfile", () => {
|
||||
expect(dockerfile).not.toContain('\\"fpr\\"');
|
||||
});
|
||||
|
||||
it("counts primary pub keys before Docker apt fingerprint compare and dearmor", async () => {
|
||||
const dockerfile = collapseDockerContinuations(await readFile(dockerfilePath, "utf8"));
|
||||
const anchor = dockerfile.indexOf(
|
||||
"curl -fsSL https://download.docker.com/linux/debian/gpg -o /tmp/docker.gpg.asc",
|
||||
);
|
||||
expect(anchor).toBeGreaterThan(-1);
|
||||
const slice = dockerfile.slice(anchor);
|
||||
expect(slice).toContain("docker_gpg_pub_count=");
|
||||
expect(slice).toContain('$1 == "pub"');
|
||||
expect(slice).not.toContain('\\"pub\\"');
|
||||
const pubCountIdx = slice.indexOf("docker_gpg_pub_count=");
|
||||
const fpIdx = slice.indexOf("actual_fingerprint=");
|
||||
const dearmorIdx = slice.indexOf("gpg --dearmor");
|
||||
expect(pubCountIdx).toBeLessThan(fpIdx);
|
||||
expect(fpIdx).toBeLessThan(dearmorIdx);
|
||||
expect(slice).toContain('[ "$docker_gpg_pub_count" != "1" ]');
|
||||
});
|
||||
|
||||
it("keeps runtime pnpm available", async () => {
|
||||
const dockerfile = await readFile(dockerfilePath, "utf8");
|
||||
expect(dockerfile).toContain("ENV COREPACK_HOME=/usr/local/share/corepack");
|
||||
|
||||
Reference in New Issue
Block a user