feat(cpa-api-keys): support key-policy plugin keys with source isolation - #443
Open
crossly wants to merge 1 commit into
Open
feat(cpa-api-keys): support key-policy plugin keys with source isolation#443crossly wants to merge 1 commit into
crossly wants to merge 1 commit into
Conversation
- add cpa_api_keys.source column (cpa/plugin) with backfill migration - syncCPA/api-keys replacement now only soft-deletes source=cpa rows - add key-policy plugin keys fetch (GET /v0/management/plugins/cpa-key-policy/keys) - add SyncPluginAPIKeys upsert/soft-delete scoped to source=plugin rows - exclude plugin rows from api-key login (short ids are guessable) - gate plugin sync behind KEY_POLICY_SYNC_ENABLED (default off)
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.
Problem
API keys issued by the cpa-plugin-key-policy CPA plugin never appear in per-key statistics / rankings:
usage_events.api_group_keycarries the plugin key id, e.g.kath), and overview aggregations include them.cpa_api_keysis synced from CPA's/v0/management/api-keyswith full-replace semantics (SyncCPAAPIKeys): any row not in that list is soft-deleted. Plugin keys are never in CPA's coreapi-keys, so a manually added row cannot survive even one sync cycle.cpa_api_keys ... AND is_deleted = 0, so plugin keys are permanently invisible in the UI.Solution
Opt-in support for key-policy plugin keys, behind
KEY_POLICY_SYNC_ENABLED(default false — zero behavior change when off):cpa_api_keys.source(cpa/plugin, migration20260822_add_cpa_api_key_source, existing rows backfilled tocpa).SyncCPAAPIKeysnow only soft-deletessource='cpa'rows; plugin rows are untouched by the CPA full-replace sync.FetchKeyPolicyPluginKeys→GET {CPA_BASE_URL}/v0/management/plugins/cpa-key-policy/keys(same management Bearer token; onlyenabledkeys are kept).SyncPluginAPIKeys: upserts plugin keys by their id (which is exactly what usage events carry inapi_group_key),display_keyuses the plugin'skey_preview(falls back to id),key_aliasis filled from the plugin key's name only when locally empty (user-edited aliases are never overwritten). Plugin keys removed from the plugin side are soft-deleted — but only when the plugin fetch succeeded; on failure, local state is left untouched (same semantics as the CPA key sync).Security
cpa_api_keysdoubles as the credential store for api-key viewer login (apiKeyLogin→FindActiveCPAAPIKeyByValue). Plugin key ids are short, human-meaningful strings (e.g.kath) — storing them as login-able key values would be a weak-password equivalent.FindActiveCPAAPIKeyByValuetherefore excludessource='plugin'rows: plugin keys are visible in stats but cannot be used to log in.No plaintext plugin secrets are handled: the plugin's management API exposes only id/name/key_preview (the raw key is shown once at creation), and none is needed for attribution.
Tests
go build ./...,go vet ./...,go test ./...all green.Notes
Verified in production against CLIProxyAPI Plus v7.2.127 + cpa-key-policy v0.4.4: plugin key appears in rankings, survives CPA restarts and metadata sync cycles, and new usage aggregates correctly.