Skip to content

feat(clients): add a closed OIDC RP claim mapper profile - #72

Open
seonghobae wants to merge 30 commits into
mainfrom
feat/oidc-rp-claim-profile
Open

feat(clients): add a closed OIDC RP claim mapper profile#72
seonghobae wants to merge 30 commits into
mainfrom
feat/oidc-rp-claim-profile

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible product gap

Keyverse can validate and reconcile secret-free relying-party metadata, but Naruon also requires one audience mapper and bounded role, org, and workspace claims. Without a reviewed runtime path for those mappers, Naruon remains coupled to an application client embedded in the portable realm and cannot be fully recovered from Keyverse desired state.

Implemented bounded slice

  • optional, bounded protocolMappers on the closed RP representation;
  • exactly one oidc-audience-mapper, pinned to the registration clientId;
  • optional hardcoded claims limited to role, org, and workspace;
  • canonical mapper names, nested fields, claim destinations, value bounds, and order;
  • rejection of scripts, user attributes, groups, regex, arbitrary claims, unknown fields, credential material, and unsupported mapper classes;
  • non-reflective hostile nested-input handling;
  • normalization of Keycloak-generated mapper IDs and return order before drift comparison;
  • runtime Naruon desired-state template at deploy/templates/oidc-rp-naruon.json;
  • architecture, onboarding, operations, CHANGELOG, and APA 7th doctoring updates;
  • preservation of zero DNS, HTTP, Keycloak, storage, file, or secret side effects during preflight;
  • preservation of secret-free desired state, post-mutation re-observation, duplicate fail-closed behavior, remote-first deletion, and canonical receipts.

TDD evidence

The first production-shaped Naruon mapper test failed with HTTP 422 because protocolMappers was not an allowed field. After implementation, CI exposed a response-regression where the endpoint omitted ready_to_apply; the result model contract was restored. Additional integration tests exercise the shipped runtime template, Keycloak-generated mapper IDs, mapper reordering, and semantic drift.

Standards and doctoring

The doctoring record separates OpenID Connect audience/claim semantics, RFC 9068 access-token audience guidance, RFC 8725 JWT validation guidance, current Keycloak ClientRepresentation / ProtocolMapperRepresentation behavior, stricter Keyverse policy, measured evidence, assumptions, and limitations. References use APA 7th style; no formal conformance claim is made.

Protected completion

Merge requires locked installation, Ruff, Interrogate 100%, complete pytest, production statement and branch coverage 100%, package and deployment-template validation, exact-current-head CI, CodeQL, Semgrep, Security Scan, current-head independent review, zero unresolved review threads, and repository branch protection.

No self-approval, administrator bypass, version bump, tag, release, COPILOT_GITHUB_TOKEN, or review-agent credential change is included. Controlled authorization-code/PKCE login and downstream authorization acceptance remain separate evidence boundaries.

Closes #70
Tracks #2.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e5887f33-0857-4cf4-b8f9-bc78cc2c55d6

📥 Commits

Reviewing files that changed from the base of the PR and between c8968ec and 91a3a71.

📒 Files selected for processing (18)
  • .github/workflows/ci.yml
  • AGENTS.md
  • ARCHITECTURE.md
  • CHANGELOG.md
  • CLAUDE.md
  • deploy/templates/README.md
  • deploy/templates/oidc-rp-naruon.json
  • docs/doctoring/oidc-rp-claim-mapper-profile.md
  • docs/operations/oidc-rp-reconciliation.md
  • docs/rp-onboarding.md
  • docs/superpowers/plans/2026-08-07-keyverse-oidc-rp-claim-profile.md
  • docs/superpowers/specs/2026-08-07-keyverse-oidc-rp-claim-profile-design.md
  • services/account_unification/app/relying_party.py
  • services/account_unification/app/relying_party_state.py
  • services/account_unification/tests/test_relying_party_claim_mappers.py
  • services/account_unification/tests/test_relying_party_endpoint_policy.py
  • services/account_unification/tests/test_relying_party_mapper_reconciliation.py
  • services/account_unification/tests/test_relying_party_template.py

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

