Skip to content

chore(ci): update e2e test environments to Keycloak 26.4 - #3792

Merged
dmihalcik-virtru merged 1 commit into
mainfrom
DSPX-4190
Jul 29, 2026
Merged

chore(ci): update e2e test environments to Keycloak 26.4#3792
dmihalcik-virtru merged 1 commit into
mainfrom
DSPX-4190

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary

Updates all test/CI/e2e Keycloak targets to 26.4+. The runtime image (ghcr.io/opentdf/keycloak-standard:26.4.0) was already at 26.4; this cleans up the remaining stale/orphaned targets.

Fixes DSPX-4190

Changes

  • Keytool image 25.0 → 26.4 in .github/scripts/init-temp-keys.sh and init-temp-keys.cmd (used only as a keytool entrypoint to build the truststore).
  • Retire the orphaned custom image: the cert-exchange OAuth test was the sole user of the SHA-pinned ghcr.io/opentdf/keycloak:sha-8a6d35a (no semver tag, no public source repo). Repointed setupCustomKeycloakForCertExchange at keycloak-standard:26.4.0, dropped the redundant legacy KEYCLOAK_ADMIN* env vars, and switched its readiness probe from wait.ForLog("Running the server") to an HTTP check — on 26.4 that log line is printed before the HTTP connector accepts connections, which raced the admin login (EOF).
  • Enable DPoP explicitly via KC_FEATURES: dpop in docker-compose.yaml (covers the start-up-with-containers action + BDD suite transitively) and in the OAuth + ERS test containers. DPoP is supported/default-on in 26.4; set explicitly for robustness. The opentdf-dpop client attribute is unchanged.
  • start-up-with-containers action: new bootstrap-ref input. The action overlays docker-compose.yaml / init-temp-keys.sh / watch.sh by fetching them from a hardcoded pqc-enabled tag (independent of platform-ref). Added a bootstrap-ref input (default pqc-enabled, so existing behavior is unchanged) so those bootstrap files can be pulled from any branch/tag/SHA — letting downstream e2e workflows test infra changes like this one from a PR branch before the tag is moved.

Testing

Run against keycloak-standard:26.4.0 (local Docker):

  • TestOAuthTestSuite — pass, including both DPoP tests and standard token exchange.
  • TestCertExchangeTestSuite — pass; X.509 cert-exchange flow works on the standard image (validates dropping the custom image).
  • service/entityresolution/integration/... — pass with the DPoP env addition.
  • make fmt / gofmt clean; remaining lint findings are pre-existing and unrelated.

To exercise cross-repo e2e workflows on this branch, reference the action at this branch and set both refs:

uses: opentdf/platform/test/start-up-with-containers@DSPX-4190
with:
  bootstrap-ref: DSPX-4190   # pull docker-compose.yaml + init-temp-keys.sh (26.4 + dpop) from this branch
  platform-ref: DSPX-4190    # optional: use branch service code too

Notes

  • gocloak was not bumped — v13.9.0 works fine against 26.4 across all suites.
  • Follow-up DSPX-4191 tracks migrating the legacy Python KAS / virtru-corp consumers off the custom tdf_claims mapper so the custom image can be fully retired.

Summary by CodeRabbit

  • New Features

    • Enabled Demonstration of Proof-of-Possession (DPoP) support for Keycloak-based authentication.
    • Added configurable bootstrap sources, allowing startup files to be selected from approved release tracks.
  • Bug Fixes

    • Updated Keycloak tooling and container configuration to version 26.4 for improved compatibility.
    • Improved integration-test startup checks by validating OpenID configuration availability rather than relying on log messages.

@dmihalcik-virtru
dmihalcik-virtru requested review from a team as code owners July 27, 2026 20:24
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@github-actions github-actions Bot added comp:ci Github Actions Work size/xs labels Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Keycloak tooling now uses version 26.4, and runtime and integration containers enable DPoP. OAuth tests use the standard image and OpenID configuration readiness checks. The startup action accepts and validates an allowlisted bootstrap reference for downloads.

Changes

Keycloak configuration and OAuth integration

Layer / File(s) Summary
Keycloak runtime configuration
.github/scripts/init-temp-keys.*, docker-compose.yaml
Keytool initialization uses Keycloak 26.4, and the Compose Keycloak service enables DPoP.
Integration container feature configuration
service/entityresolution/integration/keycloak_test.go
The entity resolution test container enables the dpop feature.
OAuth test container and readiness flow
test/integration/oauth/oauth_test.go
OAuth setups use the standard Keycloak image, enable DPoP, and wait for a successful OpenID configuration response.

Configurable startup bootstrap

