Skip to content

[api-test] Per-client protocol switch coverage: PKCE, PAR and DPoP #2455

Open

Description

@nandhu-kumar

Parent: #2120

Covers the three per-client protocol switches eSignet enforces through additionalConfig —
require_pkce, require_pushed_authorization_requests and dpop_bound_access_tokens — enforced at
authorize, /oauth2/par, token and userinfo respectively. #2120 Phase 5+ listed "PAR/DPoP
(FAPI2) scenarios" as not delivered by #2357; this is that item.

Until now only the conformance surface reached these switches, and only for the client registrations
its FAPI2 plan happens to use. Neither the e2e nor the api surface touched them at all.

Scope

  • e2e (internal/e2e/protocol.go, internal/e2e/dpop.go) — a client registered per combination,
    driven through the flow that combination demands. Scenarios declare client_config (what the
    client requires) and optionally flow (what the relying party actually does); driving the two
    against each other is how a negative is expressed. 13 scenarios per plugin spec: 7 positive
    combinations through to userinfo, 6 negatives (no code_challenge, the plain method, a direct
    authorize against a PAR-required client, a token call with no proof, a proof from a different key
    than the one bound at PAR, and a DPoP-bound token presented as Bearer at userinfo).
  • Relying-party side of DPoP — proof generation (RFC 9449) over a key kept separate from the
    client's registration key, RFC 7638 thumbprints, the PAR pre-step, the DPoP scheme at userinfo
    with an ath binding, and the use_dpop_nonce retry at par, token and userinfo. The proof
    algorithm is negotiated from dpop_signing_alg_values_supported rather than fixed.
  • api (data/features/client-mgmt/additional-config.feature) — registration-side allowlisting
    and type checking of the same keys plus the update path, no login needed.
  • Docs: a Protocol combinations section in docs/e2e-scenarios.md.

Not in scope

Enforcement of an additionalConfig update (as opposed to registration). Verifying it needs a
login flow driven against a mutated client, which neither the api surface nor the current e2e
client pool can express — the pool registers each client with its config and shares it by config
key. Raised in review on #2448 and deferred.

Status

In progress — delivered in #2448, pending merge. All 13 scenarios pass against
esignet-thunder1.esdev on mock/sunbird, with the negatives refused for the specific rule each
one exists to prove (code_challenge is required for this application, Invalid code_challenge or code_challenge_method, no redirect issued, invalid_dpop_proof, DPoP proof key does not match authorization code binding, DPoP-bound token must use DPoP scheme). On mosipid the 10 positives
pass and the 3 negatives fail, for the reason in the caveat below — this is that plugin's known
limitation, not a regression.

mosipid caveat — CONFIRMED 2026-09-02, PMS drops it. With the mosip plugin, clients are
registered through PMS /oidc-clients, not eSignet client-mgmt. The harness sends
additionalConfig on that request; round-tripping a client through PMS and reading it back (GET /oidc/client/{id}) shows the field simply absent — no error, silently dropped. So on this plugin
the positives still pass (an unhardened client happily accepts a hardened flow) and the three
negatives fail, because there is nothing to refuse against. Confirmed live against esdev +
qajava21 PMS in #2190 (tracked in detail there and in #2448's Product gap #2); environment-side,
not an eSignet bug, and not fixable from the client-registration path PMS exposes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    End Date

    None yet

    Complexity

    None yet

    Start Date

    None yet

    Original Estimate

    None yet

    Time Tracking

    None yet

    Resolved By

    None yet

    Story Points

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions