feat: workspace skeleton + phase 0 research docs
- Cargo workspace with 5 sub-crates: alkgit-core (storage), alkgit-transport (smart protocol), alkgit-http, alkgit-ssh, alkgitd (binary); sha1 pinned through the gix stack, sha256 passthrough feature - docs/research/: vision, gitoxide alignment, alk stack fit, server-side protocol inventory, license/reference policy, POC plan - AGENTS.md: conventions mirroring alkcall (no comments, thiserror, tokio, no secrets on wire/at rest, visible-surface=authorized-surface, gitoxide-only serving path, bounded resources, registry-resolved repos) Verified: cargo build, clippy -D warnings, fmt, test, check --all-features
This commit is contained in:
1 parent
a633dddd6b
commit
a3cdef909b
20 files changed
+965
No files matched your search
@@ -0,0 +1,101 @@
|
||||
# alkgit Phase 0: Vision and Guiding Principles
|
||||
|
||||
**Status**: draft v1 — 2026-09-19
|
||||
**Phase**: 0 (exploration) — this document captures WHAT we are building and
|
||||
WHY before architecture (phase 1) commits to HOW.
|
||||
|
||||
## Vision
|
||||
|
||||
A self-hosted, single-binary git server in Rust: `alkgitd` serves repositories
|
||||
over **http** and **ssh** interfaces with an authenticated-by-default surface,
|
||||
built on the alk stack (alkcall, alkhttp, alktls, alkvault) and gitoxide.
|
||||
It exists because self-hosted git platforms (gitea/gitlab) are large
|
||||
multi-component applications with a long-tail of exposed APIs, plaintext
|
||||
secret storage, and web-UI attack surface — and because CVE-2026-59774
|
||||
(gitea) demonstrated that a single logic bug in an internally-exposed API is
|
||||
enough for full compromise of the host. Our blast-radius and exposure model
|
||||
is designed from day one, not retrofitted.
|
||||
|
||||
## The problem, precisely
|
||||
|
||||
1. **Exposure model**: mainstream self-hosted git servers expose a large
|
||||
HTTP API surface regardless of auth (openapi describes everything;
|
||||
enforcement is somewhere else). alkcall inverts this: only operations the
|
||||
caller has privileges for are visible on the wire, and `Visibility::Internal`
|
||||
ops are structurally unreachable. alkgit inherits that property by using
|
||||
alkcall as the transport/protocol substrate.
|
||||
2. **Secret hygiene**: gitea stores secrets plaintext in its DB. alkgit uses
|
||||
alkvault for anything credential-shaped; the metadata store holds vault
|
||||
references, never plaintext secrets.
|
||||
3. **Footprint**: a git server is a small program (storage + smart protocol +
|
||||
two front doors). The platform features (issues, PRs, wikis, CI) are where
|
||||
the CVEs live. alkgit v1 is deliberately just the git server; everything
|
||||
else stays out.
|
||||
4. **Language**: the whole serving path is Rust (memory-safe, no C deps in
|
||||
the packet path).
|
||||
|
||||
## Guiding principles (architecture must honor)
|
||||
|
||||
1. **Authenticated by default** — no unauthenticated endpoint exists unless a
|
||||
repo is explicitly marked public; even then, advertisement is the only
|
||||
anonymous surface, and push is always authenticated.
|
||||
2. **Visible-surface = authorized-surface** — the alkcall model end to end;
|
||||
no endpoint exists on the wire that a caller cannot see themselves
|
||||
authorized for; internal/admin ops are never wire-reachable.
|
||||
3. **No plaintext secrets at rest** — alkvault or nothing.
|
||||
4. **Thin interfaces, one core** — http and ssh are adapters that authenticate,
|
||||
resolve a repo, and hand a duplex stream to the transport layer. Policy
|
||||
lives in exactly one place.
|
||||
5. **Honest capability advertisement** — the git protocol advertises only
|
||||
what we actually serve (this is both protocol correctness and the
|
||||
security pattern: promise/enforce in the same place).
|
||||
6. **gitoxide for storage/wire primitives** — never shell out to the `git`
|
||||
binary (no GPL dependency, no process injection surface); own the smart
|
||||
protocol server layer ourselves on gitoxide primitives.
|
||||
7. **Bounded resources** — every protocol session carries wall-clock, size,
|
||||
and round limits; git servers are internet-facing by definition.
|
||||
|
||||
## Non-goals for v1
|
||||
|
||||
- Web UI of any kind.
|
||||
- Issues/PR/review features.
|
||||
- Git LFS (later phase, separate decision).
|
||||
- federation/replication between alkgit instances (later phase).
|
||||
- Serving as a general sshd (only the git command surface).
|
||||
- Windows as a serving platform (linux first; keep code portable-ish but
|
||||
don't test it).
|
||||
|
||||
## Sub-crate shape (provisional, matches workspace skeleton)
|
||||
|
||||
| crate | role |
|
||||
|---|---|
|
||||
| `alkgit-core` | storage: repos, refs, odb, pack read/write, access-rule types |
|
||||
| `alkgit-transport` | smart protocol: pkt-line sessions, advertise, ls-refs, fetch, receive-pack |
|
||||
| `alkgit-http` | http front door (smart-http endpoints + admin API via alkhttp) |
|
||||
| `alkgit-ssh` | ssh front door (git commands over alkcall channels) |
|
||||
| `alkgitd` | binary: config, assembly, TLS/ACME, serving loops |
|
||||
|
||||
## What phase 0 must still produce before phase 1
|
||||
|
||||
- [x] gitoxide capability + version research (`gitoxide.md`)
|
||||
- [x] alk stack fit + integration surface (`alk-stack.md`)
|
||||
- [x] server-side protocol inventory (`git-protocol.md`)
|
||||
- [x] license/reference policy (`reference-policy.md`)
|
||||
- [ ] POC-1: real `git clone` over alkcall BiStream using gix-packetline
|
||||
(validates BiStream fit + packetline async codec end-to-end)
|
||||
- [ ] POC-2: server-side pack generation composition (bundle-write vs
|
||||
entries-to-bytes) for a small want/have set
|
||||
- [ ] POC-3: http smart-endpoint streaming shape through alkhttp
|
||||
(chunked pack response, unbuffered receive-pack POST ingestion)
|
||||
- [ ] Convergence: recommended approach summary feeding phase 1 architecture
|
||||
|
||||
## Immediate threat-model notes carried into architecture
|
||||
|
||||
- The admin API (repo/user/permission management) is alkcall
|
||||
`Visibility::Internal` ops over an admin-only listener; it is never part
|
||||
of the git traffic surface.
|
||||
- Repo names arriving on the wire are registry IDs, never paths; storage
|
||||
roots are configured server-side only.
|
||||
- The advertisement phase runs ACL before the first ref line is emitted.
|
||||
- receive-pack applies ref updates via CAS transactions; hooks/plugins do
|
||||
not exist in v1 (no arbitrary code execution surface at all).
|
||||
Reference in new issue
Block a user