Layer / File(s) Summary
Bootstrap reference validation and downloads
test/start-up-with-containers/action.yaml
The action adds bootstrap-ref, restricts it to main or pqc-enabled, and uses the selected reference when downloading bootstrap files.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • opentdf/platform#3754: Updates OAuth integration Keycloak setup for DPoP on the standard Keycloak 26.4 container.

Suggested reviewers: jrschumacher, sujankota

Poem

A bunny hops through keys renewed,
With DPoP flags in place,
Keycloak starts on twenty-six-four,
While bootstrap paths change pace.
Tests wait for OpenID’s face.

🚥 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 matches the main change: updating test and CI Keycloak environments to 26.4.
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 DSPX-4190

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.

@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 213.616496ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 119.36404ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 417.86368ms
Throughput 239.31 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 48.966333604s
Average Latency 487.54526ms
Throughput 102.11 requests/second

@dmihalcik-virtru dmihalcik-virtru changed the title chore(keycloak): update e2e test environments to Keycloak 26.4 chore(ci): update e2e test environments to Keycloak 26.4 Jul 27, 2026
@dmihalcik-virtru
dmihalcik-virtru requested a review from Copilot July 27, 2026 20:33

Copilot AI 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

Updates the repo’s CI/e2e/integration Keycloak targets to align on Keycloak 26.4 (matching the already-upgraded runtime image), removing reliance on an orphaned SHA-pinned custom image and making DPoP enablement explicit for test environments.

Changes:

  • Switched the cert-exchange OAuth integration test Keycloak container from a SHA-pinned custom image to ghcr.io/opentdf/keycloak-standard:26.4.0, and replaced log-based readiness with an HTTP readiness check.
  • Enabled DPoP explicitly via KC_FEATURES=dpop across docker-compose, OAuth integration tests, and ERS Keycloak integration tests.
  • Updated the temporary truststore/keytool helper scripts to use keycloak/keycloak:26.4.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/integration/oauth/oauth_test.go Unifies Keycloak image usage, adds explicit DPoP feature enablement, and improves container readiness checks to reduce test flakiness.
service/entityresolution/integration/keycloak_test.go Enables DPoP feature flag in the ERS integration Keycloak container env for consistency with 26.4 behavior.
docker-compose.yaml Sets KC_FEATURES: dpop so local/dev and container-based test flows consistently run with DPoP enabled.
.github/scripts/init-temp-keys.sh Updates the keytool container image tag used to build the truststore to Keycloak 26.4.
.github/scripts/init-temp-keys.cmd Windows equivalent update of the keytool container image tag to Keycloak 26.4.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dmihalcik-virtru
dmihalcik-virtru force-pushed the DSPX-4190 branch 3 times, most recently from abc403f to d1081e9 Compare July 27, 2026 20:49
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 192.216039ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 106.927649ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 428.208492ms
Throughput 233.53 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 48.795936138s
Average Latency 486.198032ms
Throughput 102.47 requests/second

@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 143.354255ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 80.783578ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 288.523857ms
Throughput 346.59 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 37.145537195s
Average Latency 370.219401ms
Throughput 134.61 requests/second

@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 214.619403ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 112.067231ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 421.26153ms
Throughput 237.38 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 51.339788962s
Average Latency 511.225438ms
Throughput 97.39 requests/second

elizabethhealy
elizabethhealy previously approved these changes Jul 28, 2026
- Bump keytool image keycloak/keycloak:25.0 -> 26.4 in init-temp-keys.{sh,cmd}
- Consolidate the cert-exchange OAuth test onto keycloak-standard:26.4.0,
  removing the orphaned SHA-pinned custom image (ghcr.io/opentdf/keycloak);
  switch its readiness probe to an HTTP check to avoid a 26.4 startup race
- Enable DPoP feature (KC_FEATURES: dpop) across docker-compose and the
  OAuth/ERS test containers (DPoP is supported/default-on in 26.4; set
  explicitly for robustness)
- Add a 'bootstrap-ref' input to the start-up-with-containers composite action
  so the docker-compose.yaml / init-temp-keys.sh / watch.sh bootstrap files can
  be fetched from an allowlisted ref (main, pqc-enabled, or DSPX-4190; default
  unchanged: pqc-enabled). These files are executed, so the input is restricted
  to a vetted allowlist rather than an arbitrary branch/tag.

Fixes DSPX-4190

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru

Copy link
Copy Markdown
Member Author

@elizabethhealy I removed allowing workflow runs against the DSPX-4190 (this) branch, so it needs a re-stamp

@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: 1

