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
This commit is contained in:
co-authored by
Claude Opus 5
parent
cab110c268
commit
89a0aacbd7
@@ -0,0 +1,49 @@
|
|||||||
|
# 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
|
||||||
Reference in New Issue
Block a user