Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ config.mk
.env

*/.npm_install_done
.vscode
.vscode/
.claude/
.devcontainer/
.DS_Store
/edge-ads/node_modules
spirit-schemas/
Expand Down
14 changes: 14 additions & 0 deletions acs-openmetadata-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM docker.getcollate.io/openmetadata/server:1.13.3

# The upstream image bundles log4j-core/log4j-api 2.25.5 under
# /opt/openmetadata/libs. Swap in a patched 2.x release - log4j2's public API
# is stable across patch versions, so this is a safe drop-in without needing
# to touch the OpenMetadata server itself. ADD's remote-URL support is used
# instead of curl/wget since the Alpine base image doesn't ship either.
ARG LOG4J_VERSION=2.26.1

USER root
RUN rm -f /opt/openmetadata/libs/log4j-core-*.jar /opt/openmetadata/libs/log4j-api-*.jar
ADD --chown=openmetadata:openmetadata https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/${LOG4J_VERSION}/log4j-core-${LOG4J_VERSION}.jar /opt/openmetadata/libs/log4j-core-${LOG4J_VERSION}.jar
ADD --chown=openmetadata:openmetadata https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/${LOG4J_VERSION}/log4j-api-${LOG4J_VERSION}.jar /opt/openmetadata/libs/log4j-api-${LOG4J_VERSION}.jar
USER openmetadata
16 changes: 16 additions & 0 deletions acs-openmetadata-server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
top=..
include ${top}/mk/acs.init.mk

repo?=openmetadata-server
# Hard-set (not ?=): this tracks the upstream openmetadata/server version
# this Dockerfile patches, not ACS's own release version, so it must not
# follow config.mk's version= override for ACS's own services.
version=1.13.3
suffix?=-patched
# Flatten after push: the Dockerfile removes the bundled server log4j jars,
# but a plain layered image only whiteouts them - the old bytes are still on
# disk in the base image's layer. Flattening collapses that away. See
# mk/acs.docker.mk and README.md.
flatten=1

include ${mk}/acs.docker.mk
84 changes: 84 additions & 0 deletions acs-openmetadata-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# OpenMetadata server image (log4j patch)

The OpenMetadata server itself is deployed via the `openmetadata` Helm chart
(see `/deploy/values.yaml`'s `openmetadata` block and
[`acs-openmetadata/README.md`](../acs-openmetadata/README.md) for the wider
OpenMetadata deployment). This is a separate image from the ingestion image
patched in `acs-openmetadata` - the server chart's default image is
`docker.getcollate.io/openmetadata/server`, built from OpenMetadata's own
Maven release tarball, not `openmetadata/ingestion`.

That upstream image bundles `log4j-core`/`log4j-api` 2.25.5 under
`/opt/openmetadata/libs`. This directory's `Dockerfile` patches the jars in
directly, the same way `acs-opensearch/Dockerfile` patches OpenSearch's
bundled log4j:

```dockerfile
FROM docker.getcollate.io/openmetadata/server:1.13.3

ARG LOG4J_VERSION=2.26.1

USER root
RUN rm -f /opt/openmetadata/libs/log4j-core-*.jar /opt/openmetadata/libs/log4j-api-*.jar
ADD --chown=openmetadata:openmetadata https://.../log4j-core-${LOG4J_VERSION}.jar /opt/openmetadata/libs/log4j-core-${LOG4J_VERSION}.jar
ADD --chown=openmetadata:openmetadata https://.../log4j-api-${LOG4J_VERSION}.jar /opt/openmetadata/libs/log4j-api-${LOG4J_VERSION}.jar
USER openmetadata
```

log4j2's public API is stable across patch versions, so this is a safe
drop-in swap that doesn't require touching the OpenMetadata server itself.
`LOG4J_VERSION` is kept in sync with the version pinned in
`acs-openmetadata/Dockerfile` and `acs-opensearch/Dockerfile` - there's no
reason to track three different patched log4j versions across the three
images.

`ADD`'s remote-URL support is used to fetch the jars (rather than `curl`/
`wget`) because the upstream image is built on Alpine and doesn't ship
either tool. `USER root`/`USER openmetadata` bracket the patch because the
upstream image already drops privileges to the `openmetadata` user, and
that user doesn't own `/opt/openmetadata/libs` by default.

## Building and pushing the patched image

Requires the [`crane`](https://github.com/google/go-containerregistry) CLI on
`PATH` in addition to `docker buildx` - see below.

```sh
cd acs-openmetadata-server
make build
```

`make build` (via `mk/acs.docker.mk`) runs
`docker buildx build --push --platform linux/amd64 -t <registry>/openmetadata-server:1.13.3-patched .`,
then flattens the pushed image with `crane flatten`. `rm`-ing a file in a
Dockerfile only hides it behind a whiteout - the bytes are still present in
the upstream base image's layer underneath, which file-level vulnerability
scanners that walk a node's disk (rather than asking a registry to resolve
the image) will still flag. Flattening merges the layers into one via the
registry API so the removed jars are actually gone, not just masked; `crane`
preserves the image's config (`ENV`/`ENTRYPOINT`/`CMD`/`USER`/etc.)
unchanged - only the filesystem layers are affected. This is opted into via
`flatten=1` in this directory's `Makefile` and is a no-op for every other
ACS service's `make build`, since `mk/acs.docker.mk` only runs it when
`flatten` is set.

The `version` in the `Makefile` is pinned to `1.13.3` on purpose (not the
usual `?=` override) - it tracks the upstream `openmetadata/server` version
this Dockerfile patches, not ACS's own release version. The resulting tag is
what `deploy/values.yaml` references:

```yaml
openmetadata:
image:
repository: <registry>/openmetadata-server
tag: "1.13.3-patched"
```

When upstream OpenMetadata ships a new release, bump the `FROM` tag here
(keeping it in sync with the `openmetadata`/`openmetadata-dependencies`
chart versions in `/deploy/Chart.yaml`, since the server image version and
chart `appVersion` are expected to match), rebuild, and update the tag in
`values.yaml` to match. If a future upstream release already bundles a fixed
log4j, this Dockerfile (and the custom image) can be dropped and
`values.yaml` pointed back at the stock
`docker.getcollate.io/openmetadata/server` image.
15 changes: 15 additions & 0 deletions acs-openmetadata/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM openmetadata/ingestion:1.13.3

# Pre-install the package during image build time
RUN pip install --no-cache-dir "apache-airflow-providers-fab==2.4.4"

# pyspark bundles its own log4j-core/log4j-api (2.20.0), which is in the
# affected range for CVE-2025-68161/CVE-2026-34477/CVE-2026-34480. Swap in a
# patched 2.x release - log4j2's public API is stable across patch
# versions, so this is a safe drop-in without needing to touch pyspark
# itself or know whether the Spark profiling engine is actually used.
ARG LOG4J_VERSION=2.26.1
RUN PYSPARK_JARS="$(python -c 'import os, pyspark; print(os.path.join(os.path.dirname(pyspark.__file__), "jars"))')" \
&& rm -f "${PYSPARK_JARS}"/log4j-core-*.jar "${PYSPARK_JARS}"/log4j-api-*.jar \
&& python -c "import urllib.request as r; r.urlretrieve('https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/${LOG4J_VERSION}/log4j-core-${LOG4J_VERSION}.jar', '${PYSPARK_JARS}/log4j-core-${LOG4J_VERSION}.jar')" \
&& python -c "import urllib.request as r; r.urlretrieve('https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/${LOG4J_VERSION}/log4j-api-${LOG4J_VERSION}.jar', '${PYSPARK_JARS}/log4j-api-${LOG4J_VERSION}.jar')"
17 changes: 17 additions & 0 deletions acs-openmetadata/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
top=..
include ${top}/mk/acs.init.mk

repo?=openmetadata-ingestion
# Hard-set (not ?=): this tracks the upstream openmetadata/ingestion
# version this Dockerfile patches, not ACS's own release version, so it
# must not follow config.mk's version= override for ACS's own services.
version=1.13.3
suffix?=-patched
k8s.deployment?=openmetadata
# Flatten after push: the Dockerfile removes the bundled pyspark log4j jars,
# but a plain layered image only whiteouts them - the old bytes are still on
# disk in the base image's layer. Flattening collapses that away. See
# mk/acs.docker.mk and README.md.
flatten=1

include ${mk}/acs.docker.mk
Loading
Loading