From c1323a3f2978822316e42d96562bc57902e8268f Mon Sep 17 00:00:00 2001 From: sjat Date: Wed, 17 Jun 2026 17:50:07 +0200 Subject: [PATCH] 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) --- Makefile | 15 +- docs/runbooks/claude-code-setup.md | 7 + .../production/group_vars/all/vault.yml | 190 ++++++++++-------- scripts/registry-login.sh | 32 +++ 4 files changed, 158 insertions(+), 86 deletions(-) create mode 100755 scripts/registry-login.sh diff --git a/Makefile b/Makefile index 77193b4..a23efff 100644 --- a/Makefile +++ b/Makefile @@ -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. CADDY_IMAGE := forgejo.nyumbani.baobab.band/sjat/caddy-gandi:2.11.4 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 # (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 \ edit-vault check-vault new-role \ 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: @echo "" @@ -69,6 +74,7 @@ help: @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-push Push the Caddy image to the Forgejo registry" + @echo " make registry-login Log Docker into the Forgejo registry (vaulted token)" @echo "" # ── Environment setup ───────────────────────────────────────────────────────── @@ -159,6 +165,13 @@ caddy-image: caddy-image-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 ───────────────────────────────────────────────────────────────── tf-init: diff --git a/docs/runbooks/claude-code-setup.md b/docs/runbooks/claude-code-setup.md index 0c9b848..8898883 100644 --- a/docs/runbooks/claude-code-setup.md +++ b/docs/runbooks/claude-code-setup.md @@ -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 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`. +- **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 diff --git a/inventories/production/group_vars/all/vault.yml b/inventories/production/group_vars/all/vault.yml index 28c7b5d..8fade1c 100644 --- a/inventories/production/group_vars/all/vault.yml +++ b/inventories/production/group_vars/all/vault.yml @@ -1,86 +1,106 @@ $ANSIBLE_VAULT;1.1;AES256 -32313030663934353361336234373562303537356334346238663836373238366136356331363761 -6337323031666565663430303562646565303533653531640a636662373939363632383838613431 -38313365626365373539653266326661393765333737386161666165666534636562353165386537 -3934633033383966360a323965333139643764326236396635383863353437313966326665373537 -65396564393130303030643861663964383436396561643666623837306366346333306430306238 -66656136626566626262373037623531623633313664376166376161363336353930636538323339 -38386564333432353363353663643539343765373662643836646666626339353539323033386230 -31613165373035363533383862366638353035653836303737656534623361313064616365643131 -64386165653835366137353339396364313661656333333635616338346561363765353934343162 -64346462656566376539643030656461363161393936623332373632653731303031393437316636 -36626165306161336262356161666531323336343663643661626365396437383230613636356530 -62326363383138643162316464396666623332366434336462363531363836313833366237396464 -38323635353238653432626361383434646538326531356333393337643066373262663462656466 -65373036653265616137666533373930333239303732623832353337343434636434616562336135 -38666137353266353130303235616362323633353735373163336138633838633738393637633964 -66623866353265316336336566663034306664656365643832616232313732626464316563636335 -63653930626565636630326661626561366539303964373933653437356537343361626438313439 -35643165636662643463616337323063343633306536346538623331333365366533653634343538 -63623261636366303261373338633939363338316463303065613436396163616537666265623439 -31383361646531633863623230616635646138653630383537366335633030343530383735616435 -35656464393432313563303030626133383761303763653530653837313930303034353136353237 -37376366623836646236363062633938666135326631376235323061666465373865396235643937 -32633736656539356332336237646137303534343337353139383637623165353338623566666535 -30643134303235633362383064376234366235363262396362613731373364306362303634613138 -39366230366262363237656631646361356464393266656166386337303663313136666261633836 -32306132323239343539396232316564326361626462366561313561393635393233653633646431 -39313039313139616262396334613035333633326135346365333537373138396535633137353832 -63636335613237623234646234653435616635356637343964656463383864366534363438343938 -39626364653832373062323434316134653831336534383934346231656533643435306465393065 -31653731653438646361363732303664626438663533393837356562376633643933376132616236 -65393432633831313433323930383736316630626230373963653536396637363436643136363962 -37326534343237363961326438376137663034356532376433376461363337333562646136616462 -61636131376264393236376532356539376536643632623864656331656630353362623133303830 -34633461633539643262353263376363613566343261373930623139626364653232363538353330 -33633634363232653439656236303262373265613762373165646131383537623438383835383962 -33383931626136313036366562363732396561633631643561646536653665333733383261363833 -66356461663965373234393237323037356331333339643931313936313234323432613563306630 -33306638663839363565636661653830316265393639313065313062666534303039326465373636 -64363033323837313030353132383562343337326366626635663439396231393537313932643337 -30663031323231313938366436343735326165326433656633336465316630383961626664303536 -38633964326431643362626631656131303539613033323039393630353766386339346363663362 -33323034396136356362313163376438393739373738366363623636623634316537313461373066 -38613062656231363532663133333438663535666566356336316266383763623765346237663838 -64336435353437373264346561363265643339306532383539306363653564356362313430333066 -65633733633938343830303537383231303036326132376263363531626565633664343038356661 -31336139663061656437633138373438663966616338343565396562306638346437353730643664 -30373133373863626137313062643062393035653463653231653465333166633063353137633538 -62383331303164343236343539396461623738396234653333356632313664616263623061363563 -34323165306533323362376161346364316135333535626261353730666131643938306366326263 -31313934633137623638316534383234376333396131303034633636323037363732383263326335 -32393766343161386537333062643434333333363538323366363231336666383161373432383563 -65613537366139643032336230303133623431376231646662643666373532636565393639373930 -65336630616462353837666431616662636635333532393331326539306233363539396266653239 -31303031303330396632386131623134313536313433623064356636333230373962643339363736 -30396130353466373136643935646436613636376636323530643031653334303863376432646534 -39343165356232346539366233373135326338343663356164616265336235623332646365633466 -35393533373663393762376332396136336236616635616535313336613034346436363665356565 -32636536336634613531393434613435613962653862343737373237623261373836386663343831 -66656135323838636638353963646638326531343635653937306230323237343933626135356533 -66356263636438633164386535333762616438626439343462393833393731643037396662653737 -31666361656530383437396230393663616133383764316437623939663631396561343266383766 -62373636663631393637393763613337356337633264366434346561343263373931323335643135 -31366661623137353336666630633365663764646234343035313130663562636361623532643461 -63333961333338623966396662656262323830396439633337663431663235663962666238356630 -30353331313462653061373638666235653938623931366466666164343566623238333237353265 -30373064353132366634623966306632303832306630383637623465323134633133656333303964 -35646637316236303364393363323137616132326437623238336631313530663230333362623633 -34383032376538366464363032343262656164376166386237383563613630336666633965653730 -64373236396564363164643637623736626532396630313131356563333238643665356166323837 -31626338623665623165643763623661666439626435643237336433646132666366623661393832 -37306533613966663936373061613331633934623462343236626234306130383738343631303231 -32326339323738323537333363313538373266623363363636633462356234363466393263316235 -39663033303165656366396334306535643361646663373935303230376466366632373563303231 -64323264653036333039663965646630653934376239653236323063656137373830623563336463 -37343461373737313539316361623763373733653930626532393565333938333761323631303332 -39663530303439616561356561666532653762343339323435636164376664373731343132666539 -63626637346563393765303065646564643661636130396439323736343764333633373331653333 -66633465343433303038623638323965636533666639643266353163353436393036336639336133 -32646664363565326539643763653832313336663262313634343635616333613434373333323036 -61366435376265336638326132333439613431353633653762653836386235643965366436363866 -35626664393139386337353335343930306130356335623131646261656434303966656431623231 -66643730393430363838626434663933613536343533316262373564666665373663336363623166 -63363037373634383961373035633239646235316137363036333765313864643365396165643432 -36623465313036376261393566383539336638363836633232656136656533396663323366313062 -64616632373333313466356362336234346564373832316433373963623263316635 +30393235363534356266376565386264666431656562646165333332393034663939353961343531 +6436663865303965393737633462393331393562336537650a326265306465366433393331343362 +62383039303432653139623636396533313336326266363264393065343834316666613765346265 +6238336566383161630a653130623266323738656338616239393032303863656438333839396438 +36336264316331363033353934333463376462366165643737633334313761316565616635643361 +63303361656536666130626337623832663065386263356364626530633435636537646664336363 +37326435346639633463306337303232393363396638313631366365376230386231626435616364 +34353237623761396537333230326266323063306466326539333237326233303036626161353965 +65613461633261653763336432333830346431356636623738336332343865343035346263626231 +30653337643964323336316365323461313338376131323861663962336238346235666664613932 +62356566306233623936663734666639356233333537373866633361313933623532643161386463 +36666565303737303663366631646535303863333761303731613332373665613261343064636561 +35636337396139336461356338333164316135623838383564653066363064376662653039333664 +62306165613433626264616334643761343263623566346432653638636138326136636335313235 +64373236343630626632623337653334383132373662306165633038303830386336373634656438 +31613431626166376536613439616363363464303763656238643339373365393636386138656634 +34356332343366623462323434363338383061346430326434343139303866306331393465333332 +36666339383066613762353866653032313435343663333433653563393564643038313062633338 +37663565336636356631373238373638346233616336363630326134646434666165386336393530 +32326431353637336432336639636663373330663433613931646638626564653364353036313562 +31353763633561393538326663633731313363366230363230313232373230626162643062653561 +61636166613761646534653230623234623035336332643961623636306161623934303364633664 +38363239393863393431643662396362653437616138316336666638303663643831376466356633 +32643661653635393836376663373838333366383833316635363864353862666534373530356231 +39666132636361386236623734333862663133343939386432313730623439343961646633333936 +36373232303263396435663163306135663361623531313734663438363730323835343866623533 +37613830666236376461643238663336623032356238313563616437363638333338306438663461 +62663035303737623635326536613564393962303462326233366137616565373034393839346565 +66633637663463643030316639366633363866643366336166393535353366316364643335353035 +32343935363536633162316634393530376332653635326464326631396464343931663133656465 +38656335306639343736346334636661636635333066663565643764373432333161653063323231 +37333464316536363037323362333432373162363833303130643534343461646563343564386565 +33363437376237633739623863353232343438306639303561646139396137646234663534636237 +30663332306162366233636666316336313538623730333162376264383463666661613436656265 +37643738313335353030383663383461663036376637346334643531636438656133393731383138 +63653338306639653266366337653865363432366364306262303232616536393738323334346334 +33646331316330633738386236323533353734623234653335643633643866393761653232303162 +31653530643934373435326539366663313033616338666633313131353334323931383635346235 +32333166636135323438353735616265373132393762323037326635633162653363393639633939 +37613231343766653437626235313666343837343865303863643035633863373235656439346538 +32613934366138653331343931386131663134623063366435623835653535623334376333366562 +65366365386239663338656233353435343639353037663732323064626261636363643261656164 +66393538343638373064376536326537623735343064643736636466323636316130373565643635 +31383531306431363533663935356339373934396361306138633266653431326132386563366565 +34646465356139636563653732373932636461313935376235366266636136663238663030373662 +31336635653666326538333931646235316262303838633138613464303837386162613263386438 +34366230353439323531646637326634616336343963373831356163373462343664393538353835 +66616235616363333430313539333637626665386562653834343139663133383463393236633662 +30303937376661323535333132653966383231353033633334356663646265613934336636363138 +65643265373334653932316262303136363763396134303730383536646538663134303964323432 +39303833386361363364303231656364356365653939373661633661313739356665323834306635 +32653933626166396462666235353238383266336361616531316433363433336238656539373661 +62306362666333653865396364663235626230303133343764613536616237313634613734393631 +32373761626161363935346437396161383365633138393164663539626439353832613437653261 +35376464313236666236313965376133323333663030383965333935383237633461646266633363 +35656561343033306162616361653062363538356136353837343866636632623765646366396638 +35313134383361346332323232643030303434363732653236366538376166333237323566383930 +62356162656538636464616432626637633531363237376337353562393731633635323536386363 +31623936663935366164373062333465383137633661393062386135376635346262336538346165 +34663561663134306635373737383430343332633365356238346264376136363862613762313166 +39323635396434386537646435366630353462313463366666626135623633386336376466353830 +64373763306464346336643531616233633237663534333536666264633564623030343533373430 +38623738623264396564316666663763356136623865623662393766343566376465633839353466 +66313333666131626639656464666130653239313864656330666666653237306131633139336565 +33333536653638386431373432663132643033313566376261376535363563356135353735346464 +66623032303639313163303739346637333839323939356364376133346363343163343661646661 +65643462356234353562346435623463633665343037313032363362643461356566623731363030 +66353530353237666132613435306537613038653062336663373366343834323238656162656538 +31383037613535303564633732346332613939333037343334646530386331643336363834313365 +66613535353631643566363062643930323966343636353666626237663733363062653564633562 +39313034643238366331636332393537376130386463653831393366636634623833366436303961 +34633162333462383834346637343337616166353035616362636462346364366539383333373964 +62343635323331376237373761383535646233366465303364663731393061326436663137613238 +35363338613339326336613535326635363236356264326330386662393666613264646465316339 +36633263626632613862613439363630353462626636373265386332316162356439323134636433 +34393334316561366231613339386339653663316661356662306230356537626431376133333736 +31663034373033666663363634386134376237663061323732653365363662323335653433656665 +30323566326530653365613937376264383435636438333734386131363737633163343734336564 +32633432613033653263356334666436353036373738346430373133346239313566346236376138 +64323565663961356331323937373032306330646664663761646131646235383731303564633366 +32656537343836326465343264363531396631613161633236366363366537613439376464653866 +61316164363032313630383063336436303661366438623666373538396432303331623139393833 +33653061363766313465633964353439383136343832323630666630323865326461666137313132 +62333963323564396139333130303539623935303733616138376466303461643439373934393432 +38356535663333343232306135623261336534383233333632386638623232383737616239326666 +38643139623730643439373939616562393162376564346130643135653334616338333739313935 +33343563346664346531623161313937636562653132613831303132363665343333633232373633 +30363034373362626266633562633634643635343161613262373463616437396566343733626561 +30626462313261383461653532396263663139323134653764363963393665653165326130643031 +36303962313433623034633930633762393263383830663261653631333830643637313332613136 +66636364373137306539643566633830393030393932336632646565383638343639623232316165 +63333637616237313262646539363835346138613234376164333238643139653934343365386632 +37633562633863373033666564666665396261386537653866353533336233316339656365356563 +33663561643531623837656237313938303363363662383830363435323661306164383932613438 +63623963336361356639303162373935613734666466663933646239363939616239323164303364 +62393765343539646633616630313463633963396432636637313162666432386637616233343532 +39343366323236336266396438326565343561313330313539366439343262396361386662323434 +30313433323063316531613338303239333539316133623961316432616632613066636136336436 +35613864363731373333313637363036303561343263316466303935313664646635396331323039 +31333134316535356134666365306263303337623636353430333731343037656661363333643165 +30383734336662336632356537376232623664653436396464633037643839343238623330613136 +31663137366437396330333231303636633461616230383339646261303964393539393637643730 +30626463313434646566313939656432313066356232303435313734353930336265343431346362 +36346666643230303565613563313634393338323735373965336138646432363534383066383236 +30383230666335393861653937316233633534316666643865643439313938633230 diff --git a/scripts/registry-login.sh b/scripts/registry-login.sh new file mode 100755 index 0000000..5df53c6 --- /dev/null +++ b/scripts/registry-login.sh @@ -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