feat(admin): accept NIP-98 auth on admin API routes - #730
Conversation
🦋 Changeset detectedLatest commit: 115a5ea The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
I think CodeQL doesn’t recognize our Redis adminRateLimitMiddleware (it only models express-rate-limit etc). These routes still run that limiter before auth, same as the rest of this file. |
|
@Anshumancanrock totally agree, its a codeql false positive, it was happening same with me too, had tried a fix in #692. |
There was a problem hiding this comment.
Pull request overview
Adds optional NIP-98 authentication to protected admin APIs while preserving session authentication.
Changes:
- Adds NIP-98 verification, allowlisting, payload binding, and Redis replay protection.
- Introduces pre-body authentication gates and raw-body capture.
- Adds configuration, documentation, and tests.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/handlers/request-handlers/admin-auth-middleware.ts |
Implements NIP-98 admin authentication. |
src/handlers/request-handlers/admin-json-body-middleware.ts |
Captures raw JSON bodies. |
src/utils/nip98-replay.ts |
Adds Redis-backed replay claims. |
src/routes/admin/index.ts |
Wires authentication and body middleware. |
src/@types/settings.ts |
Defines NIP-98 settings types. |
resources/default-settings.yaml |
Adds disabled-by-default settings. |
CONFIGURATION.md |
Documents configuration. |
test/unit/handlers/request-handlers/admin-auth-middleware.spec.ts |
Tests authentication behavior. |
test/unit/utils/nip98-replay.spec.ts |
Tests replay claims. |
.knip.json |
Recognizes the now-used verifier. |
.changeset/nip98-admin-middleware.md |
Records the feature release. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
5ca12e7 to
558ee46
Compare
558ee46 to
115a5ea
Compare
Description
Protected admin API routes now accept
Authorization: Nostron top of the existing session cookie.Off by default. Set
admin.nip98.enabledand put hex pubkeys inadmin.nip98.allowedPubkeys. Empty allowlist means nobody gets in that way.For PATCH/POST we check the header (sig + allowlist) before parsing JSON, so a junk
Nostrtoken never hits the 1mb body parser. After the body is read we check the payload hash and store the event id in Redis withSET NX(TTL =maxSkewSeconds). Same event twice, or Redis down → 401.GETs don't parse a body. Same session-or-NIP-98 check, including the one-time event id.
Clients still sign
uagainstinfo.relay_url(not the requestHost). Password login / dashboard / cookie session are unchanged;/loginstays 100kb.Related Issue
Follows #722 (verifier), #725 (absolute URL), #726 (Redis NX).
Motivation and Context
#722 only verifies a header. This is the part that actually lets you call the admin API with a signed event instead of sharing the password.