Skip to content

build: keep test certificate fixtures out of the images - #979

Merged
EliMoshkovich merged 4 commits into
masterfrom
eli/per-17672-dockerignore-test-certs
Oct 23, 2026
Merged

EliMoshkovich merged 4 commits into
masterfrom
eli/per-17672-dockerignore-test-certs

Conversation

@EliMoshkovich

@EliMoshkovich EliMoshkovich commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes Issue

Follow-up to #974, from review on #978 (its 0.9.x backport).

docker/Dockerfile runs COPY ./packages ./packages/, so the trust-store test's fixture packages/opal-common/opal_common/tests/emudhra_compromised_cas.pem ends up in every client and server image. The fixture holds the compromised eMudhra certificates (CVE-2026-111943). Nothing loads it as a trust anchor and it isn't in the wheels, so it's not a vulnerability. But the published detection guidance for this CVE searches an image's whole filesystem for those certificates by fingerprint, and it reports this file as affected in exactly the images #974 fixed.

Changes proposed

  • docker/Dockerfile: COPY --exclude=**/tests/*.pem ./packages ./packages/ in the common and common-alpine stages. .dockerignore alone isn't enough: CI and the release build with docker/build-push-action's default Git context, and BuildKit doesn't apply .dockerignore to a Git context. --exclude needs dockerfile frontend 1.19 or later, so the first line is # syntax=docker/dockerfile:1.19, pinned by digest.
  • .dockerignore: the same pattern, for local builds.
  • tests.yml: both E2E jobs fail if any *.pem is under /opal/packages in the client or server image. The check first confirms it can see the test modules, so it can't pass by seeing nothing.

The fixture stays in git, so the test still finds it.

Verification

  • Built from the Git context, as CI does: no .pem in any of the four images, the other test files still copied, and /opal/check_trust_store.py passes. As a control, the published 0.9.10-rc.2 images still contain the fixture.
  • CI's new check reports no .pem in all four images.
  • DOCKER_BUILDKIT=0 docker build --target common still builds and leaves the fixture out.

Check List (Check all the applicable boxes)

  • I sign off on contributing this submission to open-source
  • My code follows the code style of this project.
  • My change requires changes to the documentation.
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • This PR does not contain plagiarized content.
  • The title of my pull request is a short description of the requested changes.

🤖 Generated with Claude Code

`COPY ./packages` put the trust-store test's fixture, which holds the
compromised eMudhra certificates, in every client and server image, where an
image scanner looking for those certificates finds it. Nothing loads it as a
trust anchor, and the wheels never had it. The fixture stays in git for the
test; only the Docker build context drops it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@EliMoshkovich
EliMoshkovich requested review from zeevmoney and a balanced review from Copilot October 22, 2026 19:36
@linear-code

linear-code Bot commented Oct 22, 2026

Copy link
Copy Markdown

PER-17672

@netlify

netlify Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for opal-docs canceled.

Name Link
🔨 Latest commit cea391b
🔍 Latest deploy log https://app.netlify.com/projects/opal-docs/deploys/6adb7f037e494485369ffb20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI balanced review requested due to automatic review settings October 22, 2026 21:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@EliMoshkovich
EliMoshkovich requested review from zeevmoney and removed request for zeevmoney October 23, 2026 14:03

@EliMoshkovich EliMoshkovich left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review: not ready to merge (one HIGH finding). This would be REQUEST_CHANGES, but GitHub doesn't let an author request changes on their own PR.

HIGH: the new pattern doesn't reach any image that CI or the release builds. None of the docker/build-push-action steps in tests.yml or on_release.yml set context:, so the action builds from its default Git context. BuildKit applies .dockerignore only to a local context. With a Git context, MainContext in frontend/dockerui/config.go returns the cloned tree without any exclude patterns. Evidence:

  • This PR's own E2E jobs log load git source https://github.com/permitio/opal.git#refs/pull/979/merge, and so does every publish_docker_images job of the 0.9.10-rc.2 release.
  • permitio/opal-server:0.9.10-rc.2 was built from the #978 merge, which has the same .dockerignore line, and it still contains /opal/packages/opal-common/opal_common/tests/emudhra_compromised_cas.pem.
  • I built COPY ./packages from this PR's head (b9583e9) twice. From a local path the .pem is gone. From https://github.com/permitio/opal.git#b9583e94… it is still there.

The verification in the description used a local-path build (make / docker build .), which is why it passed.

Suggested fix (works with both context types): exclude the fixture in the Dockerfile itself, at both COPY ./packages ./packages/ lines (common and common-alpine):

# syntax=docker/dockerfile:1.19   # first line; --exclude is stable from 1.19 (1.17/1.18 reject it)
...
COPY --exclude=**/tests/*.pem ./packages ./packages/

I checked this from the Git context at b9583e9: no .pem, and the other 19 files in the tests directory are still copied. The .dockerignore line can stay for local builds. Deleting the file in a later RUN rm is not a fix, because the COPY layer would still hold it. An alternative is to add context: . to every build step, but that also brings the rest of .dockerignore and the release's __packaging__.py version stamp into the images (rc.2 currently ships __version__ = VERSION_STRING), so it's a bigger change than this PR needs.

It would be worth adding a check that fails CI if any *.pem is under /opal/packages in the built images, since this kind of regression is silent.

Follow-up: the release/0.9.x backport (#978, already merged) has the same no-op line, so 0.9.10-rc.2 ships the fixture. It needs the same Dockerfile change before 0.9.10 final.

Nothing else in the diff is a problem. The ** pattern is valid .dockerignore syntax, docker/Dockerfile.dockerignore doesn't exist, so the root file would apply to a local build, and the fixture is the only .pem under packages/.

Comment thread .dockerignore
… the images

CI and the release build with docker/build-push-action's default Git context,
and BuildKit applies .dockerignore only to a local context, so the
.dockerignore rule kept the trust-store test's fixture out of local builds but
not out of any image CI or a release produces. The Dockerfile now excludes it
at both COPY ./packages lines with COPY --exclude, which needs the dockerfile
1.19 frontend (# syntax line). Both E2E jobs check the client and server images
for any .pem under /opal/packages, after checking the find sees the test files.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 23, 2026 14:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…ters

The syntax line now pins docker/dockerfile:1.19 by digest, so a moved tag
can't change the frontend that builds every image. The comments now give the
real reason to keep the trust-store test's fixture out: a search of an image's
files for the compromised certificates reports it, although nothing trusts it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 23, 2026 15:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@EliMoshkovich
EliMoshkovich merged commit 27e4852 into master Oct 23, 2026
20 of 23 checks passed
@EliMoshkovich
EliMoshkovich deleted the eli/per-17672-dockerignore-test-certs branch October 23, 2026 16:07
EliMoshkovich added a commit that referenced this pull request Oct 23, 2026
…to 0.9.x) (#980)

Backport of #979. The trust-store test's fixture holds the compromised eMudhra certificates (CVE-2026-111943). #978's .dockerignore rule doesn't apply to the Git context CI and the release build from, so docker/Dockerfile now uses COPY --exclude=**/tests/*.pem (dockerfile frontend 1.19, pinned by digest), .dockerignore keeps the rule for local builds, and both E2E jobs fail if any .pem is under /opal/packages in the images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants