fix(keycloak): add omitempty to protocolMapperRep.ID to prevent ghost PK - #362
Merged
Merged
Conversation
The protocolMapperRep struct serializes the zero-value ID field as "id":"" in POST requests. Keycloak accepts this as an explicit primary key, creating a row with PK "". Every subsequent mapper creation for any scope fails with duplicate key constraint violation on PROTOCOL_MAPPER.id. The 409 handler cannot find the ghost row via GET, so it returns nil and the mapper is never created. This causes "aud not satisfied" 401 errors on all agents with AuthBridge. Adding omitempty causes the ID field to be omitted from POST payloads so Keycloak auto-generates a UUID. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: cwiklik <cwiklikj@gmail.com>
esnible
approved these changes
May 14, 2026
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.
Summary
omitemptytoprotocolMapperRep.IDJSON tag so the zero-value""is omitted from POST payloads, allowing Keycloak to auto-generate mapper UUIDsRoot cause
The
protocolMapperRepstruct serializes the zero-value ID field as"id":""in POST requests. Keycloak accepts this as an explicit primary key, inserting a row with PK""into thePROTOCOL_MAPPERtable. Every subsequent mapper creation — for any agent, any scope — fails with:The operator's 409 handler does a GET to verify the mapper exists, but the ghost row (
id="") is not returned by the Keycloak REST API. The handler returnsnil, the next reconcile retries with the same result, and the mapper is never created. This causes"aud" not satisfied401 errors on all agents with AuthBridge enabled.Affected versions
This affects all deployments where the operator creates audience scopes (PR #360 /
EnsureAudienceScope). The first agent deployed poisons the DB for all subsequent agents.Recovery
Existing deployments with the ghost row need a one-time DB cleanup:
After the cleanup + operator upgrade, new agents get correct audience mappers automatically.
Test plan
SELECT * FROM protocol_mapper WHERE id = '')Assisted-By: Claude Code