feat(make): registry-login via vaulted Forgejo token (kaizen)

scripts/registry-login.sh reads vault.forgejo.registry_token and pipes it to
docker login --password-stdin (never echoed, never on argv); 'make registry-login'
wires it with the venv binaries. Adds the operator-minted CHANGEME vault stub
(fill via make edit-vault) and a per-machine prereq note in the claude-code-setup
runbook, so 'make caddy-image-push'/'molecule-image-push' become agent-completable
non-interactively. Consumes the 2026-06-15 signal in docs/FRICTION.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sjat 2026-06-17 17:50:07 +02:00
parent 39904a778a
commit c1323a3f29
4 changed files with 158 additions and 86 deletions

View file

@ -23,6 +23,11 @@ MOLECULE_DOCKERFILE := .docker/molecule-debian13/Dockerfile
# (the Go module proxy 403s Hetzner IPs); push the pinned tag to the Forgejo registry. # (the Go module proxy 403s Hetzner IPs); push the pinned tag to the Forgejo registry.
CADDY_IMAGE := forgejo.nyumbani.baobab.band/sjat/caddy-gandi:2.11.4 CADDY_IMAGE := forgejo.nyumbani.baobab.band/sjat/caddy-gandi:2.11.4
CADDY_DOCKERFILE := .docker/caddy-gandi/Dockerfile CADDY_DOCKERFILE := .docker/caddy-gandi/Dockerfile
# Forgejo container registry (same host/user as the image tags above). `make registry-login`
# logs the Docker daemon in using vault.forgejo.registry_token (2026-06-17 kaizen) so image
# pushes are agent-completable non-interactively.
REGISTRY_HOST := forgejo.nyumbani.baobab.band
REGISTRY_USER := sjat
# For TF_ENV=offsite, source the Hetzner token from the vault into the environment # For TF_ENV=offsite, source the Hetzner token from the vault into the environment
# (rbw must be unlocked). Read in-memory; never written to a tfvars file (CLAUDE.md). # (rbw must be unlocked). Read in-memory; never written to a tfvars file (CLAUDE.md).
@ -37,7 +42,7 @@ endif
.PHONY: help setup collections lint test test-all check deploy encrypt decrypt \ .PHONY: help setup collections lint test test-all check deploy encrypt decrypt \
edit-vault check-vault new-role \ edit-vault check-vault new-role \
tf-init tf-plan tf-apply tf-output tf-inventory tf-inventory-offsite \ tf-init tf-plan tf-apply tf-output tf-inventory tf-inventory-offsite \
molecule-image molecule-image-push caddy-image caddy-image-push molecule-image molecule-image-push caddy-image caddy-image-push registry-login
help: help:
@echo "" @echo ""
@ -69,6 +74,7 @@ help:
@echo " make molecule-image-push Push the test image to the Forgejo registry" @echo " make molecule-image-push Push the test image to the Forgejo registry"
@echo " make caddy-image Build the custom Caddy + Gandi DNS-01 image (run on ubongo)" @echo " make caddy-image Build the custom Caddy + Gandi DNS-01 image (run on ubongo)"
@echo " make caddy-image-push Push the Caddy image to the Forgejo registry" @echo " make caddy-image-push Push the Caddy image to the Forgejo registry"
@echo " make registry-login Log Docker into the Forgejo registry (vaulted token)"
@echo "" @echo ""
# ── Environment setup ───────────────────────────────────────────────────────── # ── Environment setup ─────────────────────────────────────────────────────────
@ -159,6 +165,13 @@ caddy-image:
caddy-image-push: caddy-image caddy-image-push: caddy-image
docker push $(CADDY_IMAGE) docker push $(CADDY_IMAGE)
# Log the local Docker daemon into the Forgejo registry using the vaulted token, so the
# *-image-push targets above are agent-completable non-interactively (rbw must be unlocked).
registry-login:
@ANSIBLE_VAULT="$(ANSIBLE)-vault" PYTHON="$(PYTHON)" VAULT="$(VAULT)" \
REGISTRY_HOST="$(REGISTRY_HOST)" REGISTRY_USER="$(REGISTRY_USER)" \
bash scripts/registry-login.sh
# ── Terraform ───────────────────────────────────────────────────────────────── # ── Terraform ─────────────────────────────────────────────────────────────────
tf-init: tf-init:

