Skip to content

feat(OMN-15877): add OmniWeb principal identity claim - #2726

Merged
jonahgabriel merged 2 commits into
devfrom
daniyal/omn-15877-keycloak-client-contract
Aug 13, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
daniyal/omn-15877-keycloak-client-contract

Conversation

@daniyalabbas96

@daniyalabbas96 daniyalabbas96 commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add the immutable principal_id claim to OmniWeb access and user-info tokens
  • keep ordinary OmniWeb user tokens outside the gateway attach audience
  • add a contract test that prevents accidental gateway-audience broadening

The gateway credential is minted separately by the guarded server-side exchange from a per-tenant attach-only client. This PR does not expose a broker credential or add a second browser-visible secret.

Verification

  • canonical Keycloak desired-client contract: 2 passed
  • JSON and diff validation passed

Deployment gate

Live completion requires reviewed backend exchange and attach hardening, canonical reconciliation, fresh signed-token readback, and the negative broker-auth proof.

Evidence-Ticket: OMN-15877
Evidence-Source: OCC#6377

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The omniweb Keycloak client maps the principal_id user attribute to a principal_id claim in ID, access, and userinfo tokens. A contract test validates the mapper settings and the absence of a gateway-attach audience mapper.

Changes

Omniweb token claims

Layer / File(s) Summary
Claim mapper and contract validation
docker/keycloak/desired-clients.json, scripts/tests/test_keycloak_desired_clients_contract.py
The omniweb client adds the principal_id user-attribute mapper. The contract test verifies its type, attribute, claim name, token settings, and the absence of gateway-attach audience mappers.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding OmniWeb gateway token claims.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch daniyal/omn-15877-keycloak-client-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
scripts/tests/test_keycloak_desired_clients_contract.py (1)

36-45: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Cover all token-placement invariants in the contract test.

docker/keycloak/desired-clients.json sets principal_id for ID, access, and userinfo tokens at Lines 59-61. It excludes gateway-attach from ID tokens at Line 79. This test checks only the access-token flags at Line 40 and Line 45. A regression in the other placement flags would pass the test.

Suggested assertions
     assert principal["config"]["access.token.claim"] == "true"
+    assert principal["config"]["id.token.claim"] == "true"
+    assert principal["config"]["userinfo.token.claim"] == "true"

     audience = mappers["gateway-attach-audience"]
     assert audience["protocolMapper"] == "oidc-audience-mapper"
     assert audience["config"]["included.custom.audience"] == "gateway-attach"
     assert audience["config"]["access.token.claim"] == "true"
+    assert audience["config"]["id.token.claim"] == "false"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test_keycloak_desired_clients_contract.py` around lines 36 -
45, Extend the contract assertions for the principal_id and gateway-attach
mappers in the test covering mappers to validate every token-placement flag
configured in desired-clients.json: principal_id must be enabled for ID, access,
and userinfo tokens, while gateway-attach must be excluded from ID tokens and
retain its access-token setting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/tests/test_keycloak_desired_clients_contract.py`:
- Around line 36-45: Extend the contract assertions for the principal_id and
gateway-attach mappers in the test covering mappers to validate every
token-placement flag configured in desired-clients.json: principal_id must be
enabled for ID, access, and userinfo tokens, while gateway-attach must be
excluded from ID tokens and retain its access-token setting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8fdb63a7-e6c7-4d44-a433-776e04cb6fcf

📥 Commits

Reviewing files that changed from the base of the PR and between 4538230 and 2f0c1c4.

📒 Files selected for processing (2)
  • docker/keycloak/desired-clients.json
  • scripts/tests/test_keycloak_desired_clients_contract.py

@daniyalabbas96
daniyalabbas96 force-pushed the daniyal/omn-15877-keycloak-client-contract branch from 2f0c1c4 to b4e9b1b Compare August 12, 2026 09:27
@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

✅ Hostile Reviewer — PASSED

Blocking findings (critical): 0
Total findings: 0
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics (pilot phase)

Verdict Meaning Blocks merge?
passed No critical findings No
blocked CRITICAL findings found Yes
degraded All models unavailable (infra) No (pilot)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8468/OMN-8524)

