Skip to content

fix(oauth): remove the implicit and password grants entirely#165

Merged
windischb merged 1 commit into
developfrom
fix/remove-implicit-password-grants
Jul 22, 2026
Merged

fix(oauth): remove the implicit and password grants entirely#165
windischb merged 1 commit into
developfrom
fix/remove-implicit-password-grants

Conversation

@windischb

Copy link
Copy Markdown
Contributor

Why

Follow-up to a question about OAuth 2.0 vs 2.1 conformance. The admin UI listed implicit and password as selectable grant types (marked deprecated), and the backend silently persisted them as gt:implicit / gt:password OpenIddict permissions on the client.

They never actually functioned — the server enables neither AllowImplicitFlow nor AllowPasswordFlow, so a real request is rejected at the token/authorize endpoint and discovery never advertises them. But two real problems remained:

  1. UX trap — an admin could select password, save with no error, and the client silently couldn't use it.
  2. Claim gap — the security-model doc says these are "deliberately rejected," but the code path that should reject them (client create/update) didn't; it stored the permission. Rejection happened only by omission at the token endpoint.

OAuth 2.1 removes both grants. This removes them for good, at every layer.

What changed

  • Frontend (ClientDetails.vue) — drop the two options from the grant-type picker; the whole "Deprecated" group goes with them.
  • Backend constants + mapping — remove the gt:implicit / gt:password constants and both mapping directions. A legacy client that somehow still carries the permission maps to null on read (dropped from the DTO, stripped on next save).
  • New guard OAuthAdminMapping.ValidateGrantTypes — any grant that doesn't map to a supported permission (implicit, password, or a typo) is now rejected with OAuth.UnsupportedGrantType on both create and update, instead of being silently dropped while building permissions. Rejection is now explicit and at config time, which makes the doc's "deliberately rejected" claim true at the config layer.

No seed or provisioning manifest used either grant (demo-seed's implicit is a consent type, not a grant).

Testing

  • Unit: ValidateGrantTypes accept/reject cases; the two removed grants now map to null.
  • Integration (OAuthGrantTypeAllowlistTests): drives the real OAuthAdminService and asserts create + update reject implicit/password with OAuth.UnsupportedGrantType, plus a positive control that the supported set still succeeds.
  • Unit 1402/1402, integration 537/538 — the one failure is the known last-dependent UserView catch-up flake (DcrRegistrationEndpointTests), green in isolation and logically unrelated to grant validation (it asserts the discovery document, not client creation).

🤖 Generated with Claude Code

The admin UI listed 'implicit' and 'password' as selectable grant types (marked
deprecated) and the backend silently persisted them as gt:implicit / gt:password
OpenIddict permissions on the client. They never actually worked — the server
enables neither AllowImplicitFlow nor AllowPasswordFlow, so any real request is
rejected at the token/authorize endpoint and discovery never advertises them —
but a client could be configured with them, and the security-model doc's
'deliberately rejected' claim was only true by omission at the endpoint, not at
config time.

OAuth 2.1 removes both grants. Remove them for good:

- Frontend: drop the two options from the client grant-type picker (the whole
  'Deprecated' group goes with them).
- Backend: remove the gt:implicit / gt:password constants and both mapping
  directions. A client that somehow still carries the permission maps to null on
  read (dropped from the DTO, stripped on next save).
- Add OAuthAdminMapping.ValidateGrantTypes: any grant that doesn't map to a
  permission — implicit, password, or a typo — is now rejected with
  OAuth.UnsupportedGrantType on both create and update, instead of being silently
  dropped while building permissions. The rejection is now explicit and at config
  time.

No seed or provisioning manifest used either grant (demo-seed's 'implicit' is a
consent type, not a grant).

Tests: unit ValidateGrantTypes accept/reject + the two removed grants map to null;
integration OAuthGrantTypeAllowlistTests drives the real OAuthAdminService and
asserts create + update reject implicit/password with a positive control. Unit
1402/1402, integration 537/538 (the one failure is the known last-dependent
UserView catch-up flake — DcrRegistrationEndpointTests, green in isolation and
logically unrelated to grant validation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@windischb
windischb merged commit fd5de96 into develop Jul 22, 2026
8 checks passed
@windischb
windischb deleted the fix/remove-implicit-password-grants branch July 22, 2026 05:16
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