chore(skills): mint gitea-token-out-of-remote-url + record the store-format law
git 2.56 credential-store parses one URL per line (port included), not the key=value block shape the man page shows for ~/.git-credentials; a block-format file yields a silent empty get and git dies at askpass.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: gitea-token-out-of-remote-url
|
||||
description: "Move a Gitea/HTTP git token out of remote.origin.url into a credential store file, and verify auth works with prompts disabled."
|
||||
---
|
||||
|
||||
# Move a git token out of the remote URL
|
||||
|
||||
A remote URL like `http://user:<token>@host:port/org/repo.git` puts the credential in
|
||||
`.git/config` (copied by every clone), prints it in `git remote -v`, and git-lfs echoes the
|
||||
whole URL in its `Locking support detected on remote` warning on every push.
|
||||
|
||||
## 1. Capture the token from the existing remote (never paste it into a message)
|
||||
```bash
|
||||
url=$(git remote get-url origin)
|
||||
user=$(printf '%s' "$url" | sed -E 's#^http://([^:]+):[^@]+@.*$#\1#')
|
||||
tok=$(printf '%s' "$url" | sed -E 's#^http://[^:]+:([^@]+)@.*$#\1#')
|
||||
```
|
||||
|
||||
## 2. Write the credential file (URL form, port included)
|
||||
```bash
|
||||
umask 077
|
||||
printf 'http://%s:%s@HOST:PORT\n' "$user" "$tok" > ~/.config/secrets/gitea
|
||||
```
|
||||
Git 2.56 `credential-store` does NOT parse the `protocol=`/`host=`/`password=` block shape
|
||||
that `git credential fill` accepts on stdin: a block-format file gives a SILENT empty get,
|
||||
then git falls through to askpass (`could not read Username`). One URL per line, port included.
|
||||
|
||||
## 3. Point git at it, strip the URL, silence the LFS echo
|
||||
```bash
|
||||
git config --global credential.helper 'store --file ~/.config/secrets/gitea'
|
||||
git remote set-url origin http://HOST:PORT/org/repo.git
|
||||
git config lfs.http://HOST:PORT/org/repo.git/info/lfs.locksverify true
|
||||
```
|
||||
|
||||
## 4. Verify with prompts disabled (a hang is a failed credential)
|
||||
```bash
|
||||
printf 'protocol=http\nhost=HOST:PORT\n\n' | git credential-store --file ~/.config/secrets/gitea get
|
||||
GIT_TERMINAL_PROMPT=0 git ls-remote --heads origin main # read auth
|
||||
GIT_TERMINAL_PROMPT=0 git push --dry-run origin main # write auth
|
||||
git remote get-url origin # must contain no '@'
|
||||
grep -l "$tok" ~/.gitconfig */.git/config ~/.zshrc # must find nothing
|
||||
```
|
||||
A successful push over the bare URL is the end-to-end proof: the credential came from the file.
|
||||
|
||||
## 5. Sweep the leak
|
||||
Same shape on every clone on the host — loop over `find ~ -maxdepth 4 -path '*/.git/config'`,
|
||||
read `remote.origin.url`, scrub any URL containing `@`. One credential file serves them all
|
||||
via the global helper.
|
||||
|
||||
## Rotate
|
||||
Rewrite only the credential file, then delete the old token in the Gitea UI
|
||||
(Settings → Applications). No remote URL, rc file, or repository changes.
|
||||
Reference in New Issue
Block a user