mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
feat(git-sign-nostr): implement NIP-GS git object signing with Nostr keys (#459)
This commit is contained in:
Generated
+27
@@ -1361,6 +1361,19 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git-sign-nostr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
"hex",
|
||||
"libc",
|
||||
"nostr",
|
||||
"serde_json",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.13"
|
||||
@@ -5679,6 +5692,20 @@ name = "zeroize"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
|
||||
@@ -19,6 +19,7 @@ members = [
|
||||
"crates/sprout-sdk",
|
||||
"crates/sprout-persona",
|
||||
"crates/git-credential-nostr",
|
||||
"crates/git-sign-nostr",
|
||||
]
|
||||
exclude = ["desktop/src-tauri"]
|
||||
resolver = "2"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
[package]
|
||||
name = "git-sign-nostr"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
description = "NIP-GS git commit/tag signing program using Nostr secp256k1 keys"
|
||||
readme = "README.md"
|
||||
publish = false # internal workspace tool, not published to crates.io
|
||||
|
||||
[[bin]]
|
||||
name = "git-sign-nostr"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
# Base64 armor encoding/decoding for NIP-GS signature envelopes.
|
||||
# Not in workspace deps — each crate pins independently (same pattern as
|
||||
# sprout-relay, sprout-mcp, sprout-cli, git-credential-nostr).
|
||||
base64 = "0.22"
|
||||
|
||||
# Hex encoding for BIP-340 signatures and public keys.
|
||||
hex = { workspace = true }
|
||||
|
||||
# Secret key zeroization on drop.
|
||||
zeroize = { workspace = true, features = ["derive"] }
|
||||
|
||||
# Nostr key parsing (nsec/npub bech32), secp256k1 Schnorr signing, SHA-256.
|
||||
# Uses the full default feature set because we need: Keys, PublicKey,
|
||||
# FromBech32, and the re-exported bitcoin::secp256k1 + bitcoin::hashes.
|
||||
nostr = { workspace = true }
|
||||
|
||||
# JSON parsing for NIP-OA auth tag and envelope verification.
|
||||
serde_json = { workspace = true }
|
||||
|
||||
# Timestamp formatting for GnuPG VALIDSIG status lines.
|
||||
chrono = { workspace = true }
|
||||
|
||||
# Unix-specific: O_NOFOLLOW for keyfile open, fcntl for fd validation.
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
@@ -0,0 +1,46 @@
|
||||
# git-sign-nostr
|
||||
|
||||
NIP-GS signing program — signs git commits and tags with Nostr secp256k1 keys
|
||||
using BIP-340 Schnorr signatures.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Configure git to use nostr signing
|
||||
git config gpg.format x509
|
||||
git config gpg.x509.program /path/to/git-sign-nostr
|
||||
git config commit.gpgsign true
|
||||
git config tag.gpgsign true
|
||||
git config user.signingkey <hex-pubkey>
|
||||
|
||||
# Set the private key (env var)
|
||||
export NOSTR_PRIVATE_KEY=<hex-or-nsec>
|
||||
|
||||
# Optional: NIP-OA owner attestation
|
||||
export SPROUT_AUTH_TAG='["auth","<owner-pk>","<conditions>","<owner-sig>"]'
|
||||
|
||||
# Commits are now automatically signed
|
||||
git commit -m "signed with nostr"
|
||||
|
||||
# Verify
|
||||
git verify-commit HEAD
|
||||
```
|
||||
|
||||
## Key Loading Priority
|
||||
|
||||
1. `NOSTR_PRIVATE_KEY` environment variable
|
||||
2. `SPROUT_PRIVATE_KEY` environment variable
|
||||
3. Keyfile at path from `git config nostr.keyfile`
|
||||
|
||||
Keys may be hex (64 chars) or NIP-19 bech32 (`nsec1...`).
|
||||
|
||||
## How It Works
|
||||
|
||||
Git invokes this program as a signing/verification backend:
|
||||
|
||||
- **Sign:** `git-sign-nostr --status-fd=2 -bsau <keyid>` — reads payload from
|
||||
stdin, writes armored signature to stdout, status lines to fd 2 (stderr)
|
||||
- **Verify:** `git-sign-nostr --status-fd=1 --verify <sigfile> -` — reads
|
||||
payload from stdin, verifies signature from file, status lines to fd 1 (stdout)
|
||||
|
||||
See [NIP-GS](../../docs/nips/NIP-GS.md) for the full specification.
|
||||
File diff suppressed because it is too large
Load Diff
+754
-356
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user