Skip to content

Add the three v0.13.0 passwordless methods to the landing page - #411

Merged
marcjazz merged 5 commits into
mainfrom
landing/v0.13.0-sweep
Sep 26, 2026
Merged

marcjazz merged 5 commits into
mainfrom
landing/v0.13.0-sweep

Conversation

@marcjazz

Copy link
Copy Markdown
Collaborator

The "Eight ways to prove who someone is" grid had not moved since it was written — three real AuthMethod implementations shipped in v0.13.0 (magic link, email/SMS one-time codes, recovery codes) and none of them were on the page a visitor actually lands on.

What changed

  • Three new cards inserted after TOTP, before the OAuth2/OIDC group — matching the order docs.authkestra.com's sidebar now uses (fixed in the paired docs PR, Authkestra/docs#3).
  • Heading updated: "Eight ways" → "Eleven ways to prove who someone is".
  • Recovery codes' card body states precisely what it is — a look-up secret authenticator, not tied to TOTP — since that distinction is the one thing worth getting right about that method in one sentence.
  • Three new icons added to the hand-rolled Lucide registry (link, message-square-code, list-checks), fetched verbatim from lucide-static@1.47.0 rather than approximated from memory, matching this file's own stated sourcing practice ("extracted verbatim so no runtime icon package ships").
  • Quickstart.astro's install snippet was still pinned to version = "0.9" — same class of staleness as the top-level READMEs (Bring the READMEs up to v0.13 #409) and the mdBook (Bring RFC status, roadmap, and the mdBook up to v0.13.0 #410), five minors behind. Fixed.

Verification

Ran a real astro build: the output HTML has all eleven <h3> cards in the intended order (Passkeys, TOTP, Magic Link, Email/SMS One-Time Codes, Recovery Codes, Stateless OAuth2, OIDC, Client Credentials, Device Flow, Bot Protection, Device Signatures), and the heading text updated correctly.

Dependency on the docs PR

The three new cards' hrefs point at docs.authkestra.com/providers/{magic-link,otp,recovery-codes}/, which don't exist until Authkestra/docs#3 merges and deploys. Until then those three links 404 — the other eight are unaffected. Worth merging this after that PR deploys, or accepting a brief window where three cards link to nothing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu

marcjazz and others added 3 commits September 23, 2026 13:18
…status

Mechanical pass ahead of a book-wide sweep for v0.13.0.

