Skip to content

docs: add device authentication with PIN and biometrics guide#2673

Open
hperl wants to merge 16 commits into
masterfrom
deviceauthn-pin-docs
Open

docs: add device authentication with PIN and biometrics guide#2673
hperl wants to merge 16 commits into
masterfrom
deviceauthn-pin-docs

Conversation

@hperl

@hperl hperl commented Jul 10, 2026

Copy link
Copy Markdown
Member

Documents device authentication end to end and restructures it into a section with per-platform guides.

New structure: kratos/passwordless/deviceauthn/

  • Overview (keeps the existing URL): both modes — second-factor device binding and, with first_factor, complete passwordless login via app PIN or platform biometrics (AAL2 in one request). Concepts (three-key model, user_verification levels), configuration (first_factor, pin_max_attempts, ios_biometric_first_factor, app-ID pinning), a byte-exact protocol reference for all flows (enrollment, PIN enrollment with challenge SHA256(nonce ‖ transport_public_key), biometric enrollment, step-up, first-factor login with pin_proof, secret rotation) with sequence diagrams, normative client implementation requirements, recovery/lockout, troubleshooting, and the security model.
  • Android / iOS guides: the full per-platform journey — second-factor binding plus PIN and biometric first factor — with complete copy-pasteable reference implementations (Keystore/BouncyCastle HPKE on Android incl. a fail-closed hardware check for the sealing key; App Attest/CryptoKit HPKE/Secure Enclave on iOS). The 2FA-vs-PIN attestation-challenge difference is called out where integrations commonly break.
  • Dart/Flutter guide: the native-bridge pattern.

