nostr remote signer
. . * . .
. * .-~~~~~~~~-. * .
. .~~* . ** . *~~. .
* .~* .-********-. *~. *
.~* .* ** ** ** *. *~.
. ~ .* ** ** **** ** ** *. ~ .
*~ .* ** ************** ** *. ~*
. ~ .* ** ***** ***** ** *. ~ .
.~ .* ** **** **** **** ** *. ~.
* ~ .* ** **** ****** **** ** *. ~ *
.~ .* ** **** **** **** ** *. ~.
. ~ .* ** ***** ***** ** *. ~ .
*~ .* ** ************** ** *. ~*
. ~ .* ** ** **** ** ** *. ~ .
.~* .* ** ** ** *. *~.
* .~* .-********-. *~. *
. .~~* . ** . *~~. .
. * .-~~~~~~~~-. * .
. . * . .
Mycorrhiza is a Nostr remote signer that implements the NIP-46 specification. It is built to enable delegated account access and secure signing flows.
myc loads its runtime configuration from .env in the repo root by default.
Use .env.example as the checked starting point:
cp .env.example .envThen replace the example paths, relays, and discovery host with real local values before running the service.
Transport delivery is explicit:
MYC_TRANSPORT_DELIVERY_POLICY=anysucceeds when at least one configured transport relay acknowledges a publishMYC_TRANSPORT_DELIVERY_POLICY=quorumrequiresMYC_TRANSPORT_DELIVERY_QUORUMMYC_TRANSPORT_DELIVERY_POLICY=allrequires every configured transport relay to acknowledgeMYC_TRANSPORT_PUBLISH_MAX_ATTEMPTS,MYC_TRANSPORT_PUBLISH_INITIAL_BACKOFF_MILLIS, andMYC_TRANSPORT_PUBLISH_MAX_BACKOFF_MILLIScontrol bounded retry and backoff for listener responses,connect accept, auth replay, and discovery publication
Publish flows are also durable:
- listener responses,
connect accept, auth replay, and discovery publication are written to a persistent delivery outbox before relay send myc runperforms startup recovery for unfinished delivery jobs before the service is treated as readymyc persistence backup --out ...andmyc persistence restore --from ...provide the first-class offline backup and restore workflow- after JSON-to-SQLite migration or
restore, runmyc persistence verify-restorebeforemyc run - see
docs/delivery.mdfor the durable-delivery and restart-recovery contract
Policy and auth are typed:
MYC_POLICY_CONNECTION_APPROVALsets the default connect policy for unknown clientsMYC_POLICY_TRUSTED_CLIENT_PUBKEYSandMYC_POLICY_DENIED_CLIENT_PUBKEYSoverride that default per client pubkeyMYC_POLICY_PERMISSION_CEILINGandMYC_POLICY_ALLOWED_SIGN_EVENT_KINDSbound what can ever be granted or executedMYC_POLICY_AUTH_URL,MYC_POLICY_AUTH_PENDING_TTL_SECS,MYC_POLICY_AUTHORIZED_TTL_SECS, andMYC_POLICY_REAUTH_AFTER_INACTIVITY_SECScontrol auth challenge expiry and trusted-session reauthMYC_POLICY_CONNECT_RATE_LIMIT_*optionally throttles inboundconnectattempts per client pubkeyMYC_POLICY_AUTH_CHALLENGE_RATE_LIMIT_*optionally throttles automatic auth challenge reissuance per trusted client pubkey- trusted sessions that have exceeded the configured auth TTL or inactivity reauth window are downgraded back to pending auth during bootstrap before
mycstarts serving requests
Custody is backend-aware:
- filesystem remains the default signer, user, and discovery app identity backend
MYC_PATHS_SIGNER_IDENTITY_BACKENDandMYC_PATHS_USER_IDENTITY_BACKENDsupportfilesystem,os_keyring,managed_account, andexternal_commandMYC_DISCOVERY_APP_IDENTITY_BACKENDmay be left unset to reuse the signer identity, or set explicitly for a dedicated filesystem, keyring-backed, managed-account, or external-command discovery app identitymanaged_accountstores selected public identities in an account-store file and secrets in the configured OS keyring namespaceexternal_commandexecutes a role-specific signer helper over JSON stdin/stdout, somyccan request public identity, signing,nip04, andnip44operations without loading that role's secret into themycprocessmyc custody list|generate|import-file|select|removemanages the selected signer, user, or discovery app identity when that role usesmanaged_account*_KEYRING_ACCOUNT_IDselects the public identity id stored in the local keyring vault*_KEYRING_SERVICE_NAMEscopes the local keyring service name*_PROFILE_PATHmay be set foros_keyringidentities when local profile metadata should be merged onto the loaded secret- for
managed_account,*_PATHpoints to the role-specific account store file - for
external_command,*_PATHpoints to the helper executable for that role - see
docs/custody.mdfor the backend contract and migration guidance
Observability is local-only:
MYC_OBSERVABILITY_ENABLED=trueenables the read-only admin surfaceMYC_OBSERVABILITY_BIND_ADDRmust stay on a loopback address such as127.0.0.1:9460myc status --view summary|fullemits machine-readable service status from the CLImyc metrics --format json|prometheusemits stable runtime counters from a persisted-audit startup baseline plus live in-memory updatesmyc statusincludes custody backend and resolution state for signer, user, and discovery app identitiesmyc statusalso includes signer backend capability projection for the local signer, active remote sessions, and active publish workflows- when enabled, the local admin server exposes
/healthz,/readyz,/status, and/metrics
See docs/operability.md for the status, metrics, and endpoint contract.
See docs/delivery.md for delivery outbox, startup recovery, and restart semantics.
This repository uses Nix as the canonical local validation surface:
nix run .#fmt
nix run .#check
nix run .#testEnter the repo shell when you want narrower focused cargo commands:
nix developRun the relay-backed NIP-46 proof lane directly inside the shell when you want the transport/discovery end-to-end suite:
cargo test --locked --test nip46_e2eRun the operability-focused lanes directly inside the shell when you want CLI and admin-surface proof:
cargo test --locked --test operability_cli
cargo test --locked --test operability_serverRun the final release-acceptance gate when preparing a production candidate:
nix run .#release-acceptanceSee docs/release.md for the exact matrix and the integrated-workspace consumer-side interop lanes.
This project is licensed under the AGPL-3.0.