fix(hermes): harden non-root startup
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 153

This commit is contained in:
jenkins 2026-08-08 18:17:10 -03:00
parent 7b5bf8de6a
commit 067e9ce606
6 changed files with 44 additions and 45 deletions

View File

@ -0,0 +1,23 @@
# dockerfiles/Dockerfile.hermes-chat-router
FROM --platform=$BUILDPLATFORM golang:1.24-alpine@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 AS build
ARG TARGETOS
ARG TARGETARCH
WORKDIR /src
COPY services/hermes/router/ ./
RUN GO111MODULE=off CGO_ENABLED=0 go test . \
&& GOOS=${TARGETOS} GOARCH=${TARGETARCH} GO111MODULE=off CGO_ENABLED=0 go build \
-trimpath \
-ldflags="-s -w" \
-o /out/chat-router .
FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build --chown=10000:10000 /out/chat-router /chat-router
USER 10000:10000
EXPOSE 8080
ENTRYPOINT ["/chat-router"]

View File

@ -67,6 +67,13 @@ spec:
- key: kubernetes.io/hostname - key: kubernetes.io/hostname
operator: NotIn operator: NotIn
values: [titan-13, titan-15, titan-17, titan-18, titan-19] values: [titan-13, titan-15, titan-17, titan-18, titan-19]
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values: [arm64]
- key: jetson
operator: In
values: ["true"]
preferredDuringSchedulingIgnoredDuringExecution: preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100 - weight: 100
preference: preference:
@ -238,6 +245,7 @@ spec:
- name: hermes - name: hermes
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: [/opt/hermes/.venv/bin/hermes]
args: [gateway, run] args: [gateway, run]
ports: ports:
- {name: dashboard, containerPort: 9119, protocol: TCP} - {name: dashboard, containerPort: 9119, protocol: TCP}

View File

@ -20,7 +20,7 @@ spec:
app: hermes-chat-router app: hermes-chat-router
annotations: annotations:
ai.bstein.dev/role: privacy-preserving-chat-tenant-router ai.bstein.dev/role: privacy-preserving-chat-tenant-router
ai.bstein.dev/config-rev: "20260808-webui-telegram" ai.bstein.dev/config-rev: "20260808-webui-telegram-router-image"
vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-pre-populate-only: "true" vault.hashicorp.com/agent-pre-populate-only: "true"
vault.hashicorp.com/agent-init-first: "true" vault.hashicorp.com/agent-init-first: "true"
@ -60,37 +60,10 @@ spec:
- key: hardware - key: hardware
operator: In operator: In
values: [rpi5] values: [rpi5]
initContainers:
- name: build-router
image: golang:1.24-alpine@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- |
set -eu
cd /src
GOCACHE=/tmp/go-cache GO111MODULE=off CGO_ENABLED=0 go test .
GOCACHE=/tmp/go-cache GO111MODULE=off CGO_ENABLED=0 go build -trimpath -o /tools/chat-router .
chmod 0755 /tools/chat-router
securityContext:
allowPrivilegeEscalation: false
runAsUser: 10000
runAsGroup: 10000
seccompProfile:
type: RuntimeDefault
volumeMounts:
- {name: source, mountPath: /src, readOnly: true}
- {name: tools, mountPath: /tools}
- {name: tmp, mountPath: /tmp}
resources:
requests: {cpu: 100m, memory: 128Mi}
limits: {cpu: "1", memory: 512Mi}
containers: containers:
- name: router - name: router
image: busybox:1.37 image: registry.bstein.dev/bstein/hermes-chat-router@sha256:ccb3a7c7ceba317153ff64455777459a5cfd9497bc0e6f51687feedfbfd6f4ed
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: [/tools/chat-router]
ports: ports:
- {name: http, containerPort: 8080, protocol: TCP} - {name: http, containerPort: 8080, protocol: TCP}
env: env:
@ -115,18 +88,12 @@ spec:
seccompProfile: seccompProfile:
type: RuntimeDefault type: RuntimeDefault
volumeMounts: volumeMounts:
- {name: tools, mountPath: /tools, readOnly: true}
- {name: state, mountPath: /state} - {name: state, mountPath: /state}
- {name: tmp, mountPath: /tmp} - {name: tmp, mountPath: /tmp}
resources: resources:
requests: {cpu: 25m, memory: 32Mi} requests: {cpu: 25m, memory: 32Mi}
limits: {cpu: 250m, memory: 128Mi} limits: {cpu: 250m, memory: 128Mi}
volumes: volumes:
- name: source
configMap:
name: hermes-chat-router-source
- name: tools
emptyDir: {}
- name: state - name: state
persistentVolumeClaim: persistentVolumeClaim:
claimName: hermes-chat-router-state claimName: hermes-chat-router-state

View File

@ -154,6 +154,7 @@ spec:
- name: hermes - name: hermes
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: [/opt/hermes/.venv/bin/hermes]
args: [gateway, run] args: [gateway, run]
ports: ports:
- {name: api, containerPort: 8642, protocol: TCP} - {name: api, containerPort: 8642, protocol: TCP}

View File

@ -74,6 +74,15 @@ spec:
- titan-17 - titan-17
- titan-18 - titan-18
- titan-19 - titan-19
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
- key: jetson
operator: In
values:
- "true"
preferredDuringSchedulingIgnoredDuringExecution: preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100 - weight: 100
preference: preference:
@ -253,6 +262,7 @@ spec:
- name: hermes - name: hermes
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: [/opt/hermes/.venv/bin/hermes]
args: args:
- gateway - gateway
- run - run

View File

@ -43,16 +43,6 @@ configMapGenerator:
- patch_hermes_auth.py=scripts/patch_hermes_auth.py - patch_hermes_auth.py=scripts/patch_hermes_auth.py
options: options:
disableNameSuffixHash: true disableNameSuffixHash: true
- name: hermes-chat-router-source
namespace: hermes
files:
- main.go=router/main.go
- main_test.go=router/main_test.go
- telegram.go=router/telegram.go
- telegram_test.go=router/telegram_test.go
- web.go=router/web.go
options:
disableNameSuffixHash: true
- name: hermes-triage-skill - name: hermes-triage-skill
namespace: hermes namespace: hermes
files: files: