Skip to content

feat(backend, website): add API key authentication for collections API#1218

Merged
fhennig merged 16 commits into
mainfrom
feat/api-key-auth
May 27, 2026
Merged

feat(backend, website): add API key authentication for collections API#1218
fhennig merged 16 commits into
mainfrom
feat/api-key-auth

Conversation

@fhennig
Copy link
Copy Markdown
Contributor

@fhennig fhennig commented May 20, 2026

Closes #1200

Summary

  • DB: new api_keys_table (UUID PK, unique FK to users_table, SHA-256 key hash, timestamps)
  • Backend: GET/POST/DELETE /api-keys?userId= for key management; POST /internal/api-keys/validate for proxy use; ConflictException (409) added to exception handler
  • Proxy: authMiddleware now checks Authorization: Bearer <key> first — validates against the backend, populates gsUserId, then falls through to the existing session cookie check if absent/invalid; unexpected validation errors are logged
  • Frontend: /api-keys page with a React component to view key metadata, generate a new key (shown once in a modal), and revoke it

Notes

  • The raw key is a 32-byte SecureRandom value hex-encoded (64 chars); only its SHA-256 digest is stored

Tests

Backend (ApiKeyControllerTest): covers all endpoints — GET/POST/DELETE /api-keys and POST /internal/api-keys/validate. Cases include: no key returns 404, generated key is 64 hex chars, second key returns 409, revoked key returns 404 on validate, lastUsedAt updates on each validation call, two users can hold independent keys.

Playwright (apiKey.spec.ts): full lifecycle test — navigates to /api-keys as an authenticated user, generates a key via the UI, captures it from the show-once modal, creates a collection via Authorization: Bearer <key>, verifies the collection is returned, revokes the key in the UI, then confirms a subsequent Bearer request returns 401.

Screenshots

Screen.Recording.2026-05-21.at.15.04.15.mov

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboards Ready Ready Preview, Comment May 26, 2026 9:27am

Request Review

fhennig and others added 5 commits May 20, 2026 17:09
#1200)

Implements one-key-per-user API key auth as an alternative to OAuth sessions,
allowing programmatic/script access via Authorization: Bearer <key> header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend: ApiKeyClient + ApiKeyControllerTest covering all CRUD endpoints
and the internal validate endpoint.

Frontend: Playwright e2e test for the full lifecycle — generate key via UI,
create a collection with Bearer auth, verify it, revoke the key, confirm
the revoked key returns 401.

Also fixes ktlint issues: rename package api_key → apikey, wrap long
description line in ApiKeyController; fix eslint naming-convention
violations in authMiddleware and apiKey.spec.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds API key authentication to enable programmatic access to the collections API (without browser/OAuth session), including backend storage/validation, proxy support in the website middleware, a UI management page, and end-to-end + backend test coverage.

Changes:

  • Backend: introduce API key persistence + key management endpoints (/api-keys) and internal validation endpoint (/internal/api-keys/validate), including 409 handling.
  • Website/proxy: extend authMiddleware to accept Authorization: Bearer <key> and populate gsUserId; add /api-keys UI and /api/api-keys proxy route.
  • Tests: add backend controller tests and Playwright E2E coverage for full key lifecycle + using Bearer auth to create collections.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
website/tests/e2e.fixture.ts Adds authenticated fixture for the new API keys page object.
website/tests/api-keys/ApiKeyPage.ts New Playwright page object for /api-keys interactions.
website/tests/api-keys/apiKey.spec.ts New E2E test covering generate/use/revoke API key workflow.
website/src/types/pages.ts Adds /api-keys route constant.
website/src/types/ApiKey.ts Adds Zod schemas/types for API key metadata and generated key response.
website/src/pages/api/api-keys/index.ts Proxies API key CRUD calls to the backend.
website/src/pages/api-keys/index.astro Adds /api-keys page shell + auth gating.
website/src/middleware/authMiddleware.ts Adds Bearer API key validation flow before cookie-session auth.
website/src/components/api-keys/ApiKeyManager.tsx New UI for viewing metadata, generating, showing-once, and revoking keys.
website/src/backendApi/backendService.ts Adds client methods for API key GET/POST/DELETE.
backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/ApiKeyControllerTest.kt Backend integration tests for API key endpoints and validation behavior.
backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/ApiKeyClient.kt Test client helpers for API key endpoints.
backend/src/main/resources/db/migration/V1.4__add_api_keys_table.sql Adds api_keys_table migration (UUID PK, per-user uniqueness, hash index).
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/model/apikey/ApiKeyTable.kt Exposed table/entity for API keys + lookup helpers.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/model/apikey/ApiKeyModel.kt Service logic for generate/revoke/validate and hash handling.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/controller/ExceptionHandler.kt Adds ConflictException → HTTP 409 mapping.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/controller/ApiKeyController.kt New REST controller for API key CRUD and internal validation endpoint.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/api/ApiKey.kt Adds API DTOs for metadata, generation response, and validation request/response.

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

Comment thread website/src/components/api-key/ApiKeyManager.tsx
Comment thread website/src/pages/api-key/index.astro
Comment thread website/src/components/api-key/ApiKeyManager.tsx Outdated
Comment thread website/src/components/api-key/ApiKeyManager.tsx Outdated
Enable pgcrypto extension in migration; use BackendError instanceof check instead of structural cast for 404 handling in ApiKeyManager.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Catch the unique constraint violation (SQLState 23505) on insert so concurrent requests for the same user get a 409 instead of a 500. The pre-check remains as a fast path for the common case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simpler and more idiomatic than catching SQLException and checking SQLState.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…convention

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The page is singular since a user can only have one key. Also adds an
"API Key" link to the user dropdown menu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…utton

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ode in description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Comment thread website/tests/api-key/apiKey.spec.ts
Comment thread website/src/components/auth/UserDropdown.astro
Comment thread website/src/components/auth/UserDropdown.astro
Comment thread website/tests/api-key/ApiKeyPage.ts Outdated
fhennig and others added 2 commits May 26, 2026 11:26
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rated API key

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@fhennig fhennig merged commit 59c1491 into main May 27, 2026
10 checks passed
@fhennig fhennig deleted the feat/api-key-auth branch May 27, 2026 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: API key authentication for collections API

3 participants