Accounts & keys
Your identity is a nostr keypair. ngit stores the secret in your OS credential store by default. Git config holds the name of the credential entry, not the key itself.
Logging in
bash
ngit account login # interactive
ngit account login --bunker-url bunker://... # NIP-46 remote signer
ngit account create --name "Alice" # new identity--local scopes any of these to the current repository instead of globally:
bash
ngit account login --localRemote signers
A NIP-46 bunker keeps the secret key on another device. It never touches this machine. ngit account login interactively shows a QR code and a nostrconnect:// string; --bunker-url takes a connection non-interactively.
Where the secret goes
| Storage | Behaviour |
|---|---|
auto (default) | OS credential store, falling back to ngit's user-only file store |
file | ngit's user-only file store |
git-config | Plaintext in git config, which must be requested explicitly |
bash
ngit account login --secret-storage fileSet it persistently with NGIT_SECRET_STORAGE or nostr.secret-storage.
Several identities
Aliases name stored signers without exposing their secrets:
bash
ngit account login --nsec-file /private/key --alias alice
ngit account login alice # make alice the global default
ngit account login --local alice # make alice this repository's defaultTo use a non-default identity for one command, don't switch logins:
bash
ngit --signer alice issue create --subject "Bug" --body "Details"
git -c nostr.signer=alice push origin pr/topic--signer accepts an alias, an npub, or an exact cached profile name. It fails closed. A missing, ambiguous or invalid selector is an error, never a silent fallback to your default key.
Note that --signer covers ngit commands only. A git push needs git's own -c nostr.signer=..., because git is what runs at that point.
Seeing what you have
bash
ngit account whoami
ngit account whoami --offlineCombines signers from local, global and system git config, the OS credential store and credentials.json. It groups aliases under their account, marks which login scopes are set, and shows which account currently wins git's scope precedence. This is useful when a repository-local login is shadowing your global one.
ngit account list is the same command.
Logging out
bash
ngit account logout # remove login config, keep the stored secret
ngit account logout --forget # also delete the stored secret
ngit account forget-keys <entry> # delete a preserved credential entry
ngit account export-keys # print the stored secretLogging out of a repository-local login can reveal a shadowed global default. whoami will show you which. Treat export-keys output as a secret and never paste it into logs, issues, or command history.
CI and automation
Pass a key for one command without logging in. Prefer secret files or a secret manager over command-line values, which may be visible in the process list:
bash
ngit --nsec-file /run/credentials/nostr-key \
issue create --subject "Automated report" --body "Details" --json
ngit --nbunksec-file /run/credentials/signer-connection \
pr list --jsonAfter an initial online read has populated the cache, add --offline where the specific command supports it.
An nbunksec file contains a portable established remote-signer connection: signer pubkey, client key, relays, and optional pairing secret. It doesn't contain your npub, so one-shot use resolves the identity from the signer.
Pair a remote signer for CI
Create a dedicated connection on a trusted workstation, then give CI the exported connection instead of your identity's nsec. There are two ways to pair it.
Supply a new bunker:// URL
In your remote signer, create a new bunker connection and copy its fresh bunker:// URL. Quote the URL so the shell doesn't interpret its query string:
bash
ngit account login --bunker-url 'bunker://...' --alias ciApprove the connection in the remote signer. ngit generates a client key, connects to the bunker and stores the established connection under the ci alias.
Connect with a generated nostrconnect:// URL
Start the interactive login and choose nostr connect (remote signer):
bash
ngit account login --alias cingit displays a QR code and the same generated nostrconnect:// URL as text. Scan the QR code, or paste the URL into your remote signer, then approve the connection. ngit waits for the signer and stores the established connection under the ci alias.
Export the connection for CI
For a manual copy into your CI secret manager, print only the selected remote signer credential:
bash
ngit --signer ci account export-keys --secretThe output begins with nbunksec1. For an automated setup, request structured output instead; the result includes npub and nbunksec fields:
bash
ngit --signer ci account export-keys --jsonStore the nbunksec as a masked, protected secret and have the CI system expose it as a regular file with mode 0400 or 0600. Pass that path with --nbunksec-file, as in the example above. Do not put the fresh bunker:// pairing URL in CI; export and use the established nbunksec instead.
Remove the workstation copy
After the CI secret manager has stored the export, confirm that the ci connection is still the active login, then remove both its login configuration and its locally stored credential:
bash
ngit account whoami --offline --json
ngit account logout --forget --jsonlogout --forget acts on the active login; it does not accept an account name to target a different one. Run it before switching away from ci, and check the whoami result if the workstation also has a repository-local login.
This removes only the workstation's copy. It does not remove the exported secret from CI or revoke the connection in the remote signer, so existing jobs continue to use it. With the local credential gone, you can pair another connection under the ci alias in the future. To rotate safely, export and install the replacement first, verify a job with it, then revoke the previous connection in the signer.
Treat nbunksec as a secret
It contains the client key for this remote-signer connection. Anyone who has it can request every NIP-46 method that the signer permits. Dedicate the connection to CI, grant only the permissions the job needs, and revoke the connection in your signer if the value leaks. The signer must also be reachable and able to approve unattended requests while the job runs.