Skip to content

oauth2 client: enforce token_endpoint_auth_method and remove or enforce require_pkce #1274

Open

Description

@gtema

Roadmap step 20 (M3). Audit finding F-B7 (P2).

Current state

OAuth2ClientResource (crates/core-types/src/oauth2_client/resource.rs) stores token_endpoint_auth_method (immutable after creation) and require_pkce, and both are exposed on the v4 API. Neither is read by any handler:

  • /token accepts HTTP Basic or body credentials for every client regardless of the registered method (crates/keystone/src/api/v4/oauth2/token.rs:247-266).
  • PKCE is unconditionally mandatory at /authorize (authorize.rs), so a client registered with require_pkce: false is misdescribed by its own record.

What must be done

  • token_endpoint_auth_method: validate at create time against the supported set (client_secret_basic, client_secret_post, none); reject none for a client with a secret and any secret-based method for a public client. At /token (all arms that call authenticate_client, plus client_credentials), reject with invalid_client when credentials arrive via a method other than the registered one (e.g. body credentials for a client_secret_basic client). Keep the Argon2 dummy-hash burn on the rejection path (enumeration posture, security-review V8a).
  • require_pkce: decision needed. Recommended: keep PKCE unconditional (ADR 0026 §1), drop the field from OAuth2ClientCreate/Update API types with a deprecation note in the v4 OpenAPI description, keep it in the stored resource as always-true for on-disk compatibility. Alternative: honour false for confidential clients only. Record the decision in ADR 0026 §5.
  • Add private_key_jwt to the roadmap as a follow-up (not in this issue) since machine identities with SPIFFE SVIDs are a natural fit.
  • Unit tests: client_secret_basic client presenting body credentials → invalid_client; none client presenting a secret → invalid_client.
  • Update the admin guide client-registration section and token_endpoint_auth_methods_supported in discovery (step 14).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions