Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6583675
ci: bump platform action SHA and enable dpop-nonce-challenge
dmihalcik-virtru Jun 15, 2026
c579df3
fix(js-shim): wire CLIENTID, CLIENTSECRET, and DPoP into cli.sh
dmihalcik-virtru Jun 16, 2026
6141d7d
fix(ci): pass OTDFCTL_HEADS to all pytest steps so otdfctl.sh uses di…
dmihalcik-virtru Jun 16, 2026
b05e397
ci: bump platform action SHA to pick up DPoP htu fix
dmihalcik-virtru Jun 16, 2026
c23d467
ci: bump platform action SHA to pick up strict_htu feature flag
dmihalcik-virtru Jun 16, 2026
f55e25d
feat(java-sdk): delegate dpop_nonce_challenge detection to binary
dmihalcik-virtru Jun 16, 2026
ccee061
fix(ci): correct SHA pin for platform action (24d7101c094b)
dmihalcik-virtru Jun 16, 2026
d47082e
fix(java-cli): enable --verbose when available for silent failure dia…
dmihalcik-virtru Jun 16, 2026
154f9ea
fix(java-cli): check root help for --verbose (it is ScopeType.INHERIT…
dmihalcik-virtru Jun 16, 2026
140ac4a
fix(ci): update platform action SHA pins to 70cb173a (fix DPoP htm va…
dmihalcik-virtru Jun 17, 2026
a44acfe
Cache java cli.sh help probes to cut JVM startup overhead
dmihalcik-virtru Jun 18, 2026
4d9e3f7
Address PR review: atomic cache write, [[ ]] tests, redact auth secret
dmihalcik-virtru Jun 18, 2026
9dd5f37
fix(ci): remove duplicate OTDFCTL_HEADS env key in xtest.yml
dmihalcik-virtru Jun 24, 2026
14d2361
ci(dpop): enforce require_nonce on additional KAS instances
dmihalcik-virtru Jun 24, 2026
a5b5508
ci(dpop): repin platform test actions to 4a19b297; make bearer test n…
dmihalcik-virtru Jun 25, 2026
424aed9
ci(dpop): repin platform test actions to 8ccc608d (enforce now opt-in)
dmihalcik-virtru Jun 25, 2026
7bd3ad1
test(dpop): entitle opentdf-dpop client in shared subject condition s…
dmihalcik Jun 26, 2026
0c79f1d
chore: repin platform actions to main (0612ea89)
dmihalcik-virtru Jun 30, 2026
8bc50ae
xtest: add dpop-challenge boolean input, default false
dmihalcik-virtru Jul 1, 2026
3d52c49
xtest: fix dpop-challenge empty string on PR trigger
dmihalcik-virtru Jul 1, 2026
226304f
style(js/cli): use [[ ]] for all conditionals (SonarCloud SC2292)
dmihalcik-virtru Jul 1, 2026
fe2c2f7
style(cli): clear SonarCloud smells in js/java shims
dmihalcik-virtru Jul 1, 2026
d3d8582
Merge branch 'main' into fix-dpop-nonce-challenge
dmihalcik-virtru Jul 1, 2026
5f82820
fix(xtest): use $2 (feature name) not $1 ("supports") in dpop probe
dmihalcik-virtru Jul 10, 2026
faa23e9
Merge branch 'main' into fix-dpop-nonce-challenge
dmihalcik-virtru Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions .github/workflows/xtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
type: string
default: all
description: "SDK to focus on (go, js, java, all)"
dpop-challenge:
required: false
type: boolean
default: false
description: "Enable DPoP nonce challenge on KAS instances"
workflow_call:
inputs:
platform-ref:
Expand All @@ -50,6 +55,10 @@ on:
required: false
type: string
default: all
dpop-challenge:
Comment thread
dmihalcik-virtru marked this conversation as resolved.
required: false
type: boolean
default: false
schedule:
- cron: "30 6 * * *" # 0630 UTC
- cron: "0 5 * * 1,3" # 500 UTC (Monday, Wednesday)
Expand Down Expand Up @@ -297,13 +306,14 @@ jobs:
######## SPIN UP PLATFORM BACKEND #############
- name: Check out and start up platform with deps/containers
id: run-platform
uses: opentdf/platform/test/start-up-with-containers@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-up-with-containers@0612ea897264e3c621ce076029a5e1e3f2d3971e # main
with:
platform-ref: ${{ fromJSON(needs.resolve-versions.outputs.platform-tag-to-sha)[matrix.platform-tag] }}
ec-tdf-enabled: true
extra-keys: ${{ steps.load-extra-keys.outputs.EXTRA_KEYS }}
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
Expand Down Expand Up @@ -591,55 +601,59 @@ jobs:
- name: Start additional kas
id: kas-alpha
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
kas-name: alpha
kas-port: 8181
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Start additional kas
id: kas-beta
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
kas-name: beta
kas-port: 8282
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Start additional kas
id: kas-gamma
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
kas-name: gamma
kas-port: 8383
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Start additional kas
id: kas-delta
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
kas-port: 8484
kas-name: delta
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Start additional KM kas (km1)
id: kas-km1
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
key-management: ${{ steps.km-check.outputs.supported }}
Expand All @@ -648,11 +662,12 @@ jobs:
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Start additional KM kas (km2)
id: kas-km2
if: ${{ steps.multikas.outputs.supported == 'true' }}
uses: opentdf/platform/test/start-additional-kas@11af44a5d4826ed281bf2e0e4e31d6ff6154b393 # pqc-enabled
uses: opentdf/platform/test/start-additional-kas@0612ea897264e3c621ce076029a5e1e3f2d3971e # main: require_nonce on additional KAS
with:
ec-tdf-enabled: true
kas-name: km2
Expand All @@ -661,6 +676,7 @@ jobs:
log-type: json
pqc-enabled: ${{ steps.pqc-check.outputs.supported == 'true' }}
root-key: ${{ steps.km-check.outputs.root_key }}
dpop-challenge-enabled: ${{ inputs.dpop-challenge || false }}

- name: Run attribute based configuration tests
if: ${{ steps.multikas.outputs.supported == 'true' }}
Expand Down
9 changes: 7 additions & 2 deletions xtest/fixtures/obligations.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
def otdf_client_scs(otdfctl: OpentdfCommandLineTool) -> abac.SubjectConditionSet:
"""
Creates a standard subject condition set for OpenTDF clients.
This condition set matches client IDs 'opentdf' or 'opentdf-sdk'.
This condition set matches client IDs 'opentdf', 'opentdf-sdk', or
'opentdf-dpop' (the DPoP-bound client used by the DPoP tests).

Returns:
abac.SubjectConditionSet: The created subject condition set
Expand All @@ -32,7 +33,11 @@ def otdf_client_scs(otdfctl: OpentdfCommandLineTool) -> abac.SubjectConditionSet
abac.Condition(
subject_external_selector_value=".clientId",
operator=abac.SubjectMappingOperatorEnum.IN,
subject_external_values=["opentdf", "opentdf-sdk"],
subject_external_values=[
"opentdf",
"opentdf-sdk",
"opentdf-dpop",
],
)
],
)
Expand Down
7 changes: 2 additions & 5 deletions xtest/sdk/go/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,9 @@ if [ "$1" == "supports" ]; then
exit $?
;;
dpop | dpop_nonce_challenge)
# DPoP support is signalled by the --dpop / --dpop-key flag on encrypt.
# The same probe covers nonce-challenge support: when nonce mode is
# required by the server, the SDK's existing 401-retry uses the same
# plumbing as the base DPoP path.
set -o pipefail
"${cmd[@]}" help encrypt | grep -iE -- '--dpop'
"${cmd[@]}" --version --json | jq -e --arg f "$2" '.supported_features |
index($f)'
exit $?
;;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
*)
Expand Down
34 changes: 31 additions & 3 deletions xtest/sdk/java/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ else
exit 1
fi

# Cache `java -jar cmdline.jar help [...]` output to avoid paying JVM startup
# (typically 150-500ms) for the capability probes on every encrypt/decrypt.
# Keyed by the jar's mtime so a reinstall invalidates the cache. stderr is
# discarded to keep JVM warnings (reflective-access, agent notices) out of logs.
jar_help() {
local jar="$SCRIPT_DIR/cmdline.jar"
local mtime
mtime=$(stat -c %Y "$jar" 2>/dev/null || stat -f %m "$jar" 2>/dev/null || echo 0)
local key
key=$(printf '%s' "$*" | tr -c 'a-zA-Z0-9' '_')
local uid
uid=$(id -u 2>/dev/null || echo default)
local cache="${TMPDIR:-/tmp}/xtest-java-help-${uid}-${mtime}-${key}"
if [[ ! -f "$cache" ]]; then
# Write to a process-unique temp file, then rename: concurrent xdist
# workers see either no cache or the complete file, never a partial read.
local tmp="${cache}.$$"
java -jar "$jar" help "$@" >"$tmp" 2>/dev/null
mv -f "$tmp" "$cache"
fi
cat "$cache"
return 0
}

if [ "$1" == "supports" ]; then
case "$2" in
autoconfigure | ns_grants)
Expand Down Expand Up @@ -118,8 +142,8 @@ if [ "$1" == "supports" ]; then
exit $?
;;
dpop_nonce_challenge)
echo "dpop_nonce_challenge not supported"
exit 1
java -jar "$SCRIPT_DIR"/cmdline.jar supports dpop_nonce_challenge
exit $?
;;
*)
echo "Unknown feature: $2"
Expand All @@ -135,7 +159,7 @@ args=(
)

# when we added support for KAS allowlist, we changed the platform endpoint format to require scheme
if java -jar "$SCRIPT_DIR"/cmdline.jar help decrypt | grep kas-allowlist; then
if jar_help decrypt | grep -q kas-allowlist; then
args+=("--platform-endpoint=$PLATFORMURL")
else
args+=("--platform-endpoint=$PLATFORMENDPOINT")
Expand Down Expand Up @@ -197,5 +221,9 @@ if [ -n "$XT_WITH_TARGET_MODE" ]; then
args+=(--with-target-mode "$XT_WITH_TARGET_MODE")
fi

if jar_help | grep -q -- '--verbose'; then
args+=(--verbose)
fi

echo java -jar "$SCRIPT_DIR"/cmdline.jar "${args[@]}" --file="$2" ">" "$3"
java -jar "$SCRIPT_DIR"/cmdline.jar "${args[@]}" --file="$2" >"$3"
Loading
Loading