Skip to content

Integration test: jwt-bearer two-VP token request payload (4078-4)#4229

Draft
stevenvegt wants to merge 4 commits intofeature/4078-jwt-bearer-two-vpfrom
4078-4-integration-test
Draft

Integration test: jwt-bearer two-VP token request payload (4078-4)#4229
stevenvegt wants to merge 4 commits intofeature/4078-jwt-bearer-two-vpfrom
4078-4-integration-test

Conversation

@stevenvegt
Copy link
Copy Markdown
Member

Parent PRD

#4078

Implementation Spec

Integration safety net. Asserts the full client-side flow produces a PSA 10.10.6-conformant token request and that both VPs verify cleanly through the existing VCR verifyVP API.

What to build

In-process Go integration test (under auth/api/iam/ — extend or add alongside the existing integration_test.go). No docker-compose; that's reserved for cross-node workflows.

Test setup

  1. Spin up a single Nuts node test instance with the experimental feature flag enabled.
  2. Pre-provision two subjects in its wallet:
    • HCP subject with credentials matching the organization PD (e.g. HealthcareProviderCredential).
    • SP subject with a ServiceProviderDelegationCredential whose issuer is one of the HCP subject's DIDs.
  3. Configure the policy with a medication-overview profile that has both organization and client PDs, sharing a delegating_hcp field id on $.issuer.
  4. Stand up an httptest.Server mock AS that:
    • Serves oauth-authorization-server metadata advertising urn:ietf:params:oauth:grant-type:jwt-bearer in grant_types_supported.
    • Captures the form POST body received on the token endpoint.
    • Returns a canned valid token response so the client doesn't error.

Positive path assertions

  • Call POST /internal/auth/v2/{HCP-subjectID}/request-service-access-token with body containing client_id, authorization_server (mock AS URL), and a mixed scope.
  • Inspect the captured form POST body:
    • grant_type equals urn:ietf:params:oauth:grant-type:jwt-bearer.
    • client_assertion_type equals urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
    • scope matches what was requested.
    • assertion and client_assertion are both present and non-empty.
    • No presentation_submission form parameter is present.
  • Submit the captured assertion JWT-VP to the same node's POST /internal/vcr/v2/verifier/vp and assert validity: true. Inspect the verified credentials — VP1 must contain the expected HCP credentials and be signed by the HCP DID.
  • Submit the captured client_assertion JWT-VP the same way. VP2 must contain the delegation credential, be signed by the SP DID, and the delegation's issuer must equal the HCP DID that signed VP1 (cross-VP binding verified end-to-end).

Negative path assertions

  • Same setup but mock AS metadata omits jwt-bearer from grant_types_supported → API call returns 400 with a clear error.
  • Same setup but no client PD configured for the requested profile → API call returns 400.
  • Feature flag disabled + client_id present → API call returns 400 (feature disabled).

Modules touched

  • auth/api/iam/integration_test.go (or a new sibling test file for the jwt-bearer flow).
  • Possibly test fixture policies and credentials under test/ or alongside.

Why no docker e2e

PSA 10.10.6 server-side support is out of scope for #4078 (separate PRD). There is no second Nuts node that can receive and validate the request. A mock AS via httptest is the appropriate level — the test verifies wire format and round-trips both VPs through the same node's verifyVP for proof validation.

Acceptance Criteria

  • Integration test exists and runs as part of the standard test suite (no docker, no extra setup).
  • Positive path: form body matches PSA 10.10.6 wire format; both VPs verify via verifyVP; cross-VP binding holds end-to-end.
  • Negative paths covered: AS unsupported, no client PD, feature flag disabled.
  • Test runs reliably (no flakes, no external network dependencies).

@qltysh
Copy link
Copy Markdown

qltysh Bot commented May 1, 2026

Qlty


Coverage Impact

⬇️ Merging this pull request will decrease total coverage on feature/4078-jwt-bearer-two-vp by 0.03%.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

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.

1 participant