Skip to content

feat: EdDSA token for database leakage/index mitigation#971

Open
eternal-flame-AD wants to merge 8 commits into
masterfrom
pk-token
Open

feat: EdDSA token for database leakage/index mitigation#971
eternal-flame-AD wants to merge 8 commits into
masterfrom
pk-token

Conversation

@eternal-flame-AD

@eternal-flame-AD eternal-flame-AD commented Jun 2, 2026

Copy link
Copy Markdown
Member

Fixes #325 , supercedes #707

Backend should be working with tests now, I'm currently settling on a timestamp based signature scheme like TOTP with more relaxed window (+-15 minutes for now).

also refactored some tests that used to rely on hijacking the token generation function to be consistency/property based.

@jmattheis

Copy link
Copy Markdown
Member

Could you answer the questions in #966 (comment)?

Comment thread api/stream/client.go
@@ -16,7 +16,7 @@ var ping = func(conn *websocket.Conn) error {
return conn.WriteMessage(websocket.PingMessage, nil)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we want to include this PR in the Gotify 3 release?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think it's a breaking change so maybe not necessary?

I can work on it a bit more next week and hopefully get a review Friday or so.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Oh actually probably yes we should merge it before v3.. we should do it since it will hide all the new tokens after generation and that might break workflows.

@jmattheis jmattheis mentioned this pull request Jun 20, 2026
9 tasks
@codecov

codecov Bot commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.84768% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.39%. Comparing base (8221c0b) to head (76fb8ed).

Files with missing lines Patch % Lines
auth/token.go 77.31% 11 Missing and 11 partials ⚠️
auth/authentication.go 35.71% 7 Missing and 2 partials ⚠️
plugin/example/echo/echo.go 0.00% 3 Missing ⚠️
api/oidc.go 66.66% 1 Missing and 1 partial ⚠️
plugin/testing/mock/mock.go 60.00% 1 Missing and 1 partial ⚠️
runner/runner.go 0.00% 2 Missing ⚠️
plugin/testing/broken/malformedconstructor/main.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #971      +/-   ##
==========================================
- Coverage   74.70%   74.39%   -0.32%     
==========================================
  Files          67       66       -1     
  Lines        3357     3441      +84     
==========================================
+ Hits         2508     2560      +52     
- Misses        665      683      +18     
- Partials      184      198      +14     

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@eternal-flame-AD

Copy link
Copy Markdown
Member Author
  1. I think we could leave the timestamp in but undocumented for now, I like the current shape allows us to adapt to future needs like signed shared message links. It's strictly gated behind a valid verify so it shouldn't open up additional security problems
  2. We probably should have some support for token rotation at least for applications (an elevated endpoint for regenerating tokens). I can create an issue for that later.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Introduces an Ed25519-based “enhanced token” scheme to mitigate database token leakage by storing a non-secret public form server-side while returning/using a private form client-side (and optionally supporting timestamp signatures). The UI is adjusted to only reveal app/client tokens once at creation time, and the API/docs/tests are updated to reflect the new token lifecycle.

Changes:

  • Added EnhancedToken (Ed25519) generation/parsing/signing utilities and updated authentication/token generation to store public-form tokens while issuing private-form tokens to clients (including session cookies).
  • Updated API responses and UI to stop displaying tokens in tables and instead show tokens only once on create dialogs; updated UI e2e tests accordingly.
  • Refactored Go tests and plugin compat code (e.g., any, slices.Contains, build tags) and updated OpenAPI spec to match token visibility changes.

Reviewed changes

Copilot reviewed 56 out of 56 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
ui/src/tests/utils.ts Updates client table column indices after removing token column.
ui/src/tests/setup.ts Puppeteer launch config updated (adds Chromium executable path).
ui/src/tests/selector.ts Adds <p> selector helper for token display assertions.
ui/src/tests/elevation.test.ts Adjusts flow to finish client creation before assertions.
ui/src/tests/client.test.ts Updates client creation/update tests for “token shown once” dialog flow.
ui/src/tests/application.test.ts Updates application tests for “token shown once” dialog flow and removed token column.
ui/src/common/CopyableSecret.tsx Refactors clipboard copying to shared helper.
ui/src/clipboard.ts Adds centralized clipboard helper (with fallback).
ui/src/client/ClientStore.ts Makes create return the newly issued token for one-time display.
ui/src/client/Clients.tsx Removes token column from client list UI.
ui/src/client/AddClientDialog.tsx Shows client token only once after creation + copy/select UX.
ui/src/application/AppStore.ts Makes create return the newly issued token for one-time display.
ui/src/application/Applications.tsx Removes token column from application list UI.
ui/src/application/AddApplicationDialog.tsx Shows application token only once after creation + copy/select UX.
test/token.go Removes old deterministic token generator helper.
test/token_test.go Removes tests for removed deterministic token helper.
test/asserts.go Uses any in test helpers.
test/asserts_test.go Uses any in fake testing helper.
runner/runner.go Uses strings.CutPrefix for unix address parsing.
router/router_test.go Integration test updates (currently includes token logging).
plugin/testing/mock/mock.go Uses slices.Contains and any updates for test plugin mock.
plugin/testing/broken/malformedconstructor/main.go Uses any return type for malformed constructor plugin.
plugin/manager.go Updates plugin/app token generation for new token scheme.
plugin/manager_test.go Updates plugin manager tests for new token generator signature/behavior.
plugin/manager_test_race.go Removes legacy build tag line.
plugin/manager_test_norace.go Removes legacy build tag line.
plugin/example/echo/echo.go Uses any + extras map typing update.
plugin/compat/wrap_test.go Removes legacy build tag line.
plugin/compat/wrap_test_race.go Removes legacy build tag line.
plugin/compat/wrap_test_norace.go Removes legacy build tag line.
plugin/compat/v1.go Uses any in wrapper config methods.
plugin/compat/v1_test.go Updates extras map typing to map[string]any.
plugin/compat/instance.go Uses any and slices.Contains; updates message extras typing.
model/message.go Updates Extras typing to map[string]any.
model/client.go Updates swagger annotations (token no longer required).
model/application.go Updates swagger annotations (token no longer required).
docs/spec.json Updates OpenAPI spec for token visibility/required fields and security blocks formatting.
database/user.go Uses any for variadic conditions.
database/database.go Uses any in gorm logger writer signature.
auth/token.go Implements Ed25519 enhanced tokens; changes app/client token generation to return public+private forms.
auth/token_test.go Updates tests for enhanced token parsing/signing (currently includes token logging).
auth/authentication.go Adds enhanced-token parsing/canonicalization + cookie preservation.
api/user.go Uses any for variadic conditions in interface.
api/tokens_test.go Updates token format assertions for enhanced tokens.
api/stream/stream_test.go Uses any in websocket write stub; adjusts loop syntax.
api/stream/client.go Uses any in websocket write helper signature.
api/session.go Stores public token in DB and sets private token in session cookie.
api/session_test.go Removes token hijacking; asserts session cookie contains enhanced token.
api/oidc.go Creates client with public token in DB, returns private token for cookie use.
api/oidc_test.go Removes token hijacking; asserts enhanced token behavior and DB storage.
api/message.go Uses map[string]any when decoding extras.
api/message_test.go Updates extras typing to any.
api/client.go Stores public token in DB, returns private token on create; strips token on list.
api/client_test.go Updates client tests for public-in-DB/private-in-response behavior.
api/application.go Stores public token in DB, returns private token on create; strips token on list.
api/application_test.go Updates application tests for public-in-DB/private-in-response behavior and image dir handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread auth/authentication.go
Comment thread auth/authentication.go
Comment thread router/router_test.go Outdated
Comment thread router/router_test.go Outdated
Comment thread auth/token_test.go Outdated
Comment thread ui/src/tests/setup.ts Outdated
Comment thread ui/src/clipboard.ts
Comment thread ui/src/common/CopyableSecret.tsx
Comment thread ui/src/client/AddClientDialog.tsx
Comment thread ui/src/application/AddApplicationDialog.tsx
@eternal-flame-AD eternal-flame-AD marked this pull request as ready for review June 21, 2026 04:30
@eternal-flame-AD eternal-flame-AD requested a review from a team as a code owner June 21, 2026 04:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Security: Store api token hashed

3 participants