Skip to content

Replay record: fallback shorter than known closes, and non-bearer confirmations shrink it #56

Open

Description

@shreemaan-abhishek

What

Two ways last_moment_usable leaves the replay record (#50) shorter than it could be, found by @jarvis9443 reviewing #53. Both apply to every tracked assertion, OneTimeUse or not, which is why they are filed against the record rather than fixed there.

1. The fallback is dominated. An assertion acceptance never bounds gets replay_ttl (600s default); one valid until 9999 gets the day cap. The strictly worse input gets the 144× shorter record. Measured: confirmations {C1: this ACS, NotBefore an hour out, no close} + {C2: this ACS, close at T+4h} record 600s, while C2 alone records ~14460s, leaving [T+600, T+14460), inside the IdP's stated window, unprotected; acceptance past T+1h is unbounded either way, so the longer record dominates. The proposed one-liner, usable_until == nil taking the day cap, would settle both, but it also retires the documented meaning of replay_ttl, so it needs deciding here, with the option's docs.

2. Non-bearer confirmations count. confirms_here ignores SubjectConfirmation@Method, so a sender-vouches sibling with no close, next to an ordinary 30-minute bearer confirmation, drops the record from ~30 minutes to 600s. Profiles 4.1.4.2 expressly permits other confirmation methods beside the required bearer one, so this shape is in-profile and inside shipped windows: the strongest item here. Fix: only bearer confirmations weigh in last_moment_usable. Whether they should weigh anywhere else is #45 (Method is parsed and checked by nobody, including at acceptance).

Not in scope

The full-zone fail-open path was weighed on #53 and stays: refusing there is a lockout lever and evicting unprotects another user's record; the ERR names the zone and README's sizing paragraph is the remedy.

Activity

  1. shreemaan-abhishek commented on Aug 31, 2026

    @shreemaan-abhishek
    ContributorAuthor

    Third item for this issue, from #53 review (r3893960851): last_moment_usable ignores the InResponseTo binding, so a request-bound confirmation with no NotOnOrAfter reads as "usable forever" when the assertion is in fact unusable anywhere after its own login, the binding refuses any later presentation by request-ID mismatch. Measured: TEST 45's fixture plus an OneTimeUse stamp draws the "stays acceptable past its record" warn, yet re-presentation after the record lapses is 401; the control without InResponseTo replays 302. So the warn is false for that shape, and the record is longer than it needs to be. The shape is out of profile (a bearer confirmation MUST carry NotOnOrAfter), so no real IdP hits it meanwhile.

    Fix belongs with the other two items, since all three are last_moment_usable's notion of "what keeps an assertion usable": bearer-only confirmations, fallback dominance, and request-bound confirmations not extending usability across logins.

  2. shreemaan-abhishek commented on Sep 1, 2026

    @shreemaan-abhishek
    ContributorAuthor

    Third input for the record-bounds pass, from the review on #53: the "stays acceptable past its record" warn decides unbounded from time attributes alone, while a confirmation binding InResponseTo to the login's own request id bounds acceptance by itself (the request id is minted per login and dropped once it completes). Carrying in_response_to forward beside not_on_or_after when deciding unbounded is the same one-line shape as the @NotBefore and @method items above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions