--- name: gitea-credential-store-url-format description: "Auth to the Dankclaw Gitea API without the empty-header trap: ~/.config/secrets/gitea is a git-credential-store URL file, so awk '/^password=/' returns empty; resolve the token via git credential fill, and Gitea writes need Authorization: token (reads pass anonymously on a public repo)." --- # Gitea auth on Dankclaw: the URL-format credential store `~/.config/secrets/gitea` is `git config credential.helper = store --file ~/.config/secrets/gitea`, i.e. a **git-credential-store URL file**: ``` http://dank:<40hex-token>@192.168.0.143:3000 ``` It does NOT contain `username=`/`password=` lines. So: ```bash # WRONG — silently returns empty string p=$(awk -F= '/^password=/{print substr($0,10)}' ~/.config/secrets/gitea) ``` An empty `$p` makes every curl send `Authorization: token ` (blank) → Gitea replies `{"message":"token is required"}` on **writes**, while **reads still return 200** (the repo is public-readable, so a green `GET /labels` or `/issues` proves nothing about auth). Symptom: PR-create returns `token is required` even though a `GET` just "worked". ## Resolve the real token via git ```bash p=$(printf 'protocol=http\nhost=192.168.0.143:3000\n\n' \ | git credential fill 2>/dev/null \ | awk -F= '/^password=/{print substr($0,10)}') # 40-hex token ``` ## Write auth = token scheme, via a 600-perm -K file ```bash cfg=$(mktemp); chmod 600 "$cfg" printf 'header = "Authorization: token %s"\n' "$p" > "$cfg" curl -s -K "$cfg" http://192.168.0.143:3000/api/v1/user # confirms identity curl -s -K "$cfg" -X POST -H 'Content-Type: application/json' --data @body.json "$API/pulls" ``` - Never pass the token with `-H` — it lands in `/proc//cmdline`, world-readable. - Confirm identity with `GET /user` before trusting a write path; a `token is required` there means the token never authenticated. - Merges are a separate shape (form-encoded `do=merge`, auth-only cfg, NO `Content-Type` header) — see the gitea-merge-form-encoded skill.