ok 2 prompts, the second one was about the test strategy so we could reuse it. I was thinking of a tool like blossom audit. but i didnt mention it specifically.
6.6 KiB
ngit-grasp
A GRASP (Git Relays Authorized via Signed-Nostr Proofs) implementation in Rust.
Overview
ngit-grasp is a Rust-based implementation of the GRASP protocol, which enables decentralized Git repository hosting with Nostr-based authorization. This implementation combines:
- Git Smart HTTP Backend: Serves Git repositories over HTTP
- Nostr Relay: Stores and validates repository announcements and state events
- Integrated Authorization: Validates Git pushes against Nostr state events without requiring external hooks
Unlike the reference implementation (ngit-relay) which uses nginx + git-http-backend + pre-receive hooks + Khatru (Go), ngit-grasp provides a unified Rust service that handles both Git and Nostr protocols natively.
Status
ALPHA - Under active development. API and architecture subject to change.
Key Features
- Pure Rust Implementation: Single binary, no external dependencies beyond Git itself
- Integrated Authorization: Push validation happens inline during the Git receive-pack operation
- GRASP-01 Compliant: Core service requirements for Git hosting with Nostr authorization
- Extensible Architecture: Designed to support GRASP-02 (Proactive Sync) and GRASP-05 (Archive) extensions
- Developer-Friendly: Built with modern Rust async patterns using tokio and actix-web
Architecture Highlights
The key architectural decision is inline authorization rather than Git hooks:
- The
git-http-backendcrate provides low-level access to the Git protocol - We intercept the
git-receive-packoperation before spawning the Git process - Push validation happens by checking the Nostr relay for the latest state event
- Only matching pushes are forwarded to the actual Git repository
This approach provides:
- Better error messages: Direct HTTP responses vs. hook stderr
- Simpler deployment: No hook management or symlinks
- Tighter integration: Shared state between Git and Nostr components
- Easier testing: Pure Rust unit and integration tests
GRASP Compliance
GRASP-01 (Core Service Requirements)
- ✅ NIP-01 compliant Nostr relay at
/ - ✅ Accepts NIP-34 repository announcements and state events
- ✅ Git Smart HTTP service at
/<npub>/<identifier>.git - ✅ Push validation against Nostr state events
- ✅ Multi-maintainer support via recursive maintainer sets
- ✅ Support for
refs/nostr/<event-id>for PRs - ✅ CORS support for web-based Git clients
- ✅ NIP-11 relay information document
GRASP-02 (Proactive Sync) - Planned
- 🔄 Proactive event sync from listed relays
- 🔄 Proactive Git data sync from listed clone URLs
- 🔄 PR data fetching and serving
GRASP-05 (Archive) - Planned
- 🔄 Accept repositories not listing this instance
- 🔄 Backup/mirror mode operation
Technology Stack
- Rust: Core language
- actix-web: HTTP server framework
- git-http-backend: Git protocol handling
- nostr-relay-builder: Nostr relay infrastructure from rust-nostr
- nostr-sdk: Nostr event handling and validation
- tokio: Async runtime
Quick Start
# Clone the repository
git clone https://gitworkshop.dev/ngit-grasp
cd ngit-grasp
# Build
cargo build --release
# Configure
cp .env.example .env
# Edit .env with your settings
# Run
cargo run --release
Configuration
Environment variables (see .env.example):
NGIT_DOMAIN: Your domain (e.g.,gitnostr.com)NGIT_OWNER_NPUB: Relay owner's npubNGIT_RELAY_NAME: Relay name for NIP-11NGIT_RELAY_DESCRIPTION: Relay descriptionNGIT_GIT_DATA_PATH: Path to store Git repositoriesNGIT_RELAY_DATA_PATH: Path to store Nostr eventsNGIT_BIND_ADDRESS: Server bind address (default:127.0.0.1:8080)
Development
See docs/ARCHITECTURE.md for detailed architecture documentation and docs/TEST_STRATEGY.md for comprehensive testing approach.
# Run tests
cargo test
# Run compliance tests
cargo test --test compliance
# Run with logging
RUST_LOG=debug cargo run
# Check code
cargo clippy
cargo fmt --check
# Generate test coverage
cargo tarpaulin --out Html
Project Structure
ngit-grasp/
├── src/
│ ├── main.rs # Entry point, server setup
│ ├── git/
│ │ ├── mod.rs # Git module
│ │ ├── handler.rs # Git HTTP handlers
│ │ └── authorization.rs # Push validation logic
│ ├── nostr/
│ │ ├── mod.rs # Nostr module
│ │ ├── relay.rs # Relay setup and policies
│ │ └── events.rs # Event handlers
│ ├── storage/
│ │ ├── mod.rs # Storage abstraction
│ │ └── repository.rs # Repository management
│ └── config.rs # Configuration
├── docs/
│ └── ARCHITECTURE.md # Detailed architecture
├── tests/
│ ├── integration/ # Integration tests
│ └── fixtures/ # Test data
└── README.md
Comparison with ngit-relay
| Feature | ngit-relay (Go) | ngit-grasp (Rust) |
|---|---|---|
| Language | Go | Rust |
| Components | nginx + git-http-backend + hooks + Khatru | Single integrated binary |
| Authorization | Pre-receive Git hook | Inline during receive-pack |
| Deployment | Docker + supervisord | Single binary |
| Testing | Go tests + shell scripts | Rust unit + integration tests |
| Performance | Good | Excellent (zero-copy, async) |
Contributing
Contributions welcome! Please:
- Read docs/ARCHITECTURE.md
- Open an issue to discuss major changes
- Follow Rust conventions and run
cargo fmt+cargo clippy - Add tests for new functionality
License
MIT License - see LICENSE for details
Related Projects
- GRASP Protocol - Protocol specification
- ngit-relay - Reference implementation in Go
- ngit - Nostr Git plugin for git CLI
- NIP-34 - Git Stuff (Nostr protocol)
Acknowledgments
- Reference implementation by @DanConwayDev
- rust-nostr team for excellent Nostr libraries
- Git community for the Smart HTTP protocol