Comment thread .github/workflows/one-shot-fix-rp-endpoint-policy.yml Fixed
@seonghobae
seonghobae marked this pull request as ready for review August 7, 2026 11:11

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review the exact current head. Focus on the closed mapper allowlist, self-pinned audience, non-reflective nested parsing, canonical mapper ordering, Keycloak-generated mapper-ID normalization, semantic drift detection, secret non-observability, and standalone/CWL/Naruon module boundaries.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

@seonghobae I will review the exact current head of #72. I will focus on the specified mapper, normalization, drift, secret, and module-boundary controls.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae enabled auto-merge (squash) August 7, 2026 11:14
@seonghobae seonghobae closed this Aug 8, 2026
auto-merge was automatically disabled August 8, 2026 15:09

Pull request was closed

@seonghobae seonghobae reopened this Aug 8, 2026
@seonghobae
seonghobae marked this pull request as draft August 8, 2026 15:11
@seonghobae
seonghobae marked this pull request as ready for review August 8, 2026 15:28

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review

Review-only request for exact current head 91a3a7190a589ac82615e283886681c0e04ece03 against protected base c8968ec1e68fab16d0ad8216fb5c8fd0b385e95f. Do not mutate the branch or merge. The historical action_required/zero-job evidence belongs to predecessor heads; current exact-head CI 31264473283, CodeQL 31264473318, SAST 31264473281, and Security Scan 31264473328 are successful, the only GHAS inline finding is resolved/outdated, and CodeRabbit exact-current-head review delivery is temporarily rate-limited while its commit status is successful. Independently review the closed OIDC relying-party claim-mapper profile: exact one audience mapper pinned to clientId, bounded role/org/workspace hardcoded claims, strict mapper/config closure, canonical order, hostile nested-input rejection, Keycloak-generated mapper-ID/order normalization, secret-free desired state and templates, and no regression to preflight side-effect boundaries. Submit a formal non-author GitHub review for this exact head; do not treat advisory statuses/checks as approval.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review exact current head 91a3a7190a589ac82615e283886681c0e04ece03 against protected base c8968ec1e68fab16d0ad8216fb5c8fd0b385e95f. Re-evaluate the complete current diff rather than predecessor-head or prior rate-limit evidence. Focus on the closed protocol-mapper shape, exact audience binding, bounded hardcoded claim allowlist, Keycloak live mapper normalization, drift detection, secret non-observability, hostile nested input, and current tests/docs. Do not infer approval from commit status alone.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Your plan includes PR reviews subject to rate limits. More reviews will be available in 5 minutes.

@opencode-agent opencode-agent 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.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 91a3a7190a589ac82615e283886681c0e04ece03.

  • Head SHA: 91a3a7190a589ac82615e283886681c0e04ece03

  • Workflow run: 31268556874

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: ci.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: ci.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Changed file (8 files)"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Changed file (8 files)"]
  R2 --> V2["required checks"]
  Evidence --> S3["Docs (5 files)"]
  S3 --> I3["operator or user guidance"]
  I3 --> R3["Review risk: Docs (5 files)"]
  R3 --> V3["docs review"]
  Evidence --> S4["Test (4 files)"]
  S4 --> I4["regression suite"]
  I4 --> R4["Review risk: Test (4 files)"]
  R4 --> V4["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 91a3a7190a589ac82615e283886681c0e04ece03
  • Workflow run: 31268556874
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 91a3a7190a589ac82615e283886681c0e04ece03.

  • Head SHA: 91a3a7190a589ac82615e283886681c0e04ece03

  • Workflow run: 31268556874

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: ci.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: ci.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Changed file (8 files)"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Changed file (8 files)"]
  R2 --> V2["required checks"]
  Evidence --> S3["Docs (5 files)"]
  S3 --> I3["operator or user guidance"]
  I3 --> R3["Review risk: Docs (5 files)"]
  R3 --> V3["docs review"]
  Evidence --> S4["Test (4 files)"]
  S4 --> I4["regression suite"]
  I4 --> R4["Review risk: Test (4 files)"]
  R4 --> V4["targeted test run"]
Loading

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.

feat(clients): reconcile a closed OIDC audience and session-claim mapper profile

2 participants