🤖 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 `@test/start-up-with-containers/action.yaml`:
- Around line 10-17: Update the bootstrap reference handling used by the
workflow’s three downloads to resolve the approved main and pqc-enabled refs to
reviewed immutable commit SHAs before constructing URLs. Use the resolved SHA
consistently for docker-compose.yaml, init-temp-keys.sh, and watch.sh,
preserving the existing allowlist and default behavior while preventing mixed
revisions.
🪄 Autofix (Beta)

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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 037b2b5b-ed5f-47b9-b6ff-e377a4ec698c

📥 Commits

Reviewing files that changed from the base of the PR and between 9a9318e and 8905606.

📒 Files selected for processing (6)
  • .github/scripts/init-temp-keys.cmd
  • .github/scripts/init-temp-keys.sh
  • docker-compose.yaml
  • service/entityresolution/integration/keycloak_test.go
  • test/integration/oauth/oauth_test.go
  • test/start-up-with-containers/action.yaml

Comment thread test/start-up-with-containers/action.yaml
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 165.476863ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 93.112295ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 418.094199ms
Throughput 239.18 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 50.394062752s
Average Latency 502.306186ms
Throughput 99.22 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

@dmihalcik-virtru
dmihalcik-virtru added this pull request to the merge queue Jul 29, 2026
Merged via the queue into main with commit 18b8070 Jul 29, 2026
46 checks passed
@dmihalcik-virtru
dmihalcik-virtru deleted the DSPX-4190 branch July 29, 2026 15:21
dmihalcik-virtru added a commit to opentdf/tests that referenced this pull request Aug 6, 2026
)

## What

Bump the `start-up-with-containers` pin to `18b8070f`
(opentdf/platform#3792) and pass `bootstrap-ref: main` on the `main`
platform lane only.

## Why

The action overlays `docker-compose.yaml` from `bootstrap-ref`,
**independent of `platform-ref`**. That input defaults to the
`pqc-enabled` tag, which is still pinned to `keycloak/keycloak:25.0` — a
Keycloak that cannot issue DPoP-bound access tokens. So every lane ran
KC 25 even though platform `main`'s own compose has been
`ghcr.io/opentdf/keycloak-standard:26.4.0` with `KC_FEATURES: dpop`
since #3792, and `service/cmd/keycloak_data.yaml` provisions
`opentdf-dpop` with `dpop.bound.access.tokens: "true"`.

The visible symptom: `test_dpop.py::test_dpop_happy_path_roundtrip`
fails for any SDK that checks token binding. The token comes back
`typ=Bearer` with no `cnf.jkt`, and the js CLI rejects it:

```
[CRITICAL] DPoP requested but the access token is not bound (missing cnf.jkt)
```

go and java pass only because they don't assert `cnf.jkt`. The other
`test_dpop.py` cases already self-skip on `token_type != DPoP`; the
SDK-level roundtrips gate on the platform well-known and SDK features,
not on IdP capability, so they run and fail. This is what keeps
opentdf/web-sdk#939 red.

Released platform tags keep the 25.0 bootstrap — they predate the move
to standard Keycloak token exchange (opentdf/platform#3754).

## Testing

Dispatched against this branch with `platform-ref=main`,
`js-ref=refs/pull/939/merge`, `focus-sdk=js` —
https://github.com/opentdf/tests/actions/runs/31016132383 — all three
lanes green (`go@main`, `java@main`, `js@pull-939`).

Confirmed Keycloak 26.4 came up, and these ran rather than skipped:

```
PASSED test_dpop.py::test_dpop_happy_path_roundtrip[small-js@pull-939-js@pull-939-in_focus0]
PASSED test_dpop.py::test_dpop_happy_path_roundtrip[small-js@pull-939-java@main-in_focus0]
PASSED test_dpop.py::test_dpop_rejects_replayed_jti[small-js@pull-939-in_focus0]
PASSED test_dpop.py::test_dpop_rejects_tampered_proof_htu[small-js@pull-939-in_focus0]
PASSED test_dpop.py::test_dpop_bearer_scheme_warns_but_accepted_for_dpop_token[small-js@pull-939-in_focus0]
```

The nonce-dependent cases still skip, correctly — `dpop-challenge` is
off by default, so `require_nonce` is unset.

## Notes

- The new action's input set is a strict superset of the old pin's; no
call-site changes beyond `bootstrap-ref`.
- `start-additional-kas` is left at `6dd5f649` — it downloads no
compose.
- Overlaps #568 (DSPX-4190), which took the broader
approach of moving every lane to 26.4 via a platform PR branch. This is
the narrow slice needed now; #568's remaining checklist (re-point the
`pqc-enabled` tag, align `vulnerability.yml`) still stands.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated platform startup workflows to use the Keycloak 26.4 revision.
* Adjusted bootstrap selection so the main platform lane uses the main
configuration while released tags retain the PQC-enabled configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:ci Github Actions Work size/xs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants