Skip to content

feat: allow deleting the code credential via the admin API - #4592

Open
walter-hostaway wants to merge 1 commit into
ory:masterfrom
walter-hostaway:feat/delete-code-credential
Open

feat: allow deleting the code credential via the admin API#4592
walter-hostaway wants to merge 1 commit into
ory:masterfrom
walter-hostaway:feat/delete-code-credential

Conversation

@walter-hostaway

@walter-hostaway walter-hostaway commented Aug 13, 2026

Copy link
Copy Markdown

The admin endpoint DELETE /admin/identities/{id}/credentials/{type} handles
every credential type except code: totp, lookup_secret, webauthn,
oidc, saml, password, and deviceauthn are all removable, but code
falls through to the default branch of the switch in
deleteIdentityCredentials and returns 400 "Credentials type code cannot be deleted." Combined with the fact that removing the sourcing trait does not drop
the derived code credential, there is no way to detach an email/phone code
credential from an identity in place (see #4462).

This change handles CredentialsTypeCodeAuth in the delete switch. Because
code is a first factor only when passwordless code login is enabled, the
existing "last first factor" guard is applied only when
SelfServiceCodeStrategy.PasswordlessEnabled is true; as a pure MFA second
factor code is freely removable, matching totp/lookup_secret. Routing it
through the password/oidc guard unconditionally would wrongly block removal
in MFA-only deployments, where CountActiveFirstFactorCredentials returns 1.

Related issue(s)

Resolves #4462

Checklist

  • I have read the contributing guidelines.
  • I have referenced the issue this change addresses (Removing Trait/Phone does not remove phone number from Credential/Code #4462).
  • I am following the contributing code guidelines.
  • I have read the security policy.
  • I confirm that this pull request does not address a security vulnerability.
  • I have added tests that prove my fix is effective (identity/handler_test.go, TestHandler passing).
  • I have added or changed the documentation.

Further Comments

Design note: the naive fix (routing code through the existing password/oidc
guarded branch) is incorrect for MFA-only setups, where the guard would block
removing a purely-second-factor code. Gating the guard on PasswordlessEnabled
avoids that while still protecting passwordless-code-only identities from losing
their last first factor. Happy to adjust the guard semantics to maintainer
preference.

AI assistance: the analysis, patch, and tests were prepared with Claude Code;
the change is human-reviewed, built (go build ./..., go vet ./identity/), and
tested (go test ./identity/ -run TestHandler).

Summary by CodeRabbit

  • New Features

    • Added support for deleting code-based login credentials.
    • Prevents deletion when it would remove the last required first-factor credential while passwordless code login is enabled.
    • Allows deletion when another eligible first-factor credential remains.
  • Bug Fixes

    • Improved credential deletion handling for passwordless authentication scenarios.

@CLAassistant

CLAassistant commented Aug 13, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b47aedb6-7c97-40c2-90f2-85f8a0b078f7

📥 Commits

Reviewing files that changed from the base of the PR and between b86338d and 8408528.

📒 Files selected for processing (2)
  • identity/handler.go
  • identity/handler_test.go

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Code credential deletion now supports code credentials. Passwordless code login blocks deletion of the last first-factor credential. Tests cover successful deletion and rejection.

Changes

Code credential deletion

Layer / File(s) Summary
Code credential deletion flow
identity/handler.go, identity/handler_test.go
The handler deletes code credentials when allowed and preserves other credentials. Passwordless mode returns a 400 error when deletion would remove the last first-factor credential. Tests cover both cases.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 84085

The admin API now permits deleting code credentials while preserving the existing first-factor protection where passwordless code login requires it. No actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: aeneasr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that the admin API can delete code credentials, which is the primary change.
Description check ✅ Passed The description explains the bug, implementation, guard behavior, related issue, tests, and validation; documentation is the only unchecked item and is justified.
Linked Issues check ✅ Passed The code and tests address issue #4462 by enabling code credential deletion while preserving the last-first-factor safeguard.
Out of Scope Changes check ✅ Passed The changes are limited to code credential deletion logic and directly related tests, with no unrelated changes identified.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The admin endpoint DELETE /admin/identities/{id}/credentials/{type}
handled every credential type except code, which fell through to the
default branch and returned 400 "Credentials type code cannot be
deleted." This made it impossible to detach an email/phone code
credential from an identity in place.

Handle CredentialsTypeCodeAuth in the delete switch. Because code is a
first factor only when passwordless login with code is enabled, apply
the last-first-factor guard only in that case; as a pure MFA second
factor it is freely removable like TOTP or lookup secrets.

Resolves ory#4462
@walter-hostaway
walter-hostaway force-pushed the feat/delete-code-credential branch from 7f80a83 to 8408528 Compare August 13, 2026 13:11
@walter-hostaway
walter-hostaway marked this pull request as ready for review August 24, 2026 14:17
@walter-hostaway
walter-hostaway requested review from a team and aeneasr as code owners August 24, 2026 14:17
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.

Removing Trait/Phone does not remove phone number from Credential/Code

2 participants