Corrections to existing content

  • client_key_id is server-assigned (the lowercase-hex SHA-256 fingerprint of the key's public key); the add-key examples no longer show a client-chosen ID and the guides show how to derive or read it.
  • Removed the outdated "can only be used as a second factor" claims.
  • Step-up examples now reference the login flow (previously linked the settings flow); sequence diagrams use POST for flow submission.

The previous kratos/passwordless/deviceauthn URL is preserved; the platform pages are new URLs. Both the Ory Network and OEL sidebars get a "Device binding" category.

Related Issue or Design Document

Documentation improvement; no issue reference required.

Checklist

  • I have read the contributing guidelines and signed the CLA.
  • I have referenced an issue containing the design document if my change introduces a new feature.
  • I have read the security policy.
  • I confirm that this pull request does not address a security vulnerability.

🤖 Generated with Claude Code

hperl and others added 10 commits July 10, 2026 17:58
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Append the iOS guide to the device authentication PIN page: prerequisites,
a full Swift reference implementation, biometric-key notes, and the PIN
change / secret rotation flows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the stale "second factor only" claims from the device binding
page and cross-link the new first-factor PIN and biometrics page. Also
fix a copy-paste error where the step-up step pointed at the settings
flow instead of the login flow, and note the enrollment user_verification
level.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 10, 2026 18:29
@hperl hperl self-assigned this Jul 10, 2026
@hperl hperl requested review from piotrmsc and wassimoo as code owners July 10, 2026 18:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds comprehensive documentation for using the deviceauthn strategy as a first factor via an app PIN or platform biometrics (AAL2 in one submission), and updates the existing device binding page to reflect this and fix flow/verb references. The new page is also wired into the Ory Network and OEL sidebars so it’s discoverable under Passwordless authentication.

Changes:

  • Adds a new “Device authentication with PIN and biometrics” page with configuration, protocol details, diagrams, and iOS/Android reference implementations.
  • Updates the existing “Device binding” page to remove outdated “second factor only” claims and correct step-up references to the login flow and POST submissions.
  • Registers the new page in sidebars-network.ts and sidebars-oel.ts.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
sidebars-oel.ts Adds the new deviceauthn-pin doc entry to the OEL sidebar.
sidebars-network.ts Adds the new deviceauthn-pin doc entry to the Network sidebar.
docs/kratos/passwordless/09_deviceauthn-pin.mdx New guide page with protocol reference, diagrams, and client reference implementations.
docs/kratos/passwordless/08_deviceauthn.mdx Updates device binding docs to point to first-factor usage and fixes flow/HTTP verb references.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +750 to +752
fun clientKeyId(signingKeyAlias: String): String =
sha256(keyStore.getCertificate(signingKeyAlias).publicKey.encoded)
.joinToString("") { "%02x".format(it) }
/// The flow's hidden deviceauthn_nonce node value:
/// base64(JSON {"nonce": "<base64 of 32 raw bytes>"}) → raw nonce bytes.
fun decodeNonce(nodeValue: String): ByteArray {
val json = String(Base64.decode(nodeValue, Base64.DEFAULT))
Comment on lines +524 to +534
static func aesCtr(key: [UInt8], iv: [UInt8], data: [UInt8]) -> [UInt8] {
var cryptor: CCCryptorRef?
CCCryptorCreateWithMode(
CCOperation(kCCEncrypt), CCMode(kCCModeCTR), CCAlgorithm(kCCAlgorithmAES128),
CCPadding(ccNoPadding), iv, key, key.count, nil, 0, 0, 0, &cryptor)
defer { CCCryptorRelease(cryptor) }
var out = [UInt8](repeating: 0, count: data.count)
var moved = 0
CCCryptorUpdate(cryptor, data, data.count, &out, out.count, &moved)
return out
}
Comment on lines +548 to +551
var salt = [UInt8](repeating: 0, count: 16)
_ = SecRandomCopyBytes(kSecRandomDefault, salt.count, &salt)
var iv = [UInt8](repeating: 0, count: 16)
_ = SecRandomCopyBytes(kSecRandomDefault, iv.count, &iv)
Comment on lines +328 to +329
- **Require an unlocked device.** Create the sealing key so it is usable only while the device is unlocked
(`setUnlockedDeviceRequired(true)` on Android; `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` on iOS).
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The network and Ory Kratos documentation sidebars now include the kratos/passwordless/deviceauthn-pin page.

Changes

Passwordless navigation

Layer / File(s) Summary
Add deviceauthn-pin sidebar entries
sidebars-network.ts, sidebars-oel.ts
Adds kratos/passwordless/deviceauthn-pin to both sidebar item lists near the existing passwordless device authentication documentation.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Possibly related PRs

  • ory/docs#2447: Adds the related deviceauthn documentation entry to the sidebar.
  • ory/docs#2589: Adds Ory Kratos guide entries to sidebars-network.ts.

Suggested reviewers: aeneasr, zepatrik, piotrmsc, unatasha8, vinckr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: adding device authentication documentation for PIN and biometrics.
Description check ✅ Passed The description follows the template with a clear summary, related issue section, checklist, and extra comments.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch deviceauthn-pin-docs

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 add-key examples still showed the client choosing and submitting
client_key_id. The server now derives it as the lowercase-hex SHA-256
fingerprint of the key's public key (SubjectPublicKeyInfo, DER) and the
add payload has no such field. Update the payloads, SDK snippets,
reference steps, and diagrams accordingly, and align the availability
wording with the new PIN page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hperl and others added 2 commits July 11, 2026 16:28
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dissolve the standalone "Device authentication with PIN and biometrics"
page. Platform-agnostic content (how it works, configuration, protocol
reference, client requirements, recovery, troubleshooting, security model)
merges into the device binding overview; the iOS and Android reference
implementations merge into the respective platform guides. Preserves the
#pin-enrollment, #first-factor-login, #rotating-the-pin-secret, and
#client-implementation-requirements anchors on the overview page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The section now covers both second-factor binding and first-factor
PIN/biometric login, so the strategy's umbrella name fits better.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pages were listed in both the network and OEL sidebars; a doc can
only display one sidebar, and the OEL one won the association, so
navigating from the Ory Network sidebar into the section reshuffled the
navigation to Ory Enterprise License. Sibling feature pages (passkeys,
one-time codes) are network-only for the same reason.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants