Admin access key routes + create stat#1005
Merged
Merged
Conversation
tudddorrr
force-pushed
the
admin-access-key-create-stat
branch
from
July 13, 2026 22:19
5e81f7e to
8bc3dd7
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1005 +/- ##
===========================================
+ Coverage 98.27% 98.33% +0.05%
===========================================
Files 427 439 +12
Lines 7111 7246 +135
Branches 965 971 +6
===========================================
+ Hits 6988 7125 +137
+ Misses 50 49 -1
+ Partials 73 72 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
tudddorrr
force-pushed
the
admin-access-key-create-stat
branch
2 times, most recently
from
July 14, 2026 00:58
d1d3e04 to
762267a
Compare
tudddorrr
force-pushed
the
admin-access-key-create-stat
branch
from
July 14, 2026 01:02
762267a to
3da5a5b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Admin API key system
AdminAPIKeyentity with scoped permissions (read:stats,write:stats,*) for server-to-server access, distinct from player-facing API keys/admin/v1/*routing layer with its own middleware that authenticates via Bearer token matching a SHA-256 hash stored in the database, and rejects revoked keys/games/:gameId/admin-api-keyslet admin users create, list, update scopes, and revoke keys; generated keys use ata_prefix with 64 hex charsrequireAdminScopespolicy middleware enforces scope checks on admin API endpoints, withFULL_ACCESSbypassing individual scope checksGame activity actor abstraction
GameActivitynow accepts either aUserorAdminAPIKeyas its actor via a polymorphic constructor, storing the appropriate foreign key (user_idoradmin_apikey_id) and making both nullableuser: ctx.state.usertoactor: ctx.state.user, and the activity description method now displays"Key ending in XXXX"when an admin API key performs the actionuser_idnullable ongame_activityand addson delete set nullfor both foreign keys, so activities persist even if the actor is deletedGame stat admin endpoint
POST /admin/v1/game-statsendpoint that reuses the existingcreateStatHandlerbut authenticates via admin API key and requires thewrite:statsscopecreateStatHandlerwas refactored to accept a genericUser | AdminAPIKeyactor instead of requiring aUserCache invalidation improvements
clearStatIndexResponseCachemiddleware; instead they calldeferClearResponseCacheafter the DB flush, moving cache clearing off the request pathIntegration.getCacheKeyForGame, and the integration delete route now clears the integrations cachetriggerIntegrationshelper now references this static method instead of constructing the key inlineAPI key listing enhancement
keyEnding(last 4 characters) for each non-revoked key, computed from the generated token, matching the pattern already used by admin API keysgetAPIKeyFromTokennow explicitly filters onrevokedAt: nullrather than relying on a separate middleware checkLast-used tracking resilience
recordLastUsedAtfunctions for both API key and admin API key no longer gate onrevokedAt— they always record timestamps (the drain task handles revocation)drainApiKeyLastUsedbackground task was refactored to drain both theAPI_KEY_LAST_USED_HASHandADMIN_API_KEY_LAST_USED_HASHRedis hashes in parallel, with per-key error handling viacaptureExceptionso a single failure doesn't block the restTerminology consistency
MISSING_ACCESS_KEY_SCOPES→MISSING_API_KEY_SCOPES)