ProofedMesh/deploy/approval-service/20-deployment.yaml
CTO (Paperclip) 20ba29d3ac
All checks were successful
build-images / signing-service image (push) Successful in 26s
build-images / verification-service image (push) Successful in 27s
build-images / approval-service image (push) Successful in 31s
build-images / dummy-sink image (push) Successful in 29s
validate / JSON Schema (ajv) (push) Successful in 23s
validate / Rego (opa fmt + opa test) (push) Successful in 16s
phase1-smoke / Phase 1 end-to-end smoke (push) Successful in 1m0s
validate / DB (migrate up/down dry-run) (push) Successful in 26s
validate / Go (vet + test) (push) Successful in 1m20s
approval-service: K8s deployment manifests + Pocket-ID OIDC client (DEV-614)
Phase-1 Subtask 8/10 (parent DEV-606):
- deploy/approval-service/: SA (no auto-mount), Deployment (replicas=2,
  distroless-nonroot, read-only rootfs), ClusterIP :8080, NetworkPolicy
  (ingress from pangolin namespace only; egress to signing-service,
  transparency-log, trust-pg in agent-trust + pocket-id + DNS), README.
- 10-secret-dev.example.yaml template + the real 10-secret-dev.sealed.yaml
  carrying the Pocket-ID client id/secret, WebAuthn RP config, and the
  dev signing-service bearer; unsealed in-cluster to Secret
  approval-service-dev.
- services/approval-service/Dockerfile: BuildKit multi-stage, context-at-
  repo-root, matches the signing/verification/dummy-sink pattern.
- .forgejo/workflows/build-images.yml: new approval-service job pushing
  harbor.basicstack.de/basicstack/approval-service:{sha,main} on main.
- Pocket-ID: created proofedmesh-admin group + OIDC client
  "ProofedMesh Approval" with PKCE enforced, callback
  https://approval.proofedmesh.basicstack.de/oidc/callback, group
  restriction to proofedmesh-admin. Client secret stored as Paperclip
  secret proposal and in the SealedSecret above — never pasted inline.

Deployment applied cluster-side pending the first CI image build:
`kubectl apply -f deploy/approval-service/` is green; pods ErrImagePull
until the Forgejo workflow completes and pushes the :main tag.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-25 21:12:01 +00:00

120 lines
4 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: approval-service
namespace: agent-trust
labels:
app.kubernetes.io/name: approval-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: approval-service
template:
metadata:
labels:
app.kubernetes.io/name: approval-service
app.kubernetes.io/part-of: proofedmesh
app.kubernetes.io/component: trust-core
spec:
serviceAccountName: approval-service
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: approval-service
image: harbor.basicstack.de/basicstack/approval-service:main
imagePullPolicy: IfNotPresent
args:
- "-listen=:8080"
- "-signing-url=http://signing-service.agent-trust.svc.cluster.local:8081"
- "-signing-key-ref=trust-api/approval-signer-2026-q4"
- "-tlog-url=http://transparency-log.agent-trust.svc.cluster.local:8080"
- "-session-ttl=15m"
- "-challenge-ttl=2m"
env:
# ---- Pocket-ID OIDC issuer for attestation `issuer` field +
# future auth middleware discovery (DEV-614). ----
- name: APPROVAL_POCKET_ID_ISSUER
value: "https://auth.basicstack.de"
- name: APPROVAL_POCKET_ID_CLIENT
valueFrom:
secretKeyRef:
name: approval-service-dev
key: APPROVAL_POCKET_ID_CLIENT
# ---- Pocket-ID client secret (OIDC authorization_code +
# client_credentials; Phase 2 middleware consumes it). ----
- name: APPROVAL_POCKET_ID_SECRET
valueFrom:
secretKeyRef:
name: approval-service-dev
key: APPROVAL_POCKET_ID_SECRET
# ---- WebAuthn RP config (DEV-608): must match the browser
# origin reached via Pangolin/Traefik. ----
- name: APPROVAL_WEBAUTHN_RP_ID
valueFrom:
secretKeyRef:
name: approval-service-dev
key: APPROVAL_WEBAUTHN_RP_ID
- name: APPROVAL_WEBAUTHN_RP_ORIGIN
valueFrom:
secretKeyRef:
name: approval-service-dev
key: APPROVAL_WEBAUTHN_RP_ORIGIN
# ---- Bearer the approval-service presents to signing-service. ----
- name: APPROVAL_SIGNING_TOKEN
valueFrom:
secretKeyRef:
name: approval-service-dev
key: APPROVAL_SIGNING_TOKEN
ports:
- name: http
containerPort: 8080
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: "500m"
memory: "256Mi"
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: approval-service