Suture Hub
Suture Hub is a self-hosted collaboration server for Suture repositories. It provides a web UI, HTTP API, and gRPC access for push/pull, repository browsing, user management, and replication.
Starting a Hub
suture-hub --db hub.db
# Web UI at http://localhost:50051
# API at http://localhost:50051/api/v2
Flags:
--addr0.0.0.0:50051--db--replication-rolestandalonestandalone, leader, or followerOmit --db for in-memory storage (useful for testing). Use --db hub.db for persistent storage.
Authentication
When a hub has no users or tokens, all operations are open. Once the first user is created, authentication is required.
Create a User (Admin Only)
curl -X POST http://localhost:50051/auth/register \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{"username": "alice", "display_name": "Alice", "role": "member"}'
Roles: admin (full access), member (push/pull), reader (pull only).
Generate an API Token
curl -X POST http://localhost:50051/auth/token \
-H "Authorization: Bearer <admin-token>"
CLI Login
suture remote add origin http://localhost:50051
suture remote login
Ed25519 Key Authentication
Generate a keypair and register the public key with the hub. Pushes signed with the corresponding private key are verified automatically.
suture key generate
Pushing and Pulling
CLI
suture remote add origin http://localhost:50051
suture push
suture pull
suture clone http://localhost:50051/my-repo
API
Push:
curl -X POST http://localhost:50051/push \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"repo_id": "my-repo",
"patches": [...],
"branches": [...],
"blobs": [...]
}'
Pull:
curl -X POST http://localhost:50051/pull \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"repo_id": "my-repo",
"known_branches": [...]
}'
Protocol V2 (Delta Transfer)
Suture Hub supports delta-based transfer for efficient syncs when both sides share common blobs.
# Handshake to discover capabilities
curl -X POST http://localhost:50051/v2/handshake \
-H "Content-Type: application/json" \
-d '{"client_version": 2}'
Response includes server_capabilities with supports_delta and supports_compression flags.
Web UI
Open http://localhost:50051 in a browser. Features:
- Repository list -- browse all repositories
- File tree -- navigate files at any branch (
/repos/{id}/tree/{branch}) - Branch browser -- view branches and their targets
- Patch history -- paginated commit log with cursor-based pagination
- Branch protection -- prevent force-push on protected branches
- Search -- search repositories and patches by keyword
Mirrors
Mirror a remote repository locally for redundancy or faster access.
Setup a Mirror
curl -X POST http://localhost:50051/mirror/setup \
-H "Content-Type: application/json" \
-d '{
"repo_name": "local-copy",
"upstream_url": "http://upstream-hub:50051",
"upstream_repo": "upstream-repo"
}'
Sync a Mirror
curl -X POST http://localhost:50051/mirror/sync \
-H "Content-Type: application/json" \
-d '{"mirror_id": 1}'
Check Mirror Status
curl http://localhost:50051/mirror/status
CLI Mirror
suture remote mirror http://upstream/repo upstream-name
Replication
Suture Hub supports leader-follower replication for high availability.
Leader (--replication-role leader):
- Pushes replication log entries to followers every 30 seconds
- Accepts peer management requests
Follower (--replication-role follower):
- Accepts replication entries from the leader
- Read-only for replication sync endpoint
Standalone (default):
- No replication; works independently
Manage Peers (Leader Only)
# Add a follower
curl -X POST http://localhost:50051/replication/peers \
-H "Content-Type: application/json" \
-d '{"peer_url": "http://follower:50051", "role": "follower"}'
# List peers
curl http://localhost:50051/replication/peers
# Remove a peer
curl -X DELETE http://localhost:50051/replication/peers/1
# Check replication status
curl http://localhost:50051/replication/status
API Reference
Repositories
/repos/repos/repo/{id}/repos/{id}Branches
/repos/{id}/branches/repos/{id}/branches/repos/{id}/branches/{name}/repos/{id}/protect/{branch}/repos/{id}/unprotect/{branch}Content
/repos/{id}/tree/{branch}/repos/{id}/blobs/{hash}/repos/{id}/patchesSync
/push/pull/push/compressed/pull/compressed/v2/push/v2/pullAuth
/auth/token/auth/verify/auth/login/auth/registerUsers
/users/users/{username}/users/{username}/role/users/{username}Mirrors
/mirror/setup/mirror/sync/mirror/status/mirrors/{id}Replication
/replication/peers/replication/peers/replication/peers/{id}/replication/status/replication/syncOther
/search?q=/activity/handshake/v2/handshakegRPC Access
Suture Hub exposes a gRPC service alongside the HTTP API. See the crates/suture-hub/grpc/ directory for service definitions.
Rate Limits
Default limits (configurable):
Rate-limited responses include a Retry-After header.