- services/transparency-log/pkg/backend/trillian.go: real gRPC client on github.com/google/trillian v1.6.1. Submit() does QueueLeaf with the canonical DSSE envelope as LeafValue and the raw content_hash bytes as LeafIdentityHash, then polls GetLatestSignedLogRoot + GetInclusionProofByHash until the leaf is sequenced. Idempotency uses Trillian's ALREADY_EXISTS signal on the inner QueuedLogLeaf.Status, so a repeated submit still returns 200 OK with the originally-assigned log_index + a valid proof against the current STH. - Unconfigured backend (missing endpoint or LogID) returns the historical ErrTrillianUnavailable so the httpapi layer keeps mapping it to 503 instead of silently 500. Existing stub-returns-503 test updated. - cmd/transparency-log: pointer-receiver Trillian wiring; flag docs mention the production SRV name. - services/transparency-log/Dockerfile: distroless multi-stage build used by deploy/trillian/40-transparency-log.yaml. - deploy/trillian/: full K8s stack for the agent-trust namespace — MySQL 8.4 StatefulSet (schema init ConfigMap vendored from upstream storage.sql v1.6.1), Trillian LogServer + LogSigner Deployments on gcr.io/trillian-opensource-ci:v1.6.1, createtree Job that writes the TreeID to a ConfigMap (re-apply safe), transparency-log Deployment with --backend=trillian pulling TRILLIAN_LOG_ID from the ConfigMap. - deploy/trillian/README.md: first-time apply + smoke-test + secret rotation + signer-key clarification (STH key is Trillian-internal; DSSE envelope signing stays with signing-service / OpenBao). - services/admin-api: go.mod / go.sum pick up the new transitive deps (trillian + grpc) via the local replace on transparency-log. - services/transparency-log/README.md: Backends table updated; next- steps list no longer carries Trillian-deployment as a follow-up. Deployed to the live cluster from this heartbeat: MySQL + LogServer + LogSigner running in agent-trust, tree id 8482455225499059043, service smoke-tested end-to-end (201 on first POST, 200 on idempotent repeat, 409 on content_hash mismatch, tree_size=2 with correct audit path). Co-Authored-By: Paperclip <noreply@paperclip.ing>
115 lines
4.4 KiB
YAML
115 lines
4.4 KiB
YAML
---
|
|
# ConfigMap populated by the createtree Job below. The transparency-log
|
|
# Deployment reads TRILLIAN_LOG_ID out of this ConfigMap. The Job owns
|
|
# writing the value; GitOps owns the structure of this object.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: trillian-log-id
|
|
namespace: agent-trust
|
|
data:
|
|
TRILLIAN_LOG_ID: ""
|
|
---
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: trillian-createtree
|
|
namespace: agent-trust
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata:
|
|
name: trillian-createtree
|
|
namespace: agent-trust
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["configmaps"]
|
|
resourceNames: ["trillian-log-id"]
|
|
verbs: ["get", "patch", "update"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: trillian-createtree
|
|
namespace: agent-trust
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: trillian-createtree
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: trillian-createtree
|
|
namespace: agent-trust
|
|
---
|
|
# One-shot Job: creates a Trillian LOG tree the first time it runs and
|
|
# writes the TreeID into the ConfigMap above. On a re-run the Job detects
|
|
# a non-empty ConfigMap value and exits early — so it is safe to re-apply.
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: trillian-createtree
|
|
namespace: agent-trust
|
|
spec:
|
|
backoffLimit: 3
|
|
template:
|
|
spec:
|
|
restartPolicy: OnFailure
|
|
serviceAccountName: trillian-createtree
|
|
containers:
|
|
- name: createtree
|
|
image: golang:1.23-alpine3.21
|
|
env:
|
|
- name: TRILLIAN_ADMIN_SERVER
|
|
value: trillian-log-server.agent-trust.svc.cluster.local:8090
|
|
- name: NAMESPACE
|
|
value: agent-trust
|
|
- name: CONFIGMAP_NAME
|
|
value: trillian-log-id
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
set -eu
|
|
apk add --no-cache git curl ca-certificates jq
|
|
# Short-circuit if the ConfigMap already carries a tree id.
|
|
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
|
|
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
API="https://kubernetes.default.svc"
|
|
EXISTING=$(curl -sS --cacert "$CACERT" -H "Authorization: Bearer $TOKEN" \
|
|
"$API/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIGMAP_NAME" \
|
|
| jq -r '.data.TRILLIAN_LOG_ID // ""')
|
|
if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ] && [ "$EXISTING" != "0" ]; then
|
|
echo "trillian-log-id ConfigMap already carries TRILLIAN_LOG_ID=$EXISTING, nothing to do."
|
|
exit 0
|
|
fi
|
|
echo "Building createtree from source (one-shot)..."
|
|
GOFLAGS=-mod=mod GOBIN=/usr/local/bin \
|
|
go install github.com/google/trillian/cmd/createtree@v1.6.1
|
|
echo "Calling admin RPC at $TRILLIAN_ADMIN_SERVER ..."
|
|
# Trillian v1.6+ removed per-flag hash/signature algorithm choices
|
|
# from createtree. The server always uses SHA256 + RFC6962_SHA256
|
|
# for LOG trees; the Trees row's PrivateKey column is unused in
|
|
# modern Trillian (STH signatures use the server's own key).
|
|
TREE_ID=$(createtree \
|
|
--admin_server="$TRILLIAN_ADMIN_SERVER" \
|
|
--tree_type=LOG \
|
|
--display_name=proofedmesh-transparency-log \
|
|
--description="ProofedMesh Transparency Log (ADR-0005)" \
|
|
--max_root_duration=0s 2>&1 | tail -n1)
|
|
# createtree writes the integer tree id to stdout as the last line.
|
|
TREE_ID=$(printf '%s' "$TREE_ID" | tr -d '[:space:]')
|
|
if [ -z "$TREE_ID" ] || [ "$TREE_ID" = "0" ] || ! printf '%s' "$TREE_ID" | grep -qE '^[0-9]+$'; then
|
|
echo "createtree returned no tree id" >&2
|
|
exit 1
|
|
fi
|
|
echo "Got tree id: $TREE_ID"
|
|
# Merge-patch the ConfigMap with the fresh tree id.
|
|
PATCH=$(printf '{"data":{"TRILLIAN_LOG_ID":"%s"}}' "$TREE_ID")
|
|
curl -sS --cacert "$CACERT" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/merge-patch+json" \
|
|
-X PATCH \
|
|
-d "$PATCH" \
|
|
"$API/api/v1/namespaces/$NAMESPACE/configmaps/$CONFIGMAP_NAME"
|
|
echo
|
|
echo "Patched ConfigMap trillian-log-id with TRILLIAN_LOG_ID=$TREE_ID"
|