Skip to content

feat(node)!: [high] support JWT auth token revocation - #5364

Open
jcstein wants to merge 6 commits into
celestiaorg:mainfrom
jcstein:jcstein/4816-make-pr
Open

jcstein wants to merge 6 commits into
celestiaorg:mainfrom
jcstein:jcstein/4816-make-pr

Conversation

@jcstein

@jcstein jcstein commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Issued JWTs cannot currently be invalidated individually. This adds admin-only node.AuthRevoke(token) and celestia node revoke-token, backed by the existing node datastore. Revoked tokens stop authenticating, their active WebSocket sessions and subscriptions disconnect, and unrelated tokens remain valid.

Closes #4816.

Approach

  • Store SHA-256 hashes of verified, decoded JWT signatures under /auth/revoked/. This supports existing tokens, including legacy tokens without nonces, and prevents alternate signature encodings from bypassing revocation.
  • Share one verifier between RPC authentication and node.AuthVerify. Parse and verify each token once, then reuse it for permission and revocation checks. Datastore read failures reject authentication.
  • Serialize request registration and revocation to close the authentication/registration race. Cancel request contexts to use go-jsonrpc's existing WebSocket shutdown behavior.
  • Keep revocation idempotent and synchronize the datastore before reporting success.
  • Add CLI usage documentation, generated mocks, and regression tests.

This follows up on the discussion in #5132 using the existing datastore and request lifecycle, without a separate revocation file or connection tracker.

Usage and scope

celestia node revoke-token "$TOKEN_TO_REVOKE" --url http://localhost:26658 --token "$ADMIN_TOKEN"

A local operator can instead supply --node.store <path>. The node must be running with RPC authentication enabled. Revocation records persist across restarts and are retained indefinitely. Offline revocation, issued-token listing, and refresh flows are outside this change. Revocation cannot undo operations already performed by an in-flight request.

Breaking Go API change: rpc.NewServer now accepts *authtoken.Verifier instead of jwt.Verifier; node.Module gains AuthRevoke. The JWT format and existing RPC methods remain unchanged.

Validation

  • make test-unit passed. Coverage packages run serially to prevent port collisions between test processes that allocate from the same deterministic port range.

  • go test -short -p 1 ./... passed. The initial parallel run encountered a port collision in TestEstimatorService; the isolated retry and serial suite passed.

  • go test -race ./libs/authtoken ./api/rpc ./nodebuilder/node ./nodebuilder/rpc ./nodebuilder/node/cmd passed.

  • Coverage includes single-pass token parsing, persistent storage reopening, legacy/expired/foreign tokens, alternate signature encodings, storage errors, concurrent registration/revocation, session cleanup, admin authorization, HTTP rejection, active WebSocket termination, reconnect rejection, self-revocation, and CLI routing.

  • Changed-package go vet, formatting/import checks, and golangci-lint v2.10.1 run --new-from-rev=origin/main ./... passed.

  • CLI build/help and OpenRPC generation passed; the generated schema includes admin-only node.AuthRevoke.

  • Repository-wide go vet ./... still reports the existing discarded timeout cancellation at cmd/rpc.go:88, unchanged from origin/main.

Persist per-token revocations in the node datastore and cancel active authenticated requests, including WebSocket sessions. Add admin RPC and CLI revocation with regression coverage.
@jcstein
jcstein requested a review from a team as a code owner October 23, 2026 18:40
@jcstein
jcstein requested a review from chatton October 23, 2026 18:40
@github-actions github-actions Bot added the external Issues created by non node team members label Oct 23, 2026
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.15842% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 40.50%. Comparing base (f218889) to head (255bf31).

Files with missing lines Patch % Lines
nodebuilder/node/mocks/api.go 0.00% 8 Missing ⚠️
nodebuilder/node/module.go 0.00% 4 Missing ⚠️
nodebuilder/node/cmd/node.go 71.42% 1 Missing and 1 partial ⚠️
libs/authtoken/authtoken.go 50.00% 1 Missing ⚠️
nodebuilder/rpc/constructors.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5364      +/-   ##
==========================================
+ Coverage   40.06%   40.50%   +0.44%     
==========================================
  Files         323      324       +1     
  Lines       22484    22572      +88     
==========================================
+ Hits         9008     9143     +135     
+ Misses      12412    12358      -54     
- Partials     1064     1071       +7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@greptile-apps

greptile-apps Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[High impact] No identified issues block merging.

Summary

Adds persistent JWT revocation through admin-only node.AuthRevoke and celestia node revoke-token.

  • Admins can revoke one token and end its active RPC sessions.
  • Operators can revoke a token with a node command.
  • Coverage tests run one package at a time.

No code changed since the previous review. No previous review threads were supplied. The previously established full-PR rules check found no violations. No blocking issues were identified.

Reviews (6) · Last reviewed commit: "ci: retry transient Go proxy download fa..." · Reviewed by Greptile

@jcstein jcstein self-assigned this Oct 23, 2026

@chatton chatton left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review! Looks good overall, left a few small suggestions

Comment thread README.md
Comment thread CHANGELOG_PENDING.md Outdated
Comment thread libs/authtoken/verifier.go Outdated
Reuse parsed JWTs for permission checks and revocation keys. Combine verification and session registration while preserving the revocation lock, invalid-token checks, and active request cancellation.

Keep the README usage example and remove CHANGELOG_PENDING.md as requested in review. The feature commit records persistent revocation; the Go API adds node.AuthRevoke and changes rpc.NewServer to accept *authtoken.Verifier.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external Issues created by non node team members

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Support JWT Auth Token Revocation

2 participants