RFC-010/011/012 all said "proposed, not implemented" despite shipping
in v0.13.0 (#400, #402, #404) — the same class of staleness as the
README version pins fixed in #409, just in the status line instead of
an install snippet. Corrected to "implemented", each naming its feature
flag and module.

Phase 2's three checkboxes in roadmap.md were unchecked even though the
gate plus all three methods are merged; checked them and added a
one-line note on the two pieces of shared store infrastructure
(AtomicDecrement, the tightened CredentialStore contract) that came out
of building them, since a future feature is the likeliest reader of
that note.

`authkestra-ssf` was listed as "(planned)" in the crate-status section
and named again under Phase 4 as future work ("Implement SSF/CAEP for
real-time revocation") — but it shipped as #309, before this session's
work began. Relabelled "(shipped, receiver only)", and Phase 4 now
names precisely what the crate's own module doc says is still missing:
revoking or attenuating a live session on an event, transmitting SETs
of its own, and CAEP-aware middleware. `authkestra-policy`'s "proof of
concept, nothing calls it yet" status was checked against the source
and left unchanged — it is still true.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu
Fanned out over the book's 11 chapters (a Workflow run, one agent per
chapter plus a cross-chapter verify pass) after scouting which ones
plausibly needed anything: five had no v0.13.0-relevant content and are
untouched (ch01, ch04, ch05, ch06, ch07, ch10, ch11 — checked, not
skipped) or made no change after checking; four did.

ch08 (Getting Started Tutorial): the same `version = "0.7"` pin bug
already fixed in the top-level READMEs (#409), four occurrences, fixed
to 0.13 the same way.

ch02 (Core Engine and Identity): its KvStore/CredentialStore persistence
list was missing recovery-code credentials and the magic-link/OTP
one-time secrets — verified each against its actual store bound in
source before adding it.

ch03 (Core Traits): the chapter that documents AuthMethod and the
KvStore atomic-primitive family in depth, so it had the most real gaps.
Added the three new AuthMethod impls with their feature flags and RFC
references; added AtomicDecrement alongside AtomicConsume/AtomicInsert;
and corrected two "planned traits" bullets that flatly denied
authkestra-ssf and authkestra-policy exist, when both are real, published
crates (receiver-only and unwired-PoC respectively) — the chapter
predates both shipping.

ch09 (Security and Threat Model): added re-proof gating as a threat this
release closes — a hijacked-but-merely-logged-in session can no longer
enrol the attacker's own factor — since this chapter already enumerates
shipped security properties and re-proof gating is squarely one. The
cross-chapter verify pass then caught what no single-chapter read could:
this same chapter's CAEP section still said "no SSF/CAEP receiver...
in the workspace", flatly contradicting the ssf correction just made in
ch03 and docs/roadmap.md §2. Split that section into a shipped-ingestion
bullet and a still-missing-transmitter/revocation-wiring bullet, matching
the labelling pattern the chapter already uses elsewhere, and fixed the
chapter's own intro sentence, which claimed all of sections 1-3 were
pure roadmap targets and was now wrong twice over.

One thing I corrected after the workflow returned, having written the
methods myself: it described magic link and OTP as leaving has_enrolled
"at their defaults". Both actually override it to explicitly return
false — the same value, but a stated decision rather than an inherited
one, which their own doc comments say in as many words. Reworded so the
chapter reflects the deliberateness rather than implying an oversight.

Two things surfaced and deliberately left alone, per the same
don't-invent-scope instruction the chapter agents were given:

- CredentialStore::delete_credential's tightened atomicity contract
  (recovery codes' single-use guarantee depends on it) has nowhere to
  attach — neither ch02 nor ch03 shows CredentialStore's actual
  definition, only mentions it in passing, so adding the contract detail
  would mean writing a new section rather than fixing a stale one.
- ch02 has a pre-existing, unrelated inconsistency (its "Architectural
  Decisions" section describes DID/GNAP work its own callout two
  paragraphs above says doesn't exist) that predates this release and is
  out of scope for a v0.13.0 sweep.

Paired with the mechanical pass in the previous commit (RFC status
lines, roadmap.md Phase 2 checkboxes and crate-status corrections).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu
The "Eight ways to prove who someone is" grid had not moved since it
was written — three real AuthMethod implementations shipped in
v0.13.0 (magic link, email/SMS one-time codes, recovery codes) and
none of them were on the page a visitor actually lands on.

Inserted after TOTP, before the OAuth2/OIDC group, matching the order
docs.authkestra.com's sidebar now uses (fixed in the paired docs PR).
Heading updated to "Eleven ways". Recovery codes' card body says what
it is precisely — a look-up secret authenticator, not tied to TOTP —
since that distinction is the one thing worth getting right about that
method in one sentence.

Three new icons needed adding to the hand-rolled Lucide registry
(`link`, `message-square-code`, `list-checks`), fetched verbatim from
lucide-static 1.47.0 rather than approximated from memory, matching
this file's own stated sourcing practice ("extracted verbatim so no
runtime icon package ships").

Also fixed: Quickstart.astro's install snippet was still pinned to
`version = "0.9"`, the same class of staleness as the top-level READMEs
(#409) and the mdBook (#410) — five minors behind.

Verified with a real `astro build`: the output HTML has all eleven
`<h3>` cards in the intended order, and the heading text updated
correctly. A stale, gitignored `dist/` directory from an unrelated
prior build briefly looked like it meant something was wrong (it listed
routes like /providers/totp/) — it didn't; those come from
astro.config.mjs's legacy MOVED_TO_DOCS redirect list for URLs that
existed before docs.authkestra.com existed, which correctly needs no
entry for pages that never lived on this domain.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu

@lightbridge-assistant lightbridge-assistant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🅵 Fast automated pass — SAST + a quick, diff-scoped look (no repo-wide retrieval). For a deeper, repo-aware review, mention @lightbridge-assistant on this PR.

Re-checked paths.ts in full: all three new icon entries match the inlined Lucide set used by the file and render via the existing Icon component — no issues. The landing docs additions are consistent (heading count matches the 11 entries). One finding stands: Quickstart.astro's cargo snippet, touched by the 0.13 bump, still names the removed "session" feature of the authkestra facade (confirmed absent from crates/authkestra/Cargo.toml's exhaustive feature list), so copy-pasting it errors. The docs/*.md files under docs/ and roadmap are prose-only additions and were not opened in depth.


🤖 AI-generated review — treat it as untrusted, verify before acting; a human owns the final decision (AI governance).

Comment thread landing/src/components/Quickstart.astro Outdated
import { highlightRust, highlightRustLine } from '../lib/rust-highlight';

const cargo = `authkestra = { version = "0.9", features = ["axum", "session", "github"] }`;
const cargo = `authkestra = { version = "0.13", features = ["axum", "session", "github"] }`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 correctness

Quickstart copy-paste fails: "session" feature gone

This line's feature list includes "session", but the authkestra facade crate no longer has a session feature — crates/authkestra/Cargo.toml says sessions became part of engine (#375) and the features comment explicitly states "There is deliberately no session ... feature". Anyone copying this quickstart gets error: none of the selected packages contains these features: session. Since the line is being touched anyway for the 0.13 bump, drop session (e.g. features = ["axum", "memory", "github"] if a store is wanted, or just ["axum", "github"]).

Was this useful? React 👍/👎 to give us feedback

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Confirmed and fixed in 1172876 — went with your suggested ["axum", "memory", "github"] after tracing it through crates/authkestra/src/lib.rs rather than taking it on faith: the sample uses MemoryStore and Authkestra::builder(), both reachable only through the facade's store re-export and core alias, both gated on memory — which itself pulls in engine (memory = ["engine", "authkestra-engine/memory"]), so nothing else needs adding. Confirmed minimal and sufficient for exactly this sample, and reran astro build clean afterward.

Good catch — this line was already stale before my PR touched it (I only bumped the version number), but since I was the one editing it, it's on me to have caught this too.

marcjazz and others added 2 commits September 26, 2026 01:55
Review on #411 caught it: the facade's `session` feature doesn't exist —
it was folded into `authkestra-engine` unconditionally when sessions
became part of the engine (#375), and crates/authkestra/Cargo.toml says
so explicitly ("There is deliberately no `session` ... feature here").
Anyone copying this Cargo.toml line got
`error: none of the selected packages contains these features: session`
before ever reaching the Rust.

Verified against source rather than taking the suggestion on faith: the
sample uses `MemoryStore` and `Authkestra::builder()`, both of which
need the facade's `store` re-export and `core` alias — gated on
`memory` (which itself pulls in `engine`, so nothing else needs adding).
Traced the exact cfg gates in crates/authkestra/src/lib.rs to confirm
`["axum", "memory", "github"]` is both sufficient and minimal for this
sample, not just plausible.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu
Prompted by "have you updated the feature comparison board? should
that table even exist honestly?" The honest answer was no on both
counts: I hadn't looked at it since checking one unrelated version
pin, and once I actually checked the three names in it, one was a
real problem — better-auth.rs is a pre-1.0 alpha (1.0.0-alpha.2), and
its own docs say APIs may change without notice between alpha
releases. Comparing a stable v0.13.0 release against an undisclosed
alpha with five confident "yes" checkmarks was not an honest
comparison, independent of anything this release changed.

Replaced it with oauth2-passkey: real, shipped, not alpha-labelled,
and honestly narrower in scope (OAuth2 relying-party + WebAuthn only,
confirmed via its own README — no OP role, no TOTP, no resource
server). A fair comparison against a real project beats a favourable
one against an unstable strawman.

Rauthy and Kanidm both re-verified against their own docs rather than
carried over from whenever this was last written: Kanidm's native
OAuth2/OIDC provider and WebAuthn support confirmed on
kanidm.github.io, Rauthy's passkey-first design and brute-force/IP
rate-limiting confirmed on its GitHub README. Both check out.

Rewrote rows to show what actually differs, using only what v0.13.0
and existing crates can back up:

  - OAuth2/OIDC role: Authkestra plays all three (provider, client,
    resource server) from one crate. Neither alternative does — this
    is the genuine structural difference, not a marketing framing.
  - Resource server: named DPoP (RFC 9449) and mTLS (RFC 8705) binding
    specifically, both real (crates/authkestra-resource), rather than
    a bare "yes".
  - Passwordless methods: names the actual count (5) instead of a bare
    "Multi-factor auth: yes", which is what the whole session's work
    had made most stale.
  - New row, "Fresh proof to enrol a factor": RFC-009's re-proof gate
    is a genuine, checkable differentiator I could find no equivalent
    documented primitive for in either alternative. Marked "Not
    documented" for both rather than a confident "No" — the honest
    claim is an absence of evidence, not evidence of absence.
  - Bot protection: named Authkestra's actual three providers
    (Turnstile/hCaptcha/reCAPTCHA, crates/authkestra-engine/src/captcha.rs)
    against what Rauthy's docs actually describe (rate-limiting and
    IP-blocking — a different mechanism, not "not offered" and not a
    false equivalence to CAPTCHA either).

One thing caught in my own second pass, after finishing the rewrite:
the oauth2-passkey cell for "Configuration safety" first read
"Standard builder", carried over from the old better-auth.rs row
without verifying oauth2-passkey uses a builder at all. Fixed to "Not
documented" — the same discipline the rest of the rewrite was supposed
to hold everywhere, caught here on a re-read rather than in review.

Renamed the internal `betterAuth` variable to `embeddedAlt` throughout
so the code doesn't keep naming a competitor that's no longer in it.

Verified with a real `astro build`: all ten row labels render, the
table caption and both `.detail` write-ups describe the new middle
column, and no reference to "better-auth" remains anywhere in the
built output.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XaoYHiT9Vb85XhBdVCg9Xu
@marcjazz
marcjazz merged commit be7e367 into main Sep 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant