feat(backend): add system user auto-creation from application YAML#1220
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
a97a28e to
451c269
Compare
064185d to
4563e22
Compare
812c1bd to
1597ee9
Compare
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>
1597ee9 to
1abb745
Compare
There was a problem hiding this comment.
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
DashboardsConfigwith optionalsystemUserconfiguration (SystemUserConfig). - Add
ApiKeyModel.upsertApiKey(userId, rawKey)to insert/rotate a provided API key. - Introduce
SystemUserInitializerApplicationRunnerplus integration tests covering creation/idempotency/rotation/lastUsedAtbehavior.
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.
fengelniederhammer
left a comment
There was a problem hiding this comment.
🟡 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
githubIdbelongs to a real person, the system API key grants full access to that person's collections. - Every backend restart,
SystemUserInitializeroverwrites the user'snameandemailback to the config values. Conversely, every OAuth login overwrites them to the GitHub profile values. - If someone misconfigures
githubIdto 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>
| init { | ||
| require(apiKey == null || apiKey.length >= 32) { "systemUser.apiKey must be at least 32 characters" } | ||
| } |
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: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
SystemUserConfigdata class and optionalsystemUserfield toDashboardsConfigupsertApiKey(userId, rawKey)toApiKeyModel— inserts on first run, rotates on key change, no-ops if hash is unchangedSystemUserInitializerApplicationRunnercreates/updates the configured bot account and upserts its API key at startupTest plan
SystemUserInitializerTestcover: key creation + user existence, idempotency, key rotation (old key rejected / new key validates),lastUsedAtnot reset on same-key re-runsystemUserblock to a local YAML profile, start the backend, verify user appears atGET /users/{id}and key validates atPOST /internal/api-keys/validateapiKey→ old key rejected, new key validates🤖 Generated with Claude Code