Commit fb4cbe
2026-03-19 05:14:36 Claude (MCP): [mcp] Add git HTTP access design document| /dev/null .. Design/Git_HTTP_Access.md | |
| @@ 0,0 1,103 @@ | |
| + | --- |
| + | category: design |
| + | tags: [infrastructure, security, git, auth] |
| + | last_updated: 2026-03-19 |
| + | confidence: medium |
| + | --- |
| + | |
| + | # Git HTTP Access |
| + | |
| + | Design for exposing git clone/pull access to wiki repos, authenticated via the existing MCP bearer token. |
| + | |
| + | ## Current State |
| + | |
| + | ### What exists in otterwiki (upstream) |
| + | |
| + | Otterwiki has native git smart HTTP endpoints (`/.git/info/refs`, `/.git/git-upload-pack`, `/.git/git-receive-pack`) in `otterwiki/remote.py`. These are: |
| + | - Gated by `GIT_WEB_SERVER` config (default: `False`) |
| + | - Authenticated via HTTP Basic Auth against otterwiki's own `user` table |
| + | |
| + | ### What exists in robot.wtf |
| + | |
| + | - `GIT_WEB_SERVER` is not seeded in `_init_wiki_db()` — defaults to off for all wikis |
| + | - There's an unfinished `GitHttpBackend` class in `app/git_http.py` — read-only, no auth, **not mounted in production** |
| + | - Per-wiki MCP bearer tokens already exist (`mcp_token_hash` in `wikis` table, displayed in management UI) |
| + | |
| + | ### The auth gap |
| + | |
| + | Otterwiki's native git auth checks credentials against its own `user` table via HTTP Basic Auth. But robot.wtf users authenticate via ATProto OAuth — they have no passwords in otterwiki's user table. If `GIT_WEB_SERVER` were enabled, git auth would either fail for everyone (no usable credentials) or, if someone populated the user table directly, bypass the platform's collaborator ACL. |
| + | |
| + | The system is currently secure by coincidence (feature off + no passwords), not by design. |
| + | |
| + | ## Proposed Design |
| + | |
| + | ### Reuse MCP bearer tokens for git auth |
| + | |
| + | The simplest approach: git HTTP Basic Auth accepts the wiki's MCP token as the password. Same token, two protocols. |
| + | |
| + | ``` |
| + | git clone https://testuser:mcp_TOKEN@slug.robot.wtf/.git/ |
| + | ``` |
| + | |
| + | Or equivalently, git prompts for credentials and the user pastes the MCP token as the password (username is ignored). |
| + | |
| + | ### Why this works |
| + | |
| + | - Tokens already exist and are already displayed in the management UI |
| + | - Token verification infrastructure exists (`WikiModel` stores and checks `mcp_token_hash`) |
| + | - No new auth system needed |
| + | - Users who have the MCP token already have full wiki access — git read access is not an escalation |
| + | |
| + | ### Implementation |
| + | |
| + | 1. **New git HTTP handler** (not otterwiki's native one): Build on the existing `GitHttpBackend` in `app/git_http.py`. Add: |
| + | - HTTP Basic Auth that extracts the password and verifies against `mcp_token_hash` |
| + | - Read-only (git-upload-pack only, git-receive-pack returns 403) |
| + | - Mount at `/.git/` on wiki subdomains |
| + | |
| + | 2. **Block otterwiki's native git endpoints**: Ensure `GIT_WEB_SERVER` stays off. Consider explicitly seeding it as `False` in `_init_wiki_db()` and/or having the resolver intercept `/.git/` routes before they reach otterwiki. |
| + | |
| + | 3. **No changes to otterwiki upstream**: All git HTTP handling lives in robot.wtf's middleware layer. |
| + | |
| + | ### Read-only for v1 |
| + | |
| + | Git push (receive-pack) is blocked. Reasons: |
| + | - Push requires merge conflict handling, branch protection, and hook infrastructure |
| + | - The wiki engine expects to be the sole writer to the git repo |
| + | - MCP write access goes through the API (which validates content, updates caches, etc.) |
| + | |
| + | ### Access control |
| + | |
| + | - Only wikis with an MCP token can be cloned (token must exist and match) |
| + | - The token grants the same access level as MCP: read + write via API, read-only via git |
| + | - Revoking/regenerating the MCP token immediately revokes git access too |
| + | |
| + | ## Use Cases |
| + | |
| + | 1. **Template updates**: `git remote add template https://github.com/schuyler/robot-wtf-template.git && git fetch template && git rebase template/main` — this doesn't require platform git access (GitHub is the remote). But pushing the rebased result back requires either git push access or the API. |
| + | |
| + | 2. **Local editing**: Clone wiki, edit in a local editor, push back. Blocked by read-only constraint in v1. Could be enabled later with receive-pack + token auth. |
| + | |
| + | 3. **Backup**: Clone the wiki repo for offline backup. |
| + | |
| + | ## Relationship to Template Repo |
| + | |
| + | The template repo update flow (`git fetch template && git rebase template/main`) fetches from GitHub (public, no auth needed). The rebase happens locally. Pushing the result back to the wiki requires write access, which v1 doesn't provide via git. |
| + | |
| + | Options for applying template updates in v1: |
| + | - Management UI "Update from template" button (platform does the fetch + rebase server-side) |
| + | - MCP tool that triggers the same operation |
| + | - Future: git push with token auth |
| + | |
| + | ## Risks |
| + | |
| + | - **Token exposure in git config**: Users may store the token in `~/.netrc` or git credential helpers. This is standard for token-based git auth (same as GitHub PATs). Document that tokens should be treated as secrets. |
| + | - **Blocking otterwiki's native git endpoints**: Must be airtight. If a code path re-enables `GIT_WEB_SERVER`, the native endpoints (with their own auth) become reachable. Defense in depth: seed `GIT_WEB_SERVER=False` in `_init_wiki_db()` AND intercept `/.git/` in the resolver. |
| + | |
| + | ## Implementation Phases |
| + | |
| + | 1. Seed `GIT_WEB_SERVER=False` explicitly in `_init_wiki_db()` (defensive) |
| + | 2. Add token auth to `GitHttpBackend` |
| + | 3. Mount at `/.git/` on wiki subdomains, read-only |
| + | 4. Management UI: show git clone URL alongside MCP token |
| + | 5. (Future) Write access via receive-pack |
