Files
devops-infra-argo-config-gcp/secretstores/toolshed-harbor-cleanup.yaml
T
Mukul SharmaandClaude Opus 5 89a0aacbd7 Add toolshed-harbor-cleanup: a delete-scoped Harbor robot for builder
Deliberately separate from harbor-robot-dockerconfig, which is mounted
into build pods running arbitrary user Dockerfiles and is scoped to
push+pull only. This one is held by builder itself — a trusted platform
service that never executes user code directly — and carries a
permission the other should never have: delete. A leaked build-pod
credential can never delete anything this way, and a leaked cleanup
credential can never push.

Used by toolshed's cleanupImage (internal/builder/builder.go) to remove
an app's Harbor repository when the app itself is deleted. Nothing
destructive happens until the Vault path this pulls from is actually
populated — builder logs and skips that step otherwise, per its own
code comment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 21:17:45 +05:30

50 lines
2.0 KiB
YAML

# Harbor management-API credentials for toolshed's builder, used only to
# delete a repository (every tagged image an app's builds ever pushed) when
# the app itself is deleted.
#
# Deliberately a separate robot account from harbor-robot-dockerconfig
# (secretstores/harbor-robot-dockerconfig.yaml), not a reuse of it. That one
# is mounted into build pods, which run arbitrary user-supplied Dockerfiles —
# scoped to push+pull only. This one is held by builder itself, a trusted
# platform service that never executes user code directly, and needs a
# permission the other should never carry: delete. Keeping them on separate
# credentials means a leaked build-pod credential can never delete anything,
# and a leaked cleanup credential can never push.
#
# Create the robot in Harbor's UI: homelab project -> Robot Accounts ->
# New Robot Account. Scope it to that one project, permission "Delete
# repository" (and "Delete artifact") only — leave push/pull unchecked, it
# never needs them. Harbor shows the generated secret exactly once.
#
# kubectl -n vault exec -i vault-0 -- sh -lc '
# vault login <root-token> >/dev/null &&
# vault kv put secret/harbor/toolshed-cleanup \
# username="robot\$homelab+toolshed-cleanup" \
# password="<the generated secret>"'
#
# Until this exists, builder logs "no management credentials, leaving its
# image alone" for every app deletion and does nothing destructive — see
# internal/builder/builder.go's cleanupImage in the toolshed repo.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: toolshed-harbor-cleanup
namespace: toolshed
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: toolshed-harbor-cleanup
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: harbor/toolshed-cleanup
property: username
- secretKey: password
remoteRef:
key: harbor/toolshed-cleanup
property: password