View file

@ -50,6 +50,13 @@ Don't install these until their trigger lands — then add them here and to
- **The venv-activate hook** — this repo expects the Python `.venv` active for Bash - **The venv-activate hook** — this repo expects the Python `.venv` active for Bash
commands. If you use the user-level `~/.claude/hooks/activate-venv.sh` pattern, commands. If you use the user-level `~/.claude/hooks/activate-venv.sh` pattern,
replicate it; otherwise `source .venv/bin/activate` per session after `make setup`. replicate it; otherwise `source .venv/bin/activate` per session after `make setup`.
- **Forgejo registry login (for image pushes)**`make caddy-image-push` /
`molecule-image-push` need the Docker daemon authenticated to
`forgejo.nyumbani.baobab.band`. Run **`make registry-login`** once per machine: it reads
`vault.forgejo.registry_token` from the vault and does `docker login --password-stdin`
(no interactive prompt, so an agent can complete a push). The token is operator-minted
(Forgejo → Settings → Applications → Generate Token, package read+write) and set via
`make edit-vault`; until then `registry-login` prints how to obtain it. (2026-06-17 kaizen.)
## 4. A note on user-level settings ## 4. A note on user-level settings

View file

@ -1,86 +1,106 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
32313030663934353361336234373562303537356334346238663836373238366136356331363761 30393235363534356266376565386264666431656562646165333332393034663939353961343531
6337323031666565663430303562646565303533653531640a636662373939363632383838613431 6436663865303965393737633462393331393562336537650a326265306465366433393331343362
38313365626365373539653266326661393765333737386161666165666534636562353165386537 62383039303432653139623636396533313336326266363264393065343834316666613765346265
3934633033383966360a323965333139643764326236396635383863353437313966326665373537 6238336566383161630a653130623266323738656338616239393032303863656438333839396438
65396564393130303030643861663964383436396561643666623837306366346333306430306238 36336264316331363033353934333463376462366165643737633334313761316565616635643361
66656136626566626262373037623531623633313664376166376161363336353930636538323339 63303361656536666130626337623832663065386263356364626530633435636537646664336363
38386564333432353363353663643539343765373662643836646666626339353539323033386230 37326435346639633463306337303232393363396638313631366365376230386231626435616364
31613165373035363533383862366638353035653836303737656534623361313064616365643131 34353237623761396537333230326266323063306466326539333237326233303036626161353965
64386165653835366137353339396364313661656333333635616338346561363765353934343162 65613461633261653763336432333830346431356636623738336332343865343035346263626231
64346462656566376539643030656461363161393936623332373632653731303031393437316636 30653337643964323336316365323461313338376131323861663962336238346235666664613932
36626165306161336262356161666531323336343663643661626365396437383230613636356530 62356566306233623936663734666639356233333537373866633361313933623532643161386463
62326363383138643162316464396666623332366434336462363531363836313833366237396464 36666565303737303663366631646535303863333761303731613332373665613261343064636561
38323635353238653432626361383434646538326531356333393337643066373262663462656466 35636337396139336461356338333164316135623838383564653066363064376662653039333664
65373036653265616137666533373930333239303732623832353337343434636434616562336135 62306165613433626264616334643761343263623566346432653638636138326136636335313235
38666137353266353130303235616362323633353735373163336138633838633738393637633964 64373236343630626632623337653334383132373662306165633038303830386336373634656438
66623866353265316336336566663034306664656365643832616232313732626464316563636335 31613431626166376536613439616363363464303763656238643339373365393636386138656634
63653930626565636630326661626561366539303964373933653437356537343361626438313439 34356332343366623462323434363338383061346430326434343139303866306331393465333332
35643165636662643463616337323063343633306536346538623331333365366533653634343538 36666339383066613762353866653032313435343663333433653563393564643038313062633338
63623261636366303261373338633939363338316463303065613436396163616537666265623439 37663565336636356631373238373638346233616336363630326134646434666165386336393530
31383361646531633863623230616635646138653630383537366335633030343530383735616435 32326431353637336432336639636663373330663433613931646638626564653364353036313562
35656464393432313563303030626133383761303763653530653837313930303034353136353237 31353763633561393538326663633731313363366230363230313232373230626162643062653561
37376366623836646236363062633938666135326631376235323061666465373865396235643937 61636166613761646534653230623234623035336332643961623636306161623934303364633664
32633736656539356332336237646137303534343337353139383637623165353338623566666535 38363239393863393431643662396362653437616138316336666638303663643831376466356633
30643134303235633362383064376234366235363262396362613731373364306362303634613138 32643661653635393836376663373838333366383833316635363864353862666534373530356231
39366230366262363237656631646361356464393266656166386337303663313136666261633836 39666132636361386236623734333862663133343939386432313730623439343961646633333936
32306132323239343539396232316564326361626462366561313561393635393233653633646431 36373232303263396435663163306135663361623531313734663438363730323835343866623533
39313039313139616262396334613035333633326135346365333537373138396535633137353832 37613830666236376461643238663336623032356238313563616437363638333338306438663461
63636335613237623234646234653435616635356637343964656463383864366534363438343938 62663035303737623635326536613564393962303462326233366137616565373034393839346565
39626364653832373062323434316134653831336534383934346231656533643435306465393065 66633637663463643030316639366633363866643366336166393535353366316364643335353035
31653731653438646361363732303664626438663533393837356562376633643933376132616236 32343935363536633162316634393530376332653635326464326631396464343931663133656465
65393432633831313433323930383736316630626230373963653536396637363436643136363962 38656335306639343736346334636661636635333066663565643764373432333161653063323231
37326534343237363961326438376137663034356532376433376461363337333562646136616462 37333464316536363037323362333432373162363833303130643534343461646563343564386565
61636131376264393236376532356539376536643632623864656331656630353362623133303830 33363437376237633739623863353232343438306639303561646139396137646234663534636237
34633461633539643262353263376363613566343261373930623139626364653232363538353330 30663332306162366233636666316336313538623730333162376264383463666661613436656265
33633634363232653439656236303262373265613762373165646131383537623438383835383962 37643738313335353030383663383461663036376637346334643531636438656133393731383138
33383931626136313036366562363732396561633631643561646536653665333733383261363833 63653338306639653266366337653865363432366364306262303232616536393738323334346334
66356461663965373234393237323037356331333339643931313936313234323432613563306630 33646331316330633738386236323533353734623234653335643633643866393761653232303162
33306638663839363565636661653830316265393639313065313062666534303039326465373636 31653530643934373435326539366663313033616338666633313131353334323931383635346235
64363033323837313030353132383562343337326366626635663439396231393537313932643337 32333166636135323438353735616265373132393762323037326635633162653363393639633939
30663031323231313938366436343735326165326433656633336465316630383961626664303536 37613231343766653437626235313666343837343865303863643035633863373235656439346538
38633964326431643362626631656131303539613033323039393630353766386339346363663362 32613934366138653331343931386131663134623063366435623835653535623334376333366562
33323034396136356362313163376438393739373738366363623636623634316537313461373066 65366365386239663338656233353435343639353037663732323064626261636363643261656164
38613062656231363532663133333438663535666566356336316266383763623765346237663838 66393538343638373064376536326537623735343064643736636466323636316130373565643635
64336435353437373264346561363265643339306532383539306363653564356362313430333066 31383531306431363533663935356339373934396361306138633266653431326132386563366565
65633733633938343830303537383231303036326132376263363531626565633664343038356661 34646465356139636563653732373932636461313935376235366266636136663238663030373662
31336139663061656437633138373438663966616338343565396562306638346437353730643664 31336635653666326538333931646235316262303838633138613464303837386162613263386438
30373133373863626137313062643062393035653463653231653465333166633063353137633538 34366230353439323531646637326634616336343963373831356163373462343664393538353835
62383331303164343236343539396461623738396234653333356632313664616263623061363563 66616235616363333430313539333637626665386562653834343139663133383463393236633662
34323165306533323362376161346364316135333535626261353730666131643938306366326263 30303937376661323535333132653966383231353033633334356663646265613934336636363138
31313934633137623638316534383234376333396131303034633636323037363732383263326335 65643265373334653932316262303136363763396134303730383536646538663134303964323432
32393766343161386537333062643434333333363538323366363231336666383161373432383563 39303833386361363364303231656364356365653939373661633661313739356665323834306635
65613537366139643032336230303133623431376231646662643666373532636565393639373930 32653933626166396462666235353238383266336361616531316433363433336238656539373661
65336630616462353837666431616662636635333532393331326539306233363539396266653239 62306362666333653865396364663235626230303133343764613536616237313634613734393631
31303031303330396632386131623134313536313433623064356636333230373962643339363736 32373761626161363935346437396161383365633138393164663539626439353832613437653261
30396130353466373136643935646436613636376636323530643031653334303863376432646534 35376464313236666236313965376133323333663030383965333935383237633461646266633363
39343165356232346539366233373135326338343663356164616265336235623332646365633466 35656561343033306162616361653062363538356136353837343866636632623765646366396638
35393533373663393762376332396136336236616635616535313336613034346436363665356565 35313134383361346332323232643030303434363732653236366538376166333237323566383930
32636536336634613531393434613435613962653862343737373237623261373836386663343831 62356162656538636464616432626637633531363237376337353562393731633635323536386363
66656135323838636638353963646638326531343635653937306230323237343933626135356533 31623936663935366164373062333465383137633661393062386135376635346262336538346165
66356263636438633164386535333762616438626439343462393833393731643037396662653737 34663561663134306635373737383430343332633365356238346264376136363862613762313166
31666361656530383437396230393663616133383764316437623939663631396561343266383766 39323635396434386537646435366630353462313463366666626135623633386336376466353830
62373636663631393637393763613337356337633264366434346561343263373931323335643135 64373763306464346336643531616233633237663534333536666264633564623030343533373430
31366661623137353336666630633365663764646234343035313130663562636361623532643461 38623738623264396564316666663763356136623865623662393766343566376465633839353466
63333961333338623966396662656262323830396439633337663431663235663962666238356630 66313333666131626639656464666130653239313864656330666666653237306131633139336565
30353331313462653061373638666235653938623931366466666164343566623238333237353265 33333536653638386431373432663132643033313566376261376535363563356135353735346464
30373064353132366634623966306632303832306630383637623465323134633133656333303964 66623032303639313163303739346637333839323939356364376133346363343163343661646661
35646637316236303364393363323137616132326437623238336631313530663230333362623633 65643462356234353562346435623463633665343037313032363362643461356566623731363030
34383032376538366464363032343262656164376166386237383563613630336666633965653730 66353530353237666132613435306537613038653062336663373366343834323238656162656538
64373236396564363164643637623736626532396630313131356563333238643665356166323837 31383037613535303564633732346332613939333037343334646530386331643336363834313365
31626338623665623165643763623661666439626435643237336433646132666366623661393832 66613535353631643566363062643930323966343636353666626237663733363062653564633562
37306533613966663936373061613331633934623462343236626234306130383738343631303231 39313034643238366331636332393537376130386463653831393366636634623833366436303961
32326339323738323537333363313538373266623363363636633462356234363466393263316235 34633162333462383834346637343337616166353035616362636462346364366539383333373964
39663033303165656366396334306535643361646663373935303230376466366632373563303231 62343635323331376237373761383535646233366465303364663731393061326436663137613238
64323264653036333039663965646630653934376239653236323063656137373830623563336463 35363338613339326336613535326635363236356264326330386662393666613264646465316339
37343461373737313539316361623763373733653930626532393565333938333761323631303332 36633263626632613862613439363630353462626636373265386332316162356439323134636433
39663530303439616561356561666532653762343339323435636164376664373731343132666539 34393334316561366231613339386339653663316661356662306230356537626431376133333736
63626637346563393765303065646564643661636130396439323736343764333633373331653333 31663034373033666663363634386134376237663061323732653365363662323335653433656665
66633465343433303038623638323965636533666639643266353163353436393036336639336133 30323566326530653365613937376264383435636438333734386131363737633163343734336564
32646664363565326539643763653832313336663262313634343635616333613434373333323036 32633432613033653263356334666436353036373738346430373133346239313566346236376138
61366435376265336638326132333439613431353633653762653836386235643965366436363866 64323565663961356331323937373032306330646664663761646131646235383731303564633366
35626664393139386337353335343930306130356335623131646261656434303966656431623231 32656537343836326465343264363531396631613161633236366363366537613439376464653866
66643730393430363838626434663933613536343533316262373564666665373663336363623166 61316164363032313630383063336436303661366438623666373538396432303331623139393833
63363037373634383961373035633239646235316137363036333765313864643365396165643432 33653061363766313465633964353439383136343832323630666630323865326461666137313132
36623465313036376261393566383539336638363836633232656136656533396663323366313062 62333963323564396139333130303539623935303733616138376466303461643439373934393432
64616632373333313466356362336234346564373832316433373963623263316635 38356535663333343232306135623261336534383233333632386638623232383737616239326666
38643139623730643439373939616562393162376564346130643135653334616338333739313935
33343563346664346531623161313937636562653132613831303132363665343333633232373633
30363034373362626266633562633634643635343161613262373463616437396566343733626561
30626462313261383461653532396263663139323134653764363963393665653165326130643031
36303962313433623034633930633762393263383830663261653631333830643637313332613136
66636364373137306539643566633830393030393932336632646565383638343639623232316165
63333637616237313262646539363835346138613234376164333238643139653934343365386632
37633562633863373033666564666665396261386537653866353533336233316339656365356563
33663561643531623837656237313938303363363662383830363435323661306164383932613438
63623963336361356639303162373935613734666466663933646239363939616239323164303364
62393765343539646633616630313463633963396432636637313162666432386637616233343532
39343366323236336266396438326565343561313330313539366439343262396361386662323434
30313433323063316531613338303239333539316133623961316432616632613066636136336436
35613864363731373333313637363036303561343263316466303935313664646635396331323039
31333134316535356134666365306263303337623636353430333731343037656661363333643165
30383734336662336632356537376232623664653436396464633037643839343238623330613136
31663137366437396330333231303636633461616230383339646261303964393539393637643730
30626463313434646566313939656432313066356232303435313734353930336265343431346362
36346666643230303565613563313634393338323735373965336138646432363534383066383236
30383230666335393861653937316233633534316666643865643439313938633230

