Skip to content

feat(backend): add system user auto-creation from application YAML#1220

Merged
fhennig merged 6 commits into
mainfrom
feat/system-user-init
May 27, 2026
Merged

feat(backend): add system user auto-creation from application YAML#1220
fhennig merged 6 commits into
mainfrom
feat/system-user-init

Conversation

@fhennig
Copy link
Copy Markdown
Contributor

@fhennig fhennig commented May 20, 2026

For our staging environment, we want to initialize a system user with a known API key, that we can use right away from our collection seeding scripts.

This feature allows us to configure that system user in the applications.yaml:

dashboards:
  systemUser:
    githubId: "218605180"
    name: "Genspectrum Bot"
    email: null
    apiKey: "${SYSTEM_USER_API_KEY}"
  organisms:
    ...

And then set the env var (SYSTEM_USER_API_KEY).

In our deployment scripts we can then have a shared secret between the backend and the seeder container.

Summary

  • Adds SystemUserConfig data class and optional systemUser field to DashboardsConfig
  • Adds upsertApiKey(userId, rawKey) to ApiKeyModel — inserts on first run, rotates on key change, no-ops if hash is unchanged
  • New SystemUserInitializer ApplicationRunner creates/updates the configured bot account and upserts its API key at startup

Test plan

  • 4 integration tests in SystemUserInitializerTest cover: key creation + user existence, idempotency, key rotation (old key rejected / new key validates), lastUsedAt not reset on same-key re-run
  • Add a systemUser block to a local YAML profile, start the backend, verify user appears at GET /users/{id} and key validates at POST /internal/api-keys/validate
  • Restart with identical config → same user, same key, no errors
  • Restart with changed apiKey → old key rejected, new key validates

🤖 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 27, 2026 9:53am

Request Review

fhennig and others added 2 commits May 27, 2026 09:13
Adds SystemUserConfig to DashboardsConfig, upsertApiKey() to ApiKeyModel,
and a SystemUserInitializer ApplicationRunner that creates/updates a bot
account with an optional deterministic API key on startup.

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

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 startup-time initialization of a configured “system user” (optionally with a pre-defined API key) from applications.yaml, intended for staging automation and seeding workflows.

Changes:

  • Extend DashboardsConfig with optional systemUser configuration (SystemUserConfig).
  • Add ApiKeyModel.upsertApiKey(userId, rawKey) to insert/rotate a provided API key.
  • Introduce SystemUserInitializer ApplicationRunner plus integration tests covering creation/idempotency/rotation/lastUsedAt behavior.

Reviewed changes

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

File Description
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/config/DashboardsConfig.kt Adds systemUser config block and SystemUserConfig data class for YAML binding.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/config/SystemUserInitializer.kt New startup initializer that syncs the configured user and upserts its API key.
backend/src/main/kotlin/org/genspectrum/dashboardsbackend/model/apikey/ApiKeyModel.kt Adds upsertApiKey to create/rotate a known key for a user.
backend/src/test/kotlin/org/genspectrum/dashboardsbackend/config/SystemUserInitializerTest.kt Integration tests validating system user/key behavior and idempotency.

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

Copy link
Copy Markdown
Contributor

@fengelniederhammer fengelniederhammer left a comment

Choose a reason for hiding this comment

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

🟡 Account identity collision via githubId

The systemUser.githubId in the YAML config uses a real GitHub user ID. Since syncUser is keyed on githubId, the system user and any OAuth user who logs in with the same GitHub ID are the same account. This means:

  • If the configured githubId belongs to a real person, the system API key grants full access to that person's collections.
  • Every backend restart, SystemUserInitializer overwrites the user's name and email back to the config values. Conversely, every OAuth login overwrites them to the GitHub profile values.
  • If someone misconfigures githubId to another user's ID, the pre-seeded API key becomes an access key to that user's resources.

This isn't a bug per se (the intent is to use a dedicated bot account), but it should be documented explicitly: the configured githubId must be a dedicated bot/service account, never a real human user's ID.


Other findings are in the individual review comments above (toString key leak, empty key hash, test naming, missing test for null apiKey).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment on lines +45 to +47
init {
require(apiKey == null || apiKey.length >= 32) { "systemUser.apiKey must be at least 32 characters" }
}
@fhennig fhennig merged commit a4fb147 into main May 27, 2026
11 checks passed
@fhennig fhennig deleted the feat/system-user-init branch May 27, 2026 10:08
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.

3 participants