Use git to clone and push to a JavaScript Solid Server (JSS) pod with Nostr NIP-98 authentication.
- Node.js 18+
- JSS server running with
--gitflag (or"git": truein config) - Git installed
npm install -g git-credential-nostrgit-credential-nostr generateThis outputs:
Generated new Nostr keypair:
Private key: <64-char-hex>
Public key: <64-char-hex>
WebID: did:nostr:<pubkey>
Setup:
git config --global nostr.privkey <privkey>
Save the private key - you'll need it for pushing.
# On the server (or via sshfs mount)
mkdir -p /path/to/pod/public/myrepo
cd /path/to/pod/public/myrepo
git init
git config receive.denyCurrentBranch ignore # Required for non-bare reposgit config nostr.privkey <your-64-char-hex-privkey>Create a .acl file with your Nostr identity and public read access:
git-credential-nostr acl > .aclThen edit .acl to add public read access. The file should look like:
{
"@context": {
"acl": "http://www.w3.org/ns/auth/acl#",
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@graph": [
{
"@id": "#owner",
"@type": "acl:Authorization",
"acl:agent": { "@id": "did:nostr:<your-pubkey>" },
"acl:accessTo": { "@id": "./" },
"acl:default": { "@id": "./" },
"acl:mode": [
{ "@id": "acl:Read" },
{ "@id": "acl:Write" },
{ "@id": "acl:Control" }
]
},
{
"@id": "#public",
"@type": "acl:Authorization",
"acl:agentClass": { "@id": "foaf:Agent" },
"acl:accessTo": { "@id": "./" },
"acl:default": { "@id": "./" },
"acl:mode": [
{ "@id": "acl:Read" }
]
}
]
}Note: The ACL uses relative URLs (./) which JSS resolves correctly.
echo "# My Project" > README.md
git add -A
git commit -m "Initial commit"git clone https://example.com/yourpod/public/myrepo
cd myrepogit config nostr.privkey <your-64-char-hex-privkey>
git config credential.helper nostrecho "Update" >> README.md
git add .
git commit -m "Update README"
git pushGit automatically uses your Nostr key to authenticate via NIP-98.
┌─────────────┐ ┌──────────────────────┐ ┌─────────────┐
│ Git │────▶│ git-credential-nostr │────▶│ JSS │
│ Client │ │ │ │ Server │
└─────────────┘ └──────────────────────┘ └─────────────┘
│ │
Creates NIP-98 token Verifies signature
signed with privkey Extracts did:nostr:
│ │
└─────── Basic Auth ──────┘
username: nostr
password: <base64-token>
- Git requests credentials from
git-credential-nostr - The helper creates a NIP-98 HTTP Auth event (kind 27235) signed with your Nostr key
- The token is sent as Basic Auth password
- JSS verifies the Schnorr signature and extracts your pubkey
- Your WebID
did:nostr:<pubkey>is checked against the ACL
# Set private key globally
git config --global nostr.privkey <key>
# Set private key per-repo (recommended)
git config nostr.privkey <key>
# Use a keyfile instead
git config nostr.keyfile ~/.nostr/privkey
# Restrict to specific hosts
git config nostr.hosts "solid.social example.com"- Check that your
did:nostr:<pubkey>is in the.aclfile - Verify the private key matches the public key in the ACL
- Ensure
acl:Writemode is granted
- Add public read access to the ACL (see Step 3)
- Check that
.aclfile exists and is valid JSON-LD
- Run
git config receive.denyCurrentBranch ignorein the server repo