@daniyalabbas96 daniyalabbas96 changed the title feat(OMN-15877): add OmniWeb gateway token claims feat(OMN-15877): add OmniWeb principal identity claim Aug 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/tests/test_keycloak_desired_clients_contract.py`:
- Around line 36-42: Extend the principal mapper assertions in the contract test
to validate that config["jsonType.label"] is set to "String", alongside the
existing principal_id mapper checks. Use the existing principal config object
and preserve all current assertions.
- Around line 44-49: Add a positive contract in the relevant Keycloak
desired-configuration test setup for the short-lived user token to include the
gateway-attach audience, then assert that source is present in the generated
configuration. Keep the existing gateway-attach mapper absence and
included.custom.audience checks unchanged as duplicate-prevention guards.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9cf4083e-22c6-4200-9126-174aebd7b632

📥 Commits

Reviewing files that changed from the base of the PR and between 2f0c1c4 and 55a672e.

📒 Files selected for processing (2)
  • docker/keycloak/desired-clients.json
  • scripts/tests/test_keycloak_desired_clients_contract.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker/keycloak/desired-clients.json

Comment on lines +36 to +42
principal = mappers["principal_id"]
assert principal["protocolMapper"] == "oidc-usermodel-attribute-mapper"
assert principal["config"]["user.attribute"] == "principal_id"
assert principal["config"]["claim.name"] == "principal_id"
assert principal["config"]["id.token.claim"] == "true"
assert principal["config"]["access.token.claim"] == "true"
assert principal["config"]["userinfo.token.claim"] == "true"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Assert the configured JSON type.

docker/keycloak/desired-clients.json Lines 54-63 set config["jsonType.label"] to "String", but this contract does not check it. Add the assertion so a non-string principal_id claim cannot pass the test.

Proposed assertion
     assert principal["config"]["userinfo.token.claim"] == "true"
+    assert principal["config"]["jsonType.label"] == "String"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
principal = mappers["principal_id"]
assert principal["protocolMapper"] == "oidc-usermodel-attribute-mapper"
assert principal["config"]["user.attribute"] == "principal_id"
assert principal["config"]["claim.name"] == "principal_id"
assert principal["config"]["id.token.claim"] == "true"
assert principal["config"]["access.token.claim"] == "true"
assert principal["config"]["userinfo.token.claim"] == "true"
principal = mappers["principal_id"]
assert principal["protocolMapper"] == "oidc-usermodel-attribute-mapper"
assert principal["config"]["user.attribute"] == "principal_id"
assert principal["config"]["claim.name"] == "principal_id"
assert principal["config"]["id.token.claim"] == "true"
assert principal["config"]["access.token.claim"] == "true"
assert principal["config"]["userinfo.token.claim"] == "true"
assert principal["config"]["jsonType.label"] == "String"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test_keycloak_desired_clients_contract.py` around lines 36 -
42, Extend the principal mapper assertions in the contract test to validate that
config["jsonType.label"] is set to "String", alongside the existing principal_id
mapper checks. Use the existing principal config object and preserve all current
assertions.

Comment on lines +44 to +49
assert "gateway-attach-audience" not in mappers
assert all(
mapper.get("config", {}).get("included.custom.audience")
!= "gateway-attach"
for mapper in mappers.values()
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 8 \
  '"gateway-attach"|gateway-attach-audience|included.custom.audience' \
  docker/keycloak/desired-clients.json \
  scripts/tests/test_keycloak_desired_clients_contract.py

Repository: OmniNode-ai/omnibase_infra

Length of output: 1630


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- test file ---'
cat -n scripts/tests/test_keycloak_desired_clients_contract.py

printf '%s\n' '--- relevant Keycloak declarations ---'
rg -n -C 12 \
  'gateway-attach|omniweb|clientScopes|clientScope|protocolMappers|audience' \
  docker scripts \
  -g '*.json' -g '*.py' -g '*.sh'

printf '%s\n' '--- repository-wide references ---'
rg -n -C 5 'gateway-attach|gateway-attach-audience' .

Repository: OmniNode-ai/omnibase_infra

Length of output: 50382


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

path = Path("docker/keycloak/desired-clients.json")
config = json.loads(path.read_text())

print("top-level keys:", sorted(config))
print("client scopes:")
for scope in config.get("clientScopes", []):
    print(json.dumps({
        "name": scope.get("name"),
        "protocol": scope.get("protocol"),
        "mappers": scope.get("protocolMappers", []),
    }, sort_keys=True))

print("clients:")
for client in config.get("clients", []):
    if client.get("clientId") == "omniweb":
        print(json.dumps({
            "clientId": client.get("clientId"),
            "defaultClientScopes": client.get("defaultClientScopes", []),
            "optionalClientScopes": client.get("optionalClientScopes", []),
            "protocolMappers": client.get("protocolMappers", []),
        }, indent=2, sort_keys=True))
PY

printf '%s\n' '--- exact gateway references in configuration and tests ---'
rg -n 'gateway-attach|gateway-attach-audience' \
  docker/keycloak/desired-clients.json \
  scripts/tests/test_keycloak_desired_clients_contract.py \
  scripts/tests/test_seed_keycloak_clients.py || true

printf '%s\n' '--- focused diff ---'
git diff --stat -- scripts/tests/test_keycloak_desired_clients_contract.py docker/keycloak/desired-clients.json
git diff -- scripts/tests/test_keycloak_desired_clients_contract.py docker/keycloak/desired-clients.json

Repository: OmniNode-ai/omnibase_infra

Length of output: 2032


Add a positive gateway-attach audience contract.

The desired configuration defines no gateway-attach mapper or client scope, so this test can pass while the short-lived user token lacks the required audience. Add the positive source and assert it here. Retain these checks as duplicate-prevention guards.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tests/test_keycloak_desired_clients_contract.py` around lines 44 -
49, Add a positive contract in the relevant Keycloak desired-configuration test
setup for the short-lived user token to include the gateway-attach audience,
then assert that source is present in the generated configuration. Keep the
existing gateway-attach mapper absence and included.custom.audience checks
unchanged as duplicate-prevention guards.

jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Aug 13, 2026
#6377)

* evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#2726

* evidence: OCC companion self-bind for #6377

---------

Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
@jonahgabriel
jonahgabriel merged commit a6d52de into dev Aug 13, 2026
221 of 295 checks passed
@jonahgabriel
jonahgabriel deleted the daniyal/omn-15877-keycloak-client-contract branch August 13, 2026 09:20
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.

3 participants