32
scripts/registry-login.sh Executable file
View file

@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# Log the local Docker daemon into the Forgejo container registry using a token stored in
# the Ansible vault — so registry pushes (make caddy-image-push / molecule-image-push) are
# agent-completable non-interactively, like every other vault-backed action.
# (2026-06-17 kaizen, docs/FRICTION.md: the push half silently needed an interactive
# `docker login`; the creds weren't in the vault, so an agent couldn't complete a push.)
#
# Reads vault.forgejo.registry_token from the vault (rbw must be unlocked) and pipes it to
# `docker login --password-stdin`. The token never lands on argv or on disk and is never
# echoed (no `set -x`). Binaries/paths are overridable via env so the Makefile can pass the
# venv ansible-vault/python; defaults work when run from the repo root with the venv present.
#
set -euo pipefail
ANSIBLE_VAULT="${ANSIBLE_VAULT:-.venv/bin/ansible-vault}"
PYTHON="${PYTHON:-.venv/bin/python}"
VAULT="${VAULT:-inventories/production/group_vars/all/vault.yml}"
REGISTRY_HOST="${REGISTRY_HOST:-forgejo.nyumbani.baobab.band}"
REGISTRY_USER="${REGISTRY_USER:-sjat}"
token="$("$ANSIBLE_VAULT" view "$VAULT" \
| "$PYTHON" -c 'import sys, yaml; d = yaml.safe_load(sys.stdin) or {}; print((((d.get("vault") or {}).get("forgejo") or {}).get("registry_token")) or "", end="")')"
if [ -z "$token" ] || [ "$token" = "CHANGEME" ]; then
echo "registry-login: vault.forgejo.registry_token is unset or still CHANGEME." >&2
echo " Mint a Forgejo token (Settings -> Applications -> Generate Token, with package" >&2
echo " read+write scope, user $REGISTRY_USER) and set it via: make edit-vault" >&2
exit 1
fi
printf '%s' "$token" | docker login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin