diff --git a/apps/swh-provenance/Dockerfile b/apps/swh-provenance/Dockerfile
index 53685d6be8e6eb7bb03e04c3bdd28c43b2c25abf..411d2c997bff99f351dee8109ca6d98e1d9c9bb7 100644
--- a/apps/swh-provenance/Dockerfile
+++ b/apps/swh-provenance/Dockerfile
@@ -2,22 +2,53 @@ ARG REGISTRY=container-registry.softwareheritage.org/swh/infra/swh-apps/
 ARG base_image=${REGISTRY}base
 ARG base_image_version=latest
 
-FROM ${base_image}:${base_image_version}
-
+ARG userid=1000
+ARG groupid=1000
 ARG user=swh
 ARG workdir=/opt/${user}
 ARG configdir=/etc/${user}
 
+FROM rust:1.85-bookworm AS rust_build
+
+# ... build swh-graph rust deps
+RUN apt-get update && \
+    apt-get upgrade -y && \
+    apt-get install -y build-essential libclang-dev \
+      zstd protobuf-compiler default-jre && \
+    apt-get clean
+
+# Install swh-graph feature swh-graph-grpc-serve
+RUN --mount=type=cache,target=.cache,uid=1000,gid=1000 \
+  RUSTFLAGS="-C target-cpu=native" \
+  cargo install swh-provenance --locked
+
+FROM ${base_image}:${base_image_version}
+
+USER root
+RUN apt-get update && \
+    apt-get install -y zstd && \
+    apt-get clean
+
+FROM ${base_image}:${base_image_version}
+
 COPY --chmod=0644 requirements-frozen.txt ${workdir}
 RUN --mount=type=cache,target=.cache,uid=1000,gid=1000 \
     uv pip sync requirements-frozen.txt
 
 COPY --chmod=0755 entrypoint.sh ${workdir}
+COPY --from=rust_build /usr/local/cargo/bin/swh-provenance* /usr/local/bin/
+COPY --chmod=0755 entrypoint.sh ${workdir}
 
 USER ${user}
 ENV SWH_CONFIG_FILENAME=${configdir}/config.yml
+# Default to be a rpc service
 ENV PORT 5014
+ENV PROVENANCE_TYPE "rpc"
+# Possible other value for grpc kind
+# ENV PORT 50141
+# ENV PROVENANCE_TYPE "grpc"
 EXPOSE $PORT
+# For rpc type, this maps directly to gunicorn env variables
 ENV WORKERS 8
 ENV THREADS 2
 ENV TIMEOUT 3600
diff --git a/apps/swh-provenance/entrypoint.sh b/apps/swh-provenance/entrypoint.sh
index 657cafa04e10d5a29f18406ea63ab5acc540ee5f..e5a5fcd13eb3528c5800c7b70d894c3614002c76 100755
--- a/apps/swh-provenance/entrypoint.sh
+++ b/apps/swh-provenance/entrypoint.sh
@@ -18,25 +18,40 @@ case "$1" in
         ;;
     *)
         EXTRA_CLI_FLAGS=()
-        if [ -n "${SWH_LOG_CONFIG_JSON}" ]; then
-            EXTRA_CLI_FLAGS+=('--log-config-json' "${SWH_LOG_CONFIG_JSON}")
-        fi
         if [ -n "${STATSD_HOST}" -a -n "${STATSD_PORT}" ]; then
             EXTRA_CLI_FLAGS+=('--statsd-host' "${STATSD_HOST}:${STATSD_PORT}")
         fi
-        if [ -n "${STATSD_SERVICE_TYPE}" ]; then
-            EXTRA_CLI_FLAGS+=('--statsd-prefix' "${STATSD_SERVICE_TYPE}")
-        fi
+        case "${PROVENANCE_TYPE}" in
+            "rpc")
+                if [ -n "${SWH_LOG_CONFIG_JSON}" ]; then
+                    EXTRA_CLI_FLAGS+=('--log-config-json' "${SWH_LOG_CONFIG_JSON}")
+                fi
+                if [ -n "${STATSD_SERVICE_TYPE}" ]; then
+                    EXTRA_CLI_FLAGS+=('--statsd-prefix' "${STATSD_SERVICE_TYPE}")
+                fi
+
+                echo 'Starting the swh-provenance RPC server'
+                exec gunicorn --bind "0.0.0.0:${PORT}" \
+                     --log-level "${SWH_LOG_LEVEL:-INFO}" \
+                     "${EXTRA_CLI_FLAGS[@]}" \
+                     --threads "${THREADS}" \
+                     --workers "${WORKERS}" \
+                     --timeout "${TIMEOUT}" \
+                     --reload \
+                     --config 'python:swh.core.api.gunicorn_config' \
+                     'swh.provenance.api.server:make_app_from_configfile()'
+              ;;
+            "grpc")
+                echo 'Starting the swh-provenance GRPC server'
+                exec swh-provenance-grpc-serve \
+                    --graph "${GRAPH_PATH}" \
+                    --database "${PROVENANCE_PATH}" \
+                    --bind ":${PORT}"
+                    "${EXTRA_CLI_FLAGS[@]}" \
+                ;;
 
-        echo 'Starting the swh-provenance RPC server'
-        exec gunicorn --bind "0.0.0.0:${PORT}" \
-             --log-level "${SWH_LOG_LEVEL:-INFO}" \
-             "${EXTRA_CLI_FLAGS[@]}" \
-             --threads "${THREADS}" \
-             --workers "${WORKERS}" \
-             --timeout "${TIMEOUT}" \
-             --reload \
-             --config 'python:swh.core.api.gunicorn_config' \
-             'swh.provenance.api.server:make_app_from_configfile()'
-      ;;
+            *)
+                echo "Unknown provenance type <${PROVENANCE_TYPE}> (either rpc or gprc)"
+                exit 1
+        esac
 esac
diff --git a/apps/swh-provenance/requirements.txt b/apps/swh-provenance/requirements.txt
index 1a035b4e8d4a4e04d071d8c4e11af06de87f1c4f..8c6278249f7e29b8529f58b4a44057e5ccdb3f63 100644
--- a/apps/swh-provenance/requirements.txt
+++ b/apps/swh-provenance/requirements.txt
@@ -1,3 +1,4 @@
 swh.provenance
 python-json-logger
 gunicorn
+awscli
diff --git a/apps/swh-utils/Dockerfile b/apps/swh-utils/Dockerfile
index 5f69b37d05d038bcb71ac6b908c83861fb456439..e1f4dca28ab1ee950ee0bceb4b0e080d46206069 100644
--- a/apps/swh-utils/Dockerfile
+++ b/apps/swh-utils/Dockerfile
@@ -2,5 +2,5 @@ FROM debian:bookworm-slim
 
 RUN apt-get update && \
     apt-get -y upgrade && \
-    apt-get install -y gettext-base curl && \
+    apt-get install -y gettext-base curl awscli && \
     apt-get clean