116 lines
4.2 KiB
Markdown
116 lines
4.2 KiB
Markdown
|
|
# 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.
|