diff --git a/README.md b/README.md index 09314bc..944b9c2 100644 --- a/README.md +++ b/README.md @@ -115,8 +115,7 @@ These are not part of any NIP but are used by this application: - When found, server: - Creates a bare git repository at `/repos/{npub}/{repo-name}.git` - Fetches the self-transfer event for ownership verification - - Creates initial commit with `.nostr-ownership-transfer` file containing the self-transfer event - - Creates `.nostr-announcement` file with the full signed announcement event JSON + - Creates initial commit with README.md and saves announcement/transfer events to `nostr/repo-events.jsonl` for offline papertrail - If repository has `clone` tags pointing to other remotes, syncs from those remotes 3. **Repository Access**: @@ -155,12 +154,18 @@ These are not part of any NIP but are used by this application: 1. **Current Owner Initiates Transfer**: - Owner creates a kind 1641 event with: - - `from` tag: Current owner pubkey - - `to` tag: New owner pubkey - `a` tag: Repository identifier (`30617:{owner}:{repo}`) - - Signs and publishes event + - `p` tag: New owner pubkey + - `d` tag: Repository name + - Signs and publishes event to Nostr relays + - Transfer event is saved to repository in `nostr/repo-events.jsonl` for offline papertrail -2. **Server Processes Transfer**: +2. **New Owner Completes Transfer**: + - New owner is notified when logging into GitRepublic web + - New owner publishes a new repository announcement (kind 30617) to complete the transfer + - New announcement is saved to repository for verification + +3. **Server Processes Transfer**: - Server fetches all ownership transfer events for repository - Validates chain of ownership chronologically - Updates current owner for all permission checks @@ -327,7 +332,7 @@ npm run dev **Note**: This repository uses npm workspaces. The CLI (`gitrepublic-cli`) is included as a workspace package but can also be published independently. See `gitrepublic-cli/SYNC.md` for details on syncing to a separate repository. -### Security Features +## Security Features ### Lightweight Mode (Single Container) - **Resource Limits**: Per-user repository count and disk quota limits @@ -507,7 +512,7 @@ git clone https://{domain}/repos/{npub}/{repo-name}.git git clone https://{domain}/{npub}/{repo-name}.git ``` -**Note**: Use `/api/git/` or `/repos/` paths to ensure proper detection by the commit signing hook and to distinguish from GRASP servers. +**Note**: Use `/api/git/` or `/repos/` paths to ensure proper detection by the commit signing hook and to distinguish from GRASP servers. All three paths work for cloning, but `/api/git/` is recommended for best compatibility. ### Pushing to a Repository @@ -549,11 +554,9 @@ The credential helper will automatically generate NIP-98 authentication tokens f - **Resource Quotas**: Per-tenant CPU, memory, and storage limits - **Separate Volumes**: Each tenant has their own PersistentVolume -See `docs/SECURITY.md` and `docs/SECURITY_IMPLEMENTATION.md` for detailed information. - -## Security Considerations +### Security Considerations -- **Path Traversal**: All file paths are validated and sanitized +- **Path Traversal Protection**: All file paths are validated and sanitized - **Input Validation**: Commit messages, author info, and file paths are validated - **Size Limits**: 2 GB per repository, 500 MB per file - **Authentication**: All write operations require NIP-98 authentication @@ -563,6 +566,8 @@ See `docs/SECURITY.md` and `docs/SECURITY_IMPLEMENTATION.md` for detailed inform - **Rate Limiting**: Per-IP and per-user rate limiting (configurable) - **Audit Logging**: All security-relevant events are logged +See `docs/SECURITY.md` and `docs/SECURITY_IMPLEMENTATION.md` for detailed information. + ## License [Add your license here] diff --git a/docs/34.md b/docs/34.md index a9c4dd5..54a11b4 100644 --- a/docs/34.md +++ b/docs/34.md @@ -258,7 +258,7 @@ GitRepublic uses repository announcements to: - **Repository Creation**: Users create repository announcements via the signup page - **Repository Updates**: Repository information updates are done via the signup page, which updates the repository announcement event - **Fork Detection**: Forks are identified by `a` tags pointing to the original repository -- **Offline Papertrail**: Repository announcements are saved to the repository itself (as `.nostr-announcement`) for offline verification +- **Offline Papertrail**: Repository announcements are saved to `nostr/repo-events.jsonl` in the repository for offline verification ### Pull Requests (Kind 1618) @@ -288,38 +288,22 @@ GitRepublic uses repository announcements to: GitRepublic implements ownership transfers using kind 1641 events: -- **Transfer Initiation**: Current owner creates a kind 1641 event with the new owner's pubkey in the `p` tag +- **Transfer Initiation**: Current owner creates a kind 1641 event with: + - `a` tag: Repository identifier (`30617:{owner}:{repo}`) + - `p` tag: New owner pubkey + - `d` tag: Repository name - **Event Publishing**: Transfer events are published to Nostr relays for online papertrail -- **Repository Storage**: Transfer events are saved to the repository (as `.nostr-ownership-transfer-{eventId}.json`) for offline papertrail +- **Repository Storage**: Transfer events are saved to `nostr/repo-events.jsonl` in the repository for offline papertrail - **New Owner Notification**: New owners are notified when they log into GitRepublic web - **Transfer Completion**: New owner completes the transfer by publishing a new repository announcement (kind 30617) -- **Verification**: The transfer is complete when the new owner's announcement is published and saved to the repository +- **Verification**: The new announcement is saved to `nostr/repo-events.jsonl`, and the transfer is complete **Transfer Workflow**: 1. Current owner initiates transfer by creating and publishing a kind 1641 event -2. Transfer event is saved to the repository for offline verification +2. Transfer event is saved to `nostr/repo-events.jsonl` for offline verification 3. New owner is notified via GitRepublic web interface 4. New owner publishes a new repository announcement (kind 30617) to complete the transfer -5. New announcement is saved to the repository for offline verification -6. Transfer is complete and repository ownership is verified - -### Ownership Transfers (Kind 1641) - -GitRepublic implements ownership transfers using kind 1641 events: - -- **Transfer Initiation**: Current owner creates a kind 1641 event with the new owner's pubkey in the `p` tag -- **Event Publishing**: Transfer events are published to Nostr relays for online papertrail -- **Repository Storage**: Transfer events are saved to the repository (as `.nostr-ownership-transfer-{eventId}.json`) for offline papertrail -- **New Owner Notification**: New owners are notified when they log into GitRepublic web -- **Transfer Completion**: New owner completes the transfer by publishing a new repository announcement (kind 30617) -- **Verification**: The transfer is complete when the new owner's announcement is published and saved to the repository - -**Transfer Workflow**: -1. Current owner initiates transfer by creating and publishing a kind 1641 event -2. Transfer event is saved to the repository for offline verification -3. New owner is notified via GitRepublic web interface -4. New owner publishes a new repository announcement (kind 30617) to complete the transfer -5. New announcement is saved to the repository for offline verification +5. New announcement is saved to `nostr/repo-events.jsonl` for offline verification 6. Transfer is complete and repository ownership is verified **Implementation**: @@ -327,5 +311,4 @@ GitRepublic implements ownership transfers using kind 1641 events: - Pull requests: `src/lib/services/nostr/prs-service.ts` - Issues: `src/lib/services/nostr/issues-service.ts` - Status events: Used throughout PR and issue management -- Ownership transfers: `src/routes/api/repos/[npub]/[repo]/transfer/+server.ts`, `src/lib/services/nostr/ownership-transfer-service.ts` - Ownership transfers: `src/routes/api/repos/[npub]/[repo]/transfer/+server.ts`, `src/lib/services/nostr/ownership-transfer-service.ts` \ No newline at end of file diff --git a/docs/tutorial.md b/docs/tutorial.md index 46cc367..e5a713c 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -94,18 +94,22 @@ Your repository will be accessible at: https://{domain}/repos/{your-npub}/{repository-name} ``` -For git operations: +For git operations, you can use any of these paths: ``` +https://{domain}/api/git/{your-npub}/{repository-name}.git # Recommended +https://{domain}/repos/{your-npub}/{repository-name}.git https://{domain}/{your-npub}/{repository-name}.git ``` +**Note**: The `/api/git/` path is recommended for best compatibility with commit signing hooks. + ### Initial Setup After creating your repository, you can: 1. **Clone it locally**: ```bash - git clone https://{domain}/{your-npub}/{repository-name}.git + git clone https://{domain}/api/git/{your-npub}/{repository-name}.git cd {repository-name} ``` @@ -126,7 +130,7 @@ After creating your repository, you can: Anyone can clone public repositories without authentication: ```bash -git clone https://{domain}/{owner-npub}/{repository-name}.git +git clone https://{domain}/api/git/{owner-npub}/{repository-name}.git cd {repository-name} ``` @@ -136,26 +140,39 @@ Private repositories require authentication. You'll need to set up NIP-98 authen #### Setting Up NIP-98 Authentication -1. **Install a git credential helper** (if not already installed): +For command-line git operations, you need to install the [GitRepublic CLI](https://github.com/your-org/gitrepublic-cli) which provides: + +1. **Credential Helper**: Automatically generates NIP-98 authentication tokens for git operations +2. **Commit Signing Hook**: Automatically signs commits for GitRepublic repositories + +**Quick Setup**: + +1. Install the CLI: ```bash - # For Linux/Mac - git config --global credential.helper store + npm install -g gitrepublic-cli ``` -2. **Configure git to use NIP-98**: +2. Set your Nostr private key: ```bash - git config --global credential.https://{domain}.helper '!f() { echo "username=nostr"; echo "password=$(nostr-auth-token)"; }; f' + export NOSTRGIT_SECRET_KEY="nsec1..." ``` - Note: You may need a custom credential helper that generates NIP-98 auth tokens. Check the GitRepublic documentation for your specific setup. +3. Run the setup script: + ```bash + gitrepublic-setup + ``` + +This automatically configures the credential helper and commit signing hook. See the README for complete setup instructions. 3. **Clone the private repository**: ```bash - git clone https://{domain}/{owner-npub}/{repository-name}.git + git clone https://{domain}/api/git/{owner-npub}/{repository-name}.git ``` When prompted, the credential helper will automatically generate and use a NIP-98 authentication token. +**Note**: For command-line git operations, you'll need to install the [GitRepublic CLI](https://github.com/your-org/gitrepublic-cli) and set up the credential helper. See the README for complete setup instructions. + ### Cloning from Multiple Remotes If a repository has multiple clone URLs configured, GitRepublic will automatically sync changes to all remotes when you push. You can see all clone URLs on the repository page. @@ -262,7 +279,7 @@ Pull requests (PRs) allow you to propose changes to a repository. They're create 1. **Fork and clone the repository**: ```bash - git clone https://{domain}/{owner-npub}/{repo}.git + git clone https://{domain}/api/git/{owner-npub}/{repo}.git cd {repo} ``` @@ -362,7 +379,7 @@ After forking: 1. **Clone your fork**: ```bash - git clone https://{domain}/{your-npub}/{fork-name}.git + git clone https://{domain}/api/git/{your-npub}/{fork-name}.git ``` 2. **Make changes** in your fork @@ -380,7 +397,7 @@ To keep your fork up to date with the original repository: 1. **Add the original as a remote**: ```bash - git remote add upstream https://{domain}/{original-npub}/{original-repo}.git + git remote add upstream https://{domain}/api/git/{original-npub}/{original-repo}.git ``` 2. **Fetch and merge**: @@ -450,13 +467,13 @@ Transfer repository ownership to another user using the transfer workflow: 1. **Initiate Transfer**: On your repository page, click "Transfer Ownership" 2. **Enter New Owner**: Provide the new owner's npub -3. **Sign and Publish**: The transfer event is signed and published to Nostr relays -4. **Save to Repository**: The transfer event is saved to your repository for offline papertrail +3. **Sign and Publish**: The transfer event (kind 1641) is signed and published to Nostr relays +4. **Save to Repository**: The transfer event is saved to `nostr/repo-events.jsonl` in your repository for offline papertrail 5. **New Owner Notification**: The new owner will be notified when they log into GitRepublic web -6. **Complete Transfer**: The new owner completes the transfer by publishing a new repository announcement -7. **Verification**: The transfer is complete and the repository is verified +6. **Complete Transfer**: The new owner completes the transfer by publishing a new repository announcement (kind 30617) +7. **Verification**: The new announcement is saved to the repository, and the transfer is complete -**Important**: Ownership transfers are permanent and create a chain of ownership events. The new owner will have full control. Both the transfer event and the new repository announcement are published to relays and saved to the repository for both online and offline papertrail. +**Important**: Ownership transfers are permanent and create a chain of ownership events. The new owner will have full control. Both the transfer event and the new repository announcement are published to relays and saved to `nostr/repo-events.jsonl` in the repository for both online and offline papertrail. --- @@ -603,10 +620,12 @@ GitRepublic implements NIP-34 for repository announcements. Key event types: - **Kind 30618**: Repository state - **Kind 1617**: Git patch - **Kind 1618**: Pull request +- **Kind 1619**: Pull request update - **Kind 1621**: Issue +- **Kind 1630-1633**: Status events (open, applied/merged, closed, draft) - **Kind 1641**: Ownership transfer -See the [NIP-34 specification](/docs/nip34/spec) for full details. +See the [NIP-34 documentation](/docs/nip34) for full details. ### GRASP Protocol Support diff --git a/nostr/commit-signatures.jsonl b/nostr/commit-signatures.jsonl index 49afd94..5ce72c5 100644 --- a/nostr/commit-signatures.jsonl +++ b/nostr/commit-signatures.jsonl @@ -26,3 +26,4 @@ {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771615631,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","handle new repo creation"]],"content":"Signed commit: handle new repo creation","id":"59bc1c664590bcbe3e05c4151154590aa1ca4399e2a48d64e94bb960e6056265","sig":"ae666597fc46256915abeec93be97c5d9559eaef90aa65208740f32fe4b00531a51ba432ed9a2089a7ec860ac1dc9a7a4a5d8e84db2a7ae433dd5c668f0b5035"} {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771618298,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","restrict repos to announced events"]],"content":"Signed commit: restrict repos to announced events","id":"d7ee36680a38fac493b27fba26d6e1c496dee9a3099db68a4352f7709a41e860","sig":"071cc8031940590785e5566a45159e5324e36e8a06023282ab1d50b608902d3b06d95efc03d0a4da861a88f12381f7b64999c09a49dfe5f36fbd8ec6aefd8aeb"} {"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771618514,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","bug-fixes"]],"content":"Signed commit: bug-fixes","id":"0a4b94a90de38e64e657c3ef5aca2bc61b5a563edf504d10f4cf5ab386b1bd9c","sig":"d7502da3f1f7d7b35b810a09cbcd3a467589afd8b97e0a7a04fb47996bb4959b510580a0f33f21c318c2733004f23840f73929ddc0dfb2572edc83ad967b09d2"} +{"kind":1640,"pubkey":"573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc","created_at":1771619647,"tags":[["author","Silberengel","silberengel7@protonmail.com"],["message","refactor"]],"content":"Signed commit: refactor","id":"190b84b2cff8b8db7b3509e05d5470c073fc88e50ba7ad4fa54fd9a9d8dc0045","sig":"638b9986b5e534d09752125721a04d8cef7af892c0394515d6deb4116c2fcab378313abc270f47a6605f50457d5bb83fdb8b34af0607725b6d774028dc6a4fb6"} diff --git a/src/routes/docs/nip34/+page.server.ts b/src/routes/docs/nip34/+page.server.ts index c85a5f4..f19a236 100644 --- a/src/routes/docs/nip34/+page.server.ts +++ b/src/routes/docs/nip34/+page.server.ts @@ -9,12 +9,12 @@ import logger from '$lib/services/logger.js'; export const load: PageServerLoad = async () => { try { - // Read tutorial documentation from docs/tutorial.md - const filePath = join(process.cwd(), 'docs', 'tutorial.md'); + // Read NIP-34 documentation from docs/34.md + const filePath = join(process.cwd(), 'docs', '34.md'); const content = await readFile(filePath, 'utf-8'); return { content }; } catch (error) { - logger.error({ error }, 'Error loading documentation'); - return { content: null, error: 'Failed to load documentation' }; + logger.error({ error }, 'Error loading NIP-34 documentation'); + return { content: null, error: 'Failed to load NIP-34 documentation' }; } };