Skip to content

feat: rotate api key, close #1692#1696

Merged
looplj merged 1 commit into
unstablefrom
dev-tmp
May 22, 2026
Merged

feat: rotate api key, close #1692#1696
looplj merged 1 commit into
unstablefrom
dev-tmp

Conversation

@looplj

@looplj looplj commented May 22, 2026

Copy link
Copy Markdown
Owner

@greptile-apps

greptile-apps Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR implements API key rotation: a new rotateAPIKey GraphQL mutation generates a fresh key value while preserving the key's ID, name, type, scopes, and usage statistics. The old key is immediately invalidated via cache eviction, and the new key is surfaced once in the rotate dialog for the user to copy.

  • internal/ent/schema/api_key.go removes Immutable() from the key field (required for rotation); GraphQL mutation inputs continue to skip the field via annotations, so external callers cannot set it directly. abstract.go is updated with a comment clarifying that Ent privacy policies are enforced through the context, not through which client instance is used.
  • The new ApiKeysRotateDialog frontend component shows the masked new key with a copy button and a success alert after rotation. Two prior review comments cover the empty catch {} block and missing copy-before-close guidance in the success state.
  • Backend tests include cross-project access prevention, noauth-type block, non-existent key, and both user and service-account type rotations.

Confidence Score: 4/5

Safe to merge after addressing the silent error-swallowing in the rotate dialog that leaves users with no feedback on failure.

The core rotation logic is sound: privacy is enforced contextually through Ent interceptors, the cross-project access test confirms this, cache invalidation covers both old and new keys, and the schema change is correctly scoped. The outstanding concern is the empty catch block in the rotate dialog, which discards mutation errors entirely — a failed rotation leaves the dialog in its pre-rotate state with no visible error, making it impossible for the user to know the operation failed.

frontend/src/features/apikeys/components/apikeys-rotate-dialog.tsx — the handleRotate catch block needs error surfacing before this ships to users.

Important Files Changed

Filename Overview
internal/server/biz/api_key.go Adds RotateAPIKey service method that generates a new key value, invalidates old key caches, and blocks rotation of noauth-type keys. Uses s.db with context-scoped privacy enforcement (clarified by abstract.go comment); correctly passes ctx to all DB operations. No status check for archived keys.
frontend/src/features/apikeys/components/apikeys-rotate-dialog.tsx New dialog component for key rotation. Has two known issues (already in previous review): empty catch block silently discards mutation errors, and the success state does not prompt the user to copy before closing. Masking logic and copy-to-clipboard are otherwise correct.
frontend/src/features/apikeys/components/data-table-row-actions.tsx Adds Rotate row action without an archived-status guard, allowing rotation of archived keys. Other actions (status-change, archive) correctly gate on apiKey.status !== 'archived'.
internal/server/biz/api_key_test.go Comprehensive test coverage including cross-project access prevention, noauth type block, non-existent key, and both user and service-account type rotations. All cases are well-formed.
internal/ent/schema/api_key.go Removes Immutable() constraint from the key field to enable rotation; GraphQL mutation inputs still skip the field via annotations, so external callers cannot set the key directly through standard update mutations.
internal/server/biz/abstract.go Adds a clarifying comment explaining that entFromContext is for transaction support only, and that Ent privacy policies are enforced contextually regardless of which client instance is used.
internal/server/gql/axonhub.resolvers.go Adds RotateAPIKey GraphQL resolver that delegates directly to the service layer. Straightforward plumbing with no issues.
internal/ent/apikey_update.go Generated code adding SetKey/SetNillableKey methods to the APIKeyUpdate builder, required after removing Immutable() from the schema field.
frontend/src/features/apikeys/data/apikeys.ts Adds useRotateApiKey mutation hook with correct GraphQL query, cache invalidation, and error handling via handleError.

Sequence Diagram

sequenceDiagram
    participant User
    participant RotateDialog
    participant Mutation Hook
    participant GraphQL Server
    participant BizLayer
    participant Database

    User->>RotateDialog: Click Rotate
    RotateDialog->>Mutation Hook: mutateAsync(id)
    Mutation Hook->>GraphQL Server: rotateAPIKey(id)
    GraphQL Server->>BizLayer: RotateAPIKey(ctx, id)
    BizLayer->>Database: APIKey.Get(ctx, id) [privacy enforced via ctx]
    Database-->>BizLayer: existing record
    BizLayer->>BizLayer: GenerateAPIKey(prefix)
    BizLayer->>Database: UpdateOneID(id).SetKey(newValue).Save(ctx)
    Database-->>BizLayer: updated record
    BizLayer->>BizLayer: invalidateAPIKeyCaches(old, new)
    BizLayer-->>GraphQL Server: APIKey
    GraphQL Server-->>Mutation Hook: rotateAPIKey result
    Mutation Hook-->>RotateDialog: result with new value
    RotateDialog->>User: Show masked value + Copy button
Loading

Reviews (4): Last reviewed commit: "feat: rotate api key, close #1692" | Re-trigger Greptile

Comment thread internal/server/biz/api_key.go

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an API key rotation feature, allowing users to generate new keys while preserving usage statistics. It includes the backend logic using raw SQL to update immutable fields, GraphQL mutations, and a new frontend dialog for the rotation process. Additionally, Atlas Cloud has been added as a provider with its own icon and sponsor sections in the documentation. Feedback focuses on potential SQL type mismatches for timestamps, the need to quote reserved keywords in database queries, and improving the visibility of newly generated keys in the UI.

Comment thread internal/server/biz/api_key.go Outdated
Comment thread internal/server/biz/api_key.go Outdated
Comment thread frontend/src/features/apikeys/components/apikeys-rotate-dialog.tsx
@looplj looplj force-pushed the dev-tmp branch 2 times, most recently from 35bc2d9 to 94de33c Compare May 22, 2026 16:53
@looplj looplj merged commit 1383a76 into unstable May 22, 2026
4 checks passed
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.

1 participant