deploy: verification-service + dummy-sink Phase-1 manifests (DEV-615)
Some checks failed
build-images / signing-service image (push) Successful in 23s
build-images / verification-service image (push) Successful in 48s
build-images / dummy-sink image (push) Successful in 49s
validate / JSON Schema (ajv) (push) Successful in 23s
validate / Rego (opa fmt + opa test) (push) Successful in 15s
phase1-smoke / Phase 1 end-to-end smoke (push) Successful in 1m0s
validate / DB (migrate up/down dry-run) (push) Successful in 24s
validate / Go (vet + test) (push) Has been cancelled
Some checks failed
build-images / signing-service image (push) Successful in 23s
build-images / verification-service image (push) Successful in 48s
build-images / dummy-sink image (push) Successful in 49s
validate / JSON Schema (ajv) (push) Successful in 23s
validate / Rego (opa fmt + opa test) (push) Successful in 15s
phase1-smoke / Phase 1 end-to-end smoke (push) Successful in 1m0s
validate / DB (migrate up/down dry-run) (push) Successful in 24s
validate / Go (vet + test) (push) Has been cancelled
ServiceAccount, Deployment, Service, and NetworkPolicy per sub-directory, matching the signing-service template (non-root, read-only rootfs, distroless, agent-trust namespace). verification-service — NetworkPolicy allows ingress only from approval-service, testagent-transform, and dummy-sink, and egress only to transparency-log, trust-pg, Pocket-ID JWKS (HTTPS/443), and kube-dns. dummy-sink — adds a 1Gi longhorn PVC `dummy-sink-data` mounted at /data/dummy-sink, projected trust-api SA token at /var/run/secrets/tokens/trust-api, Pocket-ID client creds from a dev Secret, strategy Recreate (RWO PVC). NetworkPolicy allows ingress from testagent-transform and egress to verification-service, signing-service, transparency-log, HTTPS/443 (Pocket-ID OIDC), and kube-dns. build-images workflow — adds verification-service and dummy-sink jobs mirroring signing-service's BuildKit + Harbor pipeline. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
5bbd3b2c68
commit
5d2bf73d84
14 changed files with 888 additions and 0 deletions
|
|
@ -101,3 +101,139 @@ jobs:
|
||||||
set -eu
|
set -eu
|
||||||
docker push "${{ steps.tags.outputs.image_sha }}"
|
docker push "${{ steps.tags.outputs.image_sha }}"
|
||||||
docker push "${{ steps.tags.outputs.image_main }}"
|
docker push "${{ steps.tags.outputs.image_main }}"
|
||||||
|
|
||||||
|
verification-service:
|
||||||
|
name: verification-service image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: debian:trixie-slim
|
||||||
|
options: --user 0:0
|
||||||
|
env:
|
||||||
|
REGISTRY: harbor.basicstack.de
|
||||||
|
IMAGE_REPO: harbor.basicstack.de/basicstack/verification-service
|
||||||
|
DOCKER_BUILDKIT: "1"
|
||||||
|
steps:
|
||||||
|
- name: Install git + buildx client + ca-certs
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git curl ca-certificates docker.io docker-cli docker-buildx
|
||||||
|
git --version
|
||||||
|
docker --version
|
||||||
|
docker buildx version
|
||||||
|
|
||||||
|
- name: Clone repository (sha256-aware)
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
git clone --depth=1 --branch="${GITHUB_REF_NAME}" \
|
||||||
|
"https://x-access-token:${GITHUB_TOKEN}@forgejo.basicstack.de/${GITHUB_REPOSITORY}.git" \
|
||||||
|
"${GITHUB_WORKSPACE}"
|
||||||
|
cd "${GITHUB_WORKSPACE}"
|
||||||
|
git log -1 --oneline
|
||||||
|
|
||||||
|
- name: Resolve tags
|
||||||
|
id: tags
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
SHA="$(git rev-parse --short HEAD)"
|
||||||
|
echo "sha=${SHA}" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "image_sha=${IMAGE_REPO}:${SHA}" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "image_main=${IMAGE_REPO}:main" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker buildx build \
|
||||||
|
--load \
|
||||||
|
-f services/verification-service/Dockerfile \
|
||||||
|
-t "${{ steps.tags.outputs.image_sha }}" \
|
||||||
|
-t "${{ steps.tags.outputs.image_main }}" \
|
||||||
|
.
|
||||||
|
|
||||||
|
- name: Login to Harbor (push jobs only)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
env:
|
||||||
|
HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }}
|
||||||
|
HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
echo "${HARBOR_PASSWORD}" | \
|
||||||
|
docker login "${REGISTRY}" --username "${HARBOR_USERNAME}" --password-stdin
|
||||||
|
|
||||||
|
- name: Push image (main only)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
docker push "${{ steps.tags.outputs.image_sha }}"
|
||||||
|
docker push "${{ steps.tags.outputs.image_main }}"
|
||||||
|
|
||||||
|
dummy-sink:
|
||||||
|
name: dummy-sink image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: debian:trixie-slim
|
||||||
|
options: --user 0:0
|
||||||
|
env:
|
||||||
|
REGISTRY: harbor.basicstack.de
|
||||||
|
IMAGE_REPO: harbor.basicstack.de/basicstack/dummy-sink
|
||||||
|
DOCKER_BUILDKIT: "1"
|
||||||
|
steps:
|
||||||
|
- name: Install git + buildx client + ca-certs
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git curl ca-certificates docker.io docker-cli docker-buildx
|
||||||
|
git --version
|
||||||
|
docker --version
|
||||||
|
docker buildx version
|
||||||
|
|
||||||
|
- name: Clone repository (sha256-aware)
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
git clone --depth=1 --branch="${GITHUB_REF_NAME}" \
|
||||||
|
"https://x-access-token:${GITHUB_TOKEN}@forgejo.basicstack.de/${GITHUB_REPOSITORY}.git" \
|
||||||
|
"${GITHUB_WORKSPACE}"
|
||||||
|
cd "${GITHUB_WORKSPACE}"
|
||||||
|
git log -1 --oneline
|
||||||
|
|
||||||
|
- name: Resolve tags
|
||||||
|
id: tags
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
SHA="$(git rev-parse --short HEAD)"
|
||||||
|
echo "sha=${SHA}" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "image_sha=${IMAGE_REPO}:${SHA}" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "image_main=${IMAGE_REPO}:main" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker buildx build \
|
||||||
|
--load \
|
||||||
|
-f services/dummy-sink/Dockerfile \
|
||||||
|
-t "${{ steps.tags.outputs.image_sha }}" \
|
||||||
|
-t "${{ steps.tags.outputs.image_main }}" \
|
||||||
|
.
|
||||||
|
|
||||||
|
- name: Login to Harbor (push jobs only)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
env:
|
||||||
|
HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }}
|
||||||
|
HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
echo "${HARBOR_PASSWORD}" | \
|
||||||
|
docker login "${REGISTRY}" --username "${HARBOR_USERNAME}" --password-stdin
|
||||||
|
|
||||||
|
- name: Push image (main only)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
docker push "${{ steps.tags.outputs.image_sha }}"
|
||||||
|
docker push "${{ steps.tags.outputs.image_main }}"
|
||||||
|
|
|
||||||
14
deploy/dummy-sink/00-serviceaccount.yaml
Normal file
14
deploy/dummy-sink/00-serviceaccount.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: sink
|
||||||
|
# dummy-sink uses an EXPLICIT projected SA token mounted into
|
||||||
|
# /var/run/secrets/tokens/trust-api as the second half of the
|
||||||
|
# signing-service double-identity contract (DEV-611). The default
|
||||||
|
# auto-mount is disabled so the pod only sees that scoped token.
|
||||||
|
automountServiceAccountToken: false
|
||||||
22
deploy/dummy-sink/10-pvc.yaml
Normal file
22
deploy/dummy-sink/10-pvc.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# PersistentVolumeClaim for the dummy-sink payload store.
|
||||||
|
#
|
||||||
|
# Payloads land at /data/dummy-sink/<decision_id>.json via atomic
|
||||||
|
# .tmp+rename (see services/dummy-sink/README.md). 1Gi is intentionally
|
||||||
|
# small — this is a mock sink for Phase-1 smoke, not a production store.
|
||||||
|
# Longhorn is BasicStack's cluster default dynamic-provisioning class.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink-data
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: sink
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
30
deploy/dummy-sink/11-secret-dev.example.yaml
Normal file
30
deploy/dummy-sink/11-secret-dev.example.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# dummy-sink dev secret — EXAMPLE ONLY.
|
||||||
|
#
|
||||||
|
# This file is a template. The real cluster Secret MUST be created either
|
||||||
|
# as a SealedSecret (preferred, see deploy/dummy-sink/README.md) or
|
||||||
|
# applied imperatively with values that never land in the git repo.
|
||||||
|
#
|
||||||
|
# Secret shape (Phase 1):
|
||||||
|
# POCKET_ID_ISSUER — Pocket-ID OIDC issuer URL.
|
||||||
|
# POCKET_ID_CLIENT_ID — client id for this agent.
|
||||||
|
# POCKET_ID_CLIENT_SECRET — client secret for this agent.
|
||||||
|
# POCKET_ID_AUDIENCE — expected `aud` claim (defaults to trust-api).
|
||||||
|
#
|
||||||
|
# The projected SA token for the X-Workload-Token side is mounted from
|
||||||
|
# the pod's own ServiceAccount via a projected volume — no Secret
|
||||||
|
# required for that half of the double-identity contract.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink-dev
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
proofedmesh.basicstack.de/mode: dev
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
POCKET_ID_ISSUER: "https://auth.basicstack.de"
|
||||||
|
POCKET_ID_CLIENT_ID: "REPLACE_WITH_POCKET_ID_CLIENT_ID"
|
||||||
|
POCKET_ID_CLIENT_SECRET: "REPLACE_WITH_POCKET_ID_CLIENT_SECRET"
|
||||||
|
POCKET_ID_AUDIENCE: "trust-api"
|
||||||
125
deploy/dummy-sink/20-deployment.yaml
Normal file
125
deploy/dummy-sink/20-deployment.yaml
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: sink
|
||||||
|
spec:
|
||||||
|
# ReadWriteOnce PVC → single-writer. Scaling past replicas=1 requires
|
||||||
|
# an RWX storage class or per-pod PVCs (not Phase-1 scope).
|
||||||
|
replicas: 1
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: sink
|
||||||
|
spec:
|
||||||
|
serviceAccountName: dummy-sink
|
||||||
|
# Default auto-mount is off; the projected `trust-api`-audience
|
||||||
|
# token is provided via an explicit projected volume below.
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
|
fsGroup: 65532
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: dummy-sink
|
||||||
|
image: harbor.basicstack.de/basicstack/dummy-sink:dev
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
args:
|
||||||
|
- "-listen=:8083"
|
||||||
|
- "-data-dir=/data/dummy-sink"
|
||||||
|
- "-verify-url=http://verification-service.agent-trust.svc.cluster.local:8084"
|
||||||
|
- "-signing-url=http://signing-service.agent-trust.svc.cluster.local:8081"
|
||||||
|
- "-tlog-url=http://transparency-log.agent-trust.svc.cluster.local"
|
||||||
|
- "-sink-id=sink:dummy-sink"
|
||||||
|
- "-actor=agent-dummy-sink"
|
||||||
|
- "-signing-key-ref=trust-api/agent-dummy-sink-2026-q4"
|
||||||
|
env:
|
||||||
|
# Pocket-ID client credentials for the Authorization: Bearer
|
||||||
|
# half of the signing-service double-identity check.
|
||||||
|
- name: POCKET_ID_ISSUER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dummy-sink-dev
|
||||||
|
key: POCKET_ID_ISSUER
|
||||||
|
- name: POCKET_ID_CLIENT_ID
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dummy-sink-dev
|
||||||
|
key: POCKET_ID_CLIENT_ID
|
||||||
|
- name: POCKET_ID_CLIENT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dummy-sink-dev
|
||||||
|
key: POCKET_ID_CLIENT_SECRET
|
||||||
|
- name: POCKET_ID_AUDIENCE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dummy-sink-dev
|
||||||
|
key: POCKET_ID_AUDIENCE
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8083
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 20
|
||||||
|
failureThreshold: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "50m"
|
||||||
|
memory: "64Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "256Mi"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data/dummy-sink
|
||||||
|
- name: workload-token
|
||||||
|
mountPath: /var/run/secrets/tokens
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: dummy-sink-data
|
||||||
|
# Projected ServiceAccount token addressed to the trust-api
|
||||||
|
# audience. signing-service accepts this via its K8s
|
||||||
|
# TokenReview path (DEV-609) as the workload-identity side of
|
||||||
|
# the double-identity contract.
|
||||||
|
- name: workload-token
|
||||||
|
projected:
|
||||||
|
sources:
|
||||||
|
- serviceAccountToken:
|
||||||
|
path: trust-api
|
||||||
|
audience: trust-api
|
||||||
|
expirationSeconds: 3600
|
||||||
18
deploy/dummy-sink/30-service.yaml
Normal file
18
deploy/dummy-sink/30-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: sink
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8083
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
86
deploy/dummy-sink/40-networkpolicy.yaml
Normal file
86
deploy/dummy-sink/40-networkpolicy.yaml
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
# NetworkPolicy for dummy-sink.
|
||||||
|
#
|
||||||
|
# Cluster-wide NetworkPolicy enforcement is active on BasicStack (see
|
||||||
|
# cluster memory on NetworkPolicy activation). Pods in agent-trust
|
||||||
|
# without an explicit allow-list are isolated; this file is the
|
||||||
|
# explicit allow-list for dummy-sink per DEV-615.
|
||||||
|
#
|
||||||
|
# Ingress callers (per Phase-1 architecture V1.1 §7):
|
||||||
|
# - testagent-transform — the sole producer of handover deliveries.
|
||||||
|
#
|
||||||
|
# Egress reachable targets (Phase-1 §7 Senken-Vertrag):
|
||||||
|
# - verification-service — chain verification + replay guard.
|
||||||
|
# - signing-service — handover-attestation signing.
|
||||||
|
# - transparency-log — logging the signed handover envelope.
|
||||||
|
# - DNS — kube-dns for service name resolution.
|
||||||
|
#
|
||||||
|
# dummy-sink intentionally does NOT egress Pocket-ID directly; it uses
|
||||||
|
# the Pocket-ID OIDC endpoint via HTTPS/443 as the client_credentials
|
||||||
|
# source for its Bearer token to signing-service. That cluster-external
|
||||||
|
# target is included below.
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: dummy-sink
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: testagent-transform
|
||||||
|
ports:
|
||||||
|
- port: 8083
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# verification-service (same namespace).
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
ports:
|
||||||
|
- port: 8084
|
||||||
|
protocol: TCP
|
||||||
|
# signing-service (same namespace).
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: signing-service
|
||||||
|
ports:
|
||||||
|
- port: 8081
|
||||||
|
protocol: TCP
|
||||||
|
# transparency-log (same namespace, port 80 → container 8080).
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: transparency-log
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
protocol: TCP
|
||||||
|
# Pocket-ID OIDC token exchange + JWKS — cluster-external HTTPS/443.
|
||||||
|
- ports:
|
||||||
|
- port: 443
|
||||||
|
protocol: TCP
|
||||||
|
# DNS egress to kube-dns.
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
115
deploy/dummy-sink/README.md
Normal file
115
deploy/dummy-sink/README.md
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
# dummy-sink — deployment
|
||||||
|
|
||||||
|
Kubernetes manifests for the ADR-0007 dummy-sink in the `agent-trust`
|
||||||
|
namespace. The namespace itself is created by
|
||||||
|
[`deploy/trillian/00-namespace.yaml`](../trillian/00-namespace.yaml);
|
||||||
|
this directory assumes that file (or an equivalent) is already applied.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
deploy/dummy-sink/
|
||||||
|
├── 00-serviceaccount.yaml — ServiceAccount (auto-mount off, projected token used)
|
||||||
|
├── 10-pvc.yaml — PVC dummy-sink-data (1Gi, longhorn, RWO)
|
||||||
|
├── 11-secret-dev.example.yaml — TEMPLATE for the dev-mode Secret
|
||||||
|
├── 20-deployment.yaml — Deployment (non-root, read-only rootfs, distroless)
|
||||||
|
├── 30-service.yaml — ClusterIP Service on :8083
|
||||||
|
├── 40-networkpolicy.yaml — ingress from testagent-transform,
|
||||||
|
│ egress to verification-service / signing-service / transparency-log
|
||||||
|
└── README.md — this file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Apply order
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f deploy/trillian/00-namespace.yaml # if not yet applied
|
||||||
|
kubectl apply -f deploy/dummy-sink/00-serviceaccount.yaml
|
||||||
|
kubectl apply -f deploy/dummy-sink/10-pvc.yaml
|
||||||
|
# Create the dev Secret separately (see "Secret convention" below) — DO NOT
|
||||||
|
# commit the real values. The .example file is a template, not a secret.
|
||||||
|
kubectl apply -f deploy/dummy-sink/20-deployment.yaml
|
||||||
|
kubectl apply -f deploy/dummy-sink/30-service.yaml
|
||||||
|
kubectl apply -f deploy/dummy-sink/40-networkpolicy.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Reach the sink in-cluster at:
|
||||||
|
|
||||||
|
```
|
||||||
|
http://dummy-sink.agent-trust.svc.cluster.local:8083
|
||||||
|
```
|
||||||
|
|
||||||
|
Health check (also used by Deployment probes):
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /healthz → 200 {"status":"ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Deliver endpoint (per ADR-0007 / DEV-611):
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/v1/sink/dummy/deliver
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
## PVC
|
||||||
|
|
||||||
|
`dummy-sink-data` is a 1 Gi Longhorn RWO claim mounted at
|
||||||
|
`/data/dummy-sink`. The Deployment uses `strategy.type: Recreate`
|
||||||
|
because the PVC is `ReadWriteOnce` — a rolling update would try to
|
||||||
|
schedule a second pod against the same volume. Scaling past a single
|
||||||
|
replica requires an RWX storage class or per-pod PVCs; neither is in
|
||||||
|
Phase-1 scope.
|
||||||
|
|
||||||
|
## K8s secret convention
|
||||||
|
|
||||||
|
The dummy-sink reads one Secret, `dummy-sink-dev` (or
|
||||||
|
`dummy-sink-prod` for production), with the Pocket-ID client
|
||||||
|
credentials. Shape:
|
||||||
|
|
||||||
|
| Env key | Purpose |
|
||||||
|
| ------------------------- | ---------------------------------------------- |
|
||||||
|
| `POCKET_ID_ISSUER` | Pocket-ID OIDC issuer URL |
|
||||||
|
| `POCKET_ID_CLIENT_ID` | Pocket-ID client id for this agent |
|
||||||
|
| `POCKET_ID_CLIENT_SECRET` | Pocket-ID client secret for this agent |
|
||||||
|
| `POCKET_ID_AUDIENCE` | Expected `aud` claim (default `trust-api`) |
|
||||||
|
|
||||||
|
The second half of the double-identity contract (the projected
|
||||||
|
ServiceAccount token at `/var/run/secrets/tokens/trust-api`) is wired
|
||||||
|
by the Deployment's `projected` volume and does not require a Secret.
|
||||||
|
|
||||||
|
For the GitOps path, convert the created Secret to a SealedSecret and
|
||||||
|
commit the sealed form under the same filename as the example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create secret generic dummy-sink-dev -n agent-trust \
|
||||||
|
--from-literal="POCKET_ID_ISSUER=https://auth.basicstack.de" \
|
||||||
|
--from-literal="POCKET_ID_CLIENT_ID=<id>" \
|
||||||
|
--from-literal="POCKET_ID_CLIENT_SECRET=<secret>" \
|
||||||
|
--from-literal="POCKET_ID_AUDIENCE=trust-api" \
|
||||||
|
--dry-run=client -o yaml | \
|
||||||
|
kubeseal --controller-namespace=sealed-secrets --format=yaml \
|
||||||
|
> deploy/dummy-sink/11-secret-dev.sealed.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## NetworkPolicy
|
||||||
|
|
||||||
|
See `40-networkpolicy.yaml`. In short:
|
||||||
|
|
||||||
|
- **Ingress:** `testagent-transform` pods only (matched by
|
||||||
|
`app.kubernetes.io/name`).
|
||||||
|
- **Egress:** `verification-service` (:8084), `signing-service`
|
||||||
|
(:8081), `transparency-log` (:8080), external HTTPS/443 for the
|
||||||
|
Pocket-ID OIDC endpoint, DNS to `kube-dns`.
|
||||||
|
|
||||||
|
## Image
|
||||||
|
|
||||||
|
Images are built by `.forgejo/workflows/build-images.yml` on every push
|
||||||
|
to `main` and pushed to:
|
||||||
|
|
||||||
|
```
|
||||||
|
harbor.basicstack.de/basicstack/dummy-sink:<git-sha>
|
||||||
|
harbor.basicstack.de/basicstack/dummy-sink:main (floating)
|
||||||
|
```
|
||||||
|
|
||||||
|
The Deployment currently references `:dev`; a GitOps apply will pin it
|
||||||
|
to a `:<git-sha>` once the image build pipeline has produced one.
|
||||||
13
deploy/verification-service/00-serviceaccount.yaml
Normal file
13
deploy/verification-service/00-serviceaccount.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: verification-service
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: trust-core
|
||||||
|
# verification-service does not call the Kubernetes API server (DEV-612
|
||||||
|
# scope: HTTP verification only), so the default auto-mounted SA token
|
||||||
|
# serves no purpose and is disabled to keep the pod boundary tight.
|
||||||
|
automountServiceAccountToken: false
|
||||||
28
deploy/verification-service/10-secret-dev.example.yaml
Normal file
28
deploy/verification-service/10-secret-dev.example.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# verification-service dev secret — EXAMPLE ONLY.
|
||||||
|
#
|
||||||
|
# This file is a template. The real cluster Secret MUST be created either
|
||||||
|
# as a SealedSecret (preferred, see deploy/verification-service/README.md)
|
||||||
|
# or applied imperatively with values that never land in the git repo.
|
||||||
|
#
|
||||||
|
# Secret shape (Phase 1):
|
||||||
|
# VERIFICATION_SIGNER_KEYS — comma- / newline-separated keyid=<enc>:<data>
|
||||||
|
# loaded into the in-memory keyring.
|
||||||
|
# Encodings: pem | hex | b64 | b64u.
|
||||||
|
#
|
||||||
|
# The verifier itself does not reach OpenBao Transit in Phase 1; it only
|
||||||
|
# needs the public halves of the approval and transform signers to
|
||||||
|
# validate DSSE envelopes it pulls from the transparency-log.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: verification-service-dev
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
proofedmesh.basicstack.de/mode: dev
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
VERIFICATION_SIGNER_KEYS: |
|
||||||
|
trust-api/approval-signer-2026-q4=pem:REPLACE_WITH_PEM_PUBLIC_KEY
|
||||||
|
trust-api/agent-testagent-transform-2026-q4=hex:REPLACE_WITH_64_HEX_PUBLIC_KEY
|
||||||
98
deploy/verification-service/20-deployment.yaml
Normal file
98
deploy/verification-service/20-deployment.yaml
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: verification-service
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: trust-core
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 0
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: trust-core
|
||||||
|
spec:
|
||||||
|
serviceAccountName: verification-service
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
|
fsGroup: 65532
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: verification-service
|
||||||
|
image: harbor.basicstack.de/basicstack/verification-service:dev
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
args:
|
||||||
|
- "-listen=:8084"
|
||||||
|
- "-backend=memory"
|
||||||
|
env:
|
||||||
|
- name: TLOG_URL
|
||||||
|
value: "http://transparency-log.agent-trust.svc.cluster.local"
|
||||||
|
# Keyids are the Phase-1 defaults; override via the Secret
|
||||||
|
# below if a different key rotation lands.
|
||||||
|
- name: APPROVAL_SIGNER_KEY_ID
|
||||||
|
value: "trust-api/approval-signer-2026-q4"
|
||||||
|
- name: TRANSFORM_SIGNER_KEY_ID
|
||||||
|
value: "trust-api/agent-testagent-transform-2026-q4"
|
||||||
|
# Public-key material for the DSSE validators. The Secret
|
||||||
|
# name resolves per environment (see 10-secret-dev.example.yaml
|
||||||
|
# for the shape).
|
||||||
|
- name: VERIFICATION_SIGNER_KEYS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: verification-service-dev
|
||||||
|
key: VERIFICATION_SIGNER_KEYS
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8084
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 20
|
||||||
|
failureThreshold: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "512Mi"
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
topologySpreadConstraints:
|
||||||
|
- maxSkew: 1
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
whenUnsatisfiable: ScheduleAnyway
|
||||||
|
labelSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
18
deploy/verification-service/30-service.yaml
Normal file
18
deploy/verification-service/30-service.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: verification-service
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
app.kubernetes.io/component: trust-core
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8084
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
93
deploy/verification-service/40-networkpolicy.yaml
Normal file
93
deploy/verification-service/40-networkpolicy.yaml
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
# NetworkPolicy for verification-service.
|
||||||
|
#
|
||||||
|
# Cluster-wide NetworkPolicy enforcement is active on BasicStack (see
|
||||||
|
# cluster memory on NetworkPolicy activation). Pods in agent-trust
|
||||||
|
# without an explicit allow-list are isolated; this file is the
|
||||||
|
# explicit allow-list for verification-service per DEV-615.
|
||||||
|
#
|
||||||
|
# Ingress callers (per Phase-1 architecture V1.1 §7):
|
||||||
|
# - approval-service — supplies the approval predicate when a
|
||||||
|
# fast chain pre-check is needed.
|
||||||
|
# - testagent-transform — the transformation agent that submits
|
||||||
|
# a chain to vet before shipping to the sink.
|
||||||
|
# - dummy-sink — the Phase-1 sink that calls back into
|
||||||
|
# verify/chain before persisting a payload.
|
||||||
|
#
|
||||||
|
# Egress reachable targets:
|
||||||
|
# - transparency-log — pulls DSSE envelopes + inclusion proofs
|
||||||
|
# (agent-trust/transparency-log, port 80).
|
||||||
|
# - trust-pg — Postgres backing the replay-store
|
||||||
|
# `verification_decisions` table (store=postgres).
|
||||||
|
# - Pocket-ID JWKS — out-of-cluster `auth.basicstack.de` JWKS
|
||||||
|
# fetch for OIDC validators (HTTPS/443).
|
||||||
|
# - DNS — kube-dns in kube-system for service name
|
||||||
|
# resolution.
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: verification-service
|
||||||
|
namespace: agent-trust
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
app.kubernetes.io/part-of: proofedmesh
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: verification-service
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: approval-service
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: testagent-transform
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: dummy-sink
|
||||||
|
ports:
|
||||||
|
- port: 8084
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
# transparency-log (in-cluster, agent-trust namespace, port 80).
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: transparency-log
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
protocol: TCP
|
||||||
|
# trust-api Postgres (replay-store backend). Reached via the
|
||||||
|
# `trust-pg` Service in the same namespace.
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: trust-pg
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
protocol: TCP
|
||||||
|
# Pocket-ID JWKS discovery is served from the public ingress
|
||||||
|
# (`auth.basicstack.de`). Egress is cluster-external HTTPS; no
|
||||||
|
# cluster selector will match, so this is an unrestricted
|
||||||
|
# TCP/443 egress rule.
|
||||||
|
- ports:
|
||||||
|
- port: 443
|
||||||
|
protocol: TCP
|
||||||
|
# DNS egress to kube-dns (cluster hostname resolution + out-of-
|
||||||
|
# cluster CNAME lookups for Pocket-ID JWKS).
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
92
deploy/verification-service/README.md
Normal file
92
deploy/verification-service/README.md
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
# verification-service — deployment
|
||||||
|
|
||||||
|
Kubernetes manifests for the ADR-0006 verification-service in the
|
||||||
|
`agent-trust` namespace. The namespace itself is created by
|
||||||
|
[`deploy/trillian/00-namespace.yaml`](../trillian/00-namespace.yaml);
|
||||||
|
this directory assumes that file (or an equivalent) is already applied.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
deploy/verification-service/
|
||||||
|
├── 00-serviceaccount.yaml — ServiceAccount (auto-mount off)
|
||||||
|
├── 10-secret-dev.example.yaml — TEMPLATE for the dev-mode Secret
|
||||||
|
├── 20-deployment.yaml — Deployment (non-root, read-only rootfs, distroless)
|
||||||
|
├── 30-service.yaml — ClusterIP Service on :8084
|
||||||
|
├── 40-networkpolicy.yaml — ingress from approval-service / testagent-transform / dummy-sink,
|
||||||
|
│ egress to TLog + trust-pg + Pocket-ID JWKS
|
||||||
|
└── README.md — this file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Apply order
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl apply -f deploy/trillian/00-namespace.yaml # if not yet applied
|
||||||
|
kubectl apply -f deploy/verification-service/00-serviceaccount.yaml
|
||||||
|
# Create the dev Secret separately (see "Secret convention" below) — DO NOT
|
||||||
|
# commit the real values. The .example file is a template, not a secret.
|
||||||
|
kubectl apply -f deploy/verification-service/20-deployment.yaml
|
||||||
|
kubectl apply -f deploy/verification-service/30-service.yaml
|
||||||
|
kubectl apply -f deploy/verification-service/40-networkpolicy.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Reach the service in-cluster at:
|
||||||
|
|
||||||
|
```
|
||||||
|
http://verification-service.agent-trust.svc.cluster.local:8084
|
||||||
|
```
|
||||||
|
|
||||||
|
Health check (also used by Deployment probes):
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /healthz → 200 {"status":"ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify endpoint (per ADR-0006 / DEV-612):
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/v1/verify/chain
|
||||||
|
Content-Type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
## K8s secret convention
|
||||||
|
|
||||||
|
The verification-service only reads one Secret — `verification-service-dev`
|
||||||
|
(or `verification-service-prod` when the key rotation uses production
|
||||||
|
material). The Secret shape is a single key, `VERIFICATION_SIGNER_KEYS`,
|
||||||
|
whose value is the comma- or newline-separated keyid=`<enc>:<data>` spec
|
||||||
|
documented in `services/verification-service/README.md`.
|
||||||
|
|
||||||
|
For the GitOps path, convert the created Secret to a SealedSecret with
|
||||||
|
`kubeseal` and commit the sealed form under the same filename as the
|
||||||
|
example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create secret generic verification-service-dev -n agent-trust \
|
||||||
|
--from-file=VERIFICATION_SIGNER_KEYS=./signer-keys.spec \
|
||||||
|
--dry-run=client -o yaml | \
|
||||||
|
kubeseal --controller-namespace=sealed-secrets --format=yaml \
|
||||||
|
> deploy/verification-service/10-secret-dev.sealed.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## NetworkPolicy
|
||||||
|
|
||||||
|
See `40-networkpolicy.yaml`. In short:
|
||||||
|
|
||||||
|
- **Ingress:** `approval-service`, `testagent-transform`, `dummy-sink`
|
||||||
|
pods (matched by `app.kubernetes.io/name`).
|
||||||
|
- **Egress:** `transparency-log` (:8080), `trust-pg` (:5432), external
|
||||||
|
HTTPS/443 for the Pocket-ID JWKS, DNS to `kube-dns`.
|
||||||
|
|
||||||
|
## Image
|
||||||
|
|
||||||
|
Images are built by `.forgejo/workflows/build-images.yml` on every push
|
||||||
|
to `main` and pushed to:
|
||||||
|
|
||||||
|
```
|
||||||
|
harbor.basicstack.de/basicstack/verification-service:<git-sha>
|
||||||
|
harbor.basicstack.de/basicstack/verification-service:main (floating)
|
||||||
|
```
|
||||||
|
|
||||||
|
The Deployment currently references `:dev`; a GitOps apply will pin it
|
||||||
|
to a `:<git-sha>` once the image build pipeline has produced one.
|
||||||
Loading…
Add table
Reference in a new issue