`[[page|Label]]` is Obsidian syntax, not OKF. `kb-lint` resolves it Obsidian-style — by filename, anywhere in the bundle — so it has never tripped the link gate, while every other consumer of the bundle (an OKF renderer, a Gitea wiki export, `grep` for reachability) sees bracketed text where a link should be. That is how two generated pages ended up with no inbound link at all and nobody noticed: the my-first link census of the bundle reported them as orphans because their only inbound edges were wikilinks. Mechanical conversion, 52 links across 17 pages, each resolved against the same page set `kb-lint` uses: an explicit `|Label` is kept verbatim, an unlabelled link takes the target's frontmatter `title`. Targets are emitted bundle-absolute (`/tools/niri/tips.md`), the form the spec recommends and the form 99 existing links in this bundle already use. Two links were `[[index]]`, which resolves by filename to 21 pages — the ambiguity that filename-resolution invites. Both meant their own directory's index, so both are now written out in full: `/tools/gitea/index.md`, `/tools/niri/index.md`. The linter still tolerates wikilinks; whether it should reject them outright is an open question on #64, because that would replace the two tests pinning today's tolerance. Refs #64
99 lines
3.6 KiB
Markdown
99 lines
3.6 KiB
Markdown
---
|
|
type: reference
|
|
title: Gitea Client Access
|
|
description: Token-based HTTP access from client workstations — the credential store layout, the git 2.56 store-format trap, and the verification loop.
|
|
tags:
|
|
- gitea
|
|
- git
|
|
- secrets
|
|
verified: 2026-10-09
|
|
---
|
|
|
|
# Gitea Client Access
|
|
|
|
Clients (workstations, agent hosts) reach Gitea over plain HTTP on the LAN:
|
|
`http://192.168.0.143:3000/dank/<repo>.git`. Authentication is a Gitea HTTP token sent as
|
|
the password for user `dank`. SSH is available on `:2222` (see
|
|
[architecture](/tools/gitea/architecture.md)); HTTP + token is what the agent hosts use.
|
|
|
|
## The law: the token never enters a URL, a config file, or a shell rc
|
|
|
|
A remote URL of the shape `http://dank:<token>@host/org.git` stores the credential in
|
|
`.git/config`, which is copied by every clone, printed by `git remote -v`, and echoed by
|
|
the LFS lock warning during `git push`. Keep the URL bare:
|
|
|
|
```
|
|
http://192.168.0.143:3000/dank/command-center.git
|
|
```
|
|
|
|
The credential lives in one file, mode 0600, outside every repository:
|
|
|
|
| Item | Value |
|
|
|---|---|
|
|
| Credential file | `~/.config/secrets/gitea` (0600, dir 0700) |
|
|
| Helper (global) | `git config --global credential.helper 'store --file ~/.config/secrets/gitea'` |
|
|
| Scope | every repo on the host that talks to `192.168.0.143:3000` |
|
|
|
|
## The git 2.56 store-format trap
|
|
|
|
`git credential fill` **reads** `protocol=`/`host=`/`username=`/`password=` blocks on
|
|
stdin, and the man page shows the same shape for `~/.git-credentials`. `git
|
|
credential-store` (git 2.56.0, verified) does **not** parse that shape in the file: a
|
|
key=value block yields a silent empty `get`, so git falls through to askpass and dies with
|
|
`could not read Username`. Write the file as one URL per line:
|
|
|
|
```
|
|
http://dank:<token>@192.168.0.143:3000
|
|
```
|
|
|
|
The host line must carry the port (`192.168.0.143:3000`) — git keys the lookup on
|
|
`protocol` + `host:port`.
|
|
|
|
Verify the file answers before trusting it, with prompts disabled so a failure is loud
|
|
rather than a hang:
|
|
|
|
```
|
|
printf 'protocol=http\nhost=192.168.0.143:3000\n\n' | git credential-store --file ~/.config/secrets/gitea get
|
|
```
|
|
|
|
Two lines come back (`username=`, `password=`). Silence means the format is wrong.
|
|
|
|
## Verification loop
|
|
|
|
Run every step with `GIT_TERMINAL_PROMPT=0`; anything that needs the token from a file the
|
|
helper cannot read fails immediately instead of blocking on a prompt.
|
|
|
|
```
|
|
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 # no '@' present
|
|
grep -rl '<token>' ~/.gitconfig */.git/config # no plaintext copies
|
|
```
|
|
|
|
## LFS lock warning
|
|
|
|
`git push` on a repo with git-lfs prints `Locking support detected on remote … info/lfs.locksverify true`
|
|
and echoes the remote URL — one more place a URL-embedded token leaks. Silence it per
|
|
repo with the bare URL:
|
|
|
|
```
|
|
git config lfs.http://192.168.0.143:3000/dank/<repo>.git/info/lfs.locksverify true
|
|
```
|
|
|
|
## Rotating the token
|
|
|
|
Rotate in the Gitea UI (Settings → Applications), then rewrite only the credential file:
|
|
|
|
```
|
|
umask 077 && printf 'http://dank:%s@192.168.0.143:3000\n' '<new-token>' > ~/.config/secrets/gitea
|
|
```
|
|
|
|
Nothing else changes: no remote URL, no rc file, no repository. The old token remains valid
|
|
until it is deleted in the UI, so delete it there as part of the rotation.
|
|
|
|
## See Also
|
|
|
|
- [Gitea directory index](/tools/gitea/index.md) — Gitea on dankclaw
|
|
- [management](/tools/gitea/management.md) — server-side operations
|
|
- [architecture](/tools/gitea/architecture.md) — ports (3000 HTTP, 2222 SSH) and the Caddy front
|