Hacker DirectoryHacker Directory

WEB / WEB-05.04

Key exchange and session resumption

A new TLS connection can use earlier PSK context while key exchange, record encryption, and early-data policy remain separate decisions.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Fresh-share PSK

  1. ClientHello prepared locally

    The client prepares ClientHello with identity atlas-ticket-1, a binder and a psk_dhe_ke offer. The secret PSK stays local; the server has not received the message and application data is unsent.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_dhe_ke
    Server · TLS
    Awaiting new connection; no PSK selected
  2. ClientHello received

    The server received the ticket identity, binder, and offered mode; local binder verification is still pending.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_dhe_ke
    Server · TLS
    CH received; binder pending; no app
  3. PSK mode selected; flight ready

    The supplied binder-verification predicate succeeds. The server selects psk_dhe_ke and prepares ServerHello plus protected EE/Finished; a fresh key_share belongs to this mode. The client has not received that selection yet.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_dhe_ke
    Server · TLS
    PSK accepted; psk_dhe_ke; SH/EE/Finished ready
  4. Server flight received

    The semantic ServerHello and protected EE/Finished flight arrived at the client; peer Finished verification remains pending.

    Client · TLS
    PSK selected flight received; Finished pending
    Server · TLS
    PSK accepted; psk_dhe_ke; SH/EE/Finished ready
  5. Client local gate opened

    Selected Finished and PSK context checks succeed; the client prepared its own Finished. This scene produces no app or business effect.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    PSK accepted; psk_dhe_ke; SH/EE/Finished ready
  6. Client Finished received

    Client Finished arrived at the server; arrival is not yet local Finished verification or user authentication.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    Client Finished received; verification pending
  7. Resumed handshake complete

    Selected server verification succeeds; the new traffic context completes while resource authorization and application commit remain unmodeled.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    Handshake complete; app delivery none; commit false

PSK only

  1. ClientHello prepared locally

    The client prepares ClientHello with identity atlas-ticket-1, a binder and a psk_ke offer. The secret PSK stays local; the server has not received the message and application data is unsent.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_ke
    Server · TLS
    Awaiting new connection; no PSK selected
  2. ClientHello received

    The server received the ticket identity, binder, and offered mode; local binder verification is still pending.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_ke
    Server · TLS
    CH received; binder pending; no app
  3. PSK mode selected; flight ready

    The supplied binder-verification predicate succeeds. The server selects psk_ke and prepares ServerHello plus protected EE/Finished; this mode supplies no key_share. The client has not received that selection yet.

    Client · TLS
    ClientHello ready; ticket identity/binder; psk_ke
    Server · TLS
    PSK accepted; psk_ke; SH/EE/Finished ready
  4. Server flight received

    The semantic ServerHello and protected EE/Finished flight arrived at the client; peer Finished verification remains pending.

    Client · TLS
    PSK selected flight received; Finished pending
    Server · TLS
    PSK accepted; psk_ke; SH/EE/Finished ready
  5. Client local gate opened

    Selected Finished and PSK context checks succeed; the client prepared its own Finished. This scene produces no app or business effect.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    PSK accepted; psk_ke; SH/EE/Finished ready
  6. Client Finished received

    Client Finished arrived at the server; arrival is not yet local Finished verification or user authentication.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    Client Finished received; verification pending
  7. Resumed handshake complete

    Selected server verification succeeds; the new traffic context completes while resource authorization and application commit remain unmodeled.

    Client · TLS
    Peer Finished valid; own Finished ready; app none
    Server · TLS
    Handshake complete; app delivery none; commit false

Full fallback

  1. ClientHello prepared locally

    The client prepares ClientHello with identity atlas-ticket-1, a binder and a psk_dhe_ke offer. A suitable fresh share for a full handshake is offered too. The secret PSK stays local; the server has not received the message and application data is unsent.

    Client · TLS
    ClientHello ready; PSK and full parameters
    Server · TLS
    Awaiting new connection; no PSK selected
  2. PSK offer received

    A normal ClientHello offers a PSK identity and a suitable fresh share for a full handshake; server acceptance is undecided.

    Client · TLS
    ClientHello ready; PSK and full parameters
    Server · TLS
    CH received; PSK decision pending
  3. Certificate flight prepared locally

    Server policy declines PSK. Because the client offered full parameters, the server prepares its certificate-based flight. Preparing Certificate and Finished does not mean the client verified either message.

    Client · TLS
    ClientHello ready; PSK and full parameters
    Server · TLS
    PSK declined; certificate-full flight ready
  4. Full flight received

    The certificate-based server flight arrived at the client; path, hostname, private-key proof, and Finished checks remain pending.

    Client · TLS
    Full server flight received; all peer checks pending
    Server · TLS
    PSK declined; certificate-full flight ready
  5. Fallback selected; verification pending

    The client received the certificate-based flight, but path, hostname, CertificateVerify and Finished checks remain unfinished. This branch stops at that boundary: handshakeCompletedSelected=false and businessCommit=false remain.

    Client · TLS
    Fallback selected; handshake incomplete; app none
    Server · TLS
    PSK declined; certificate-full flight ready

Early data waits

  1. Initial context

    The selected initial conditions are local state; no message arrival or application outcome has occurred yet.

    Client · TLS
    Ticket eligible; new connection; app unsent
    Server · TLS
    Awaiting new connection; no PSK selected
  2. Action context selected

    The normal publish-note request is a mutating operation; resumption eligibility does not replace business-policy approval.

    Client · TLS
    Operation publish-note; mutates=true
    Server · TLS
    Awaiting new connection; no PSK selected
  3. Early policy closed

    The client profile excludes this operation from early data; no early message was sent to the network.

    Client · TLS
    EarlyDataSent=false; wait for verified 1-RTT
    Server · TLS
    Awaiting new connection; no PSK selected
  4. Business effect waits

    An ordinary handshake and current resource authorization are required later; the server receives no message in this local branch.

    Client · TLS
    Handshake incomplete; app none; businessCommit=false
    Server · TLS
    Awaiting new connection; no PSK selected

ACTORS · STATE · DATA FLOW

What is established again on a new connection?

Atlas Notes opens a second connection to the same service. Reusing an open TCP connection can avoid a new TLS handshake for another HTTP request; session resumption establishes an actually new TLS connection. It does not continue the previous socket. A PSK derived from an earlier handshake becomes an input to a new negotiation, with a new transcript and new traffic secrets. Describing this as reusing the previous encryption key therefore gives the wrong mechanism.

Key exchange establishes shared keying material; record encryption protects application data with symmetric keys derived from that material; a signature binds control of a certificate private key to a certificate-based handshake transcript. Sending an X25519 public share does not send its private scalar. A certificate public key is not an application-record traffic key either. Collapsing these three jobs into one lock drawing makes the absence of CertificateVerify during resumption look incorrectly like absence of authentication.

A PSK, a ticket, and a binder are different things

In the selected example an initial certificate-based connection completed successfully, and the server supplied an opaque ticket alias in NewSessionTicket. The client associates the ticket with a secret PSK, its KDF hash, the earlier service identity context, and a lifetime. A later ClientHello carries a ticket identity and a binder, not the secret PSK in cleartext. The ticket may represent a server-side lookup or protected server state; this lesson assumes no actual encoding for either design.

The binder is a MAC tying an offered PSK to ClientHello context; the server verifies the binder for its selected identity. Having a ticket does not establish acceptance: lifetime, hash compatibility, service context, and server policy still matter. When PSK authentication is selected, the server omits Certificate and CertificateVerify; the linked PSK context and Finished provide authentication. This context is not an application login session. Logout and permission changes must not depend solely on TLS ticket expiry.

Why psk_dhe_ke and psk_ke are not equivalent

The client advertises supported choices through psk_key_exchange_modes. In the selected psk_dhe_ke case both peers create fresh X25519 shares; the PSK and the new asymmetric shared secret enter the key schedule together. The “dhe” part of the mode label is historical: the current TLS 1.3 specification also distinguishes asymmetric establishment with extension-defined KEM choices. This example selects X25519 specifically, without claiming every implementation chooses that group.

psk_ke uses only the PSK, and ServerHello contains no key_share. Ordinary application data on that connection lacks the same forward-secrecy argument against later PSK disclosure. In psk_dhe_ke, properly generated ephemeral values that are not reused across connections, together with secret-erasure assumptions, provide the distinction. Forward secrecy does not prevent an endpoint reading current plaintext or an application logging it; it does not promise perpetual secrecy for every copy of the data.

An unsuitable ticket can lead to a full handshake

The artifact selects a 3600-second ticket lifetime and a 900-second client-side elapsed age. Ticket eligibility is computed from age not exceeding lifetime, KDF-hash compatibility, and suitable service context; server acceptance remains a separate policy input. These are small fixture values rather than normative minima or browser defaults. The ticket’s SNI context cannot replace the requirement that the earlier certificate be valid for the new service identity. The current ticket_lifetime limit is seven days; zero requires immediate discard and the server may apply a shorter acceptance policy. The bounded positive-lifetime comparison does not remove those additional rules.

If the client also offers a suitable key_share for a full handshake, the server can decline the ticket and select a certificate-based handshake. That is an ordinary fallback, not proof that an application request completed or that a measured number of milliseconds was saved. The fallback scene stops at selection, explicitly leaving certificate path, hostname, CertificateVerify, and Finished verification to be completed later. A rejected ticket does not necessarily mean the entire TLS connection must fail.

0-RTT has a separate acceptance decision

Resumption does not require 0-RTT. Early data can be sent before ServerHello using a separate PSK-derived key context; it does not have the same forward-secrecy and cross-connection non-replay guarantees as ordinary 1-RTT data. Successful AEAD verification does not prove the message has never been processed. Understanding that distinction needs no repeated-send experiment: follow the point where application policy permits a side effect.

Atlas policy does not permit the mutating “publish note” operation as early data. The selected branch waits at the client’s own policy gate, so no early application message appears on the wire. Normal application authorization will still run after 1-RTT verification. Even an apparently read-only operation can affect quotas, logs, cost, or rate state. An explicit application profile is needed rather than declaring every 0-RTT request safe from its HTTP method name alone.

2. Red · Trust & Impact

Read every scenario without motion

PSK mode

  1. A ticket is not an application role

    atlas-ticket-1 belongs to notes.example.org service context. Resumption eligibility and acceptance establish neither current user role/tenant rights nor active-account state.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    No policy gate
    Business boundary
    No business effect
  2. Mode or early-data scope was explicit

    psk_dhe_ke includes fresh agreement; psk_ke has serverKeyShare=false and ordinaryForwardSecrecyFromFreshAgreement=false. A TLS 1.3 label does not prove fresh-share mode selection.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    psk_ke vs psk_dhe_ke distinct
    Business boundary
    No business effect
  3. The business action remained pending

    Even normal handshakeCompletedSelected=true leaves businessCommit=false. Absent certificate messages do not establish passed application authorization.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    psk_ke vs psk_dhe_ke distinct
    Business boundary
    Resumed channel / no commit
  4. Secret roles were not substituted

    The resumption PSK is a key-schedule input, not sent in plaintext; c-app-new is not the old record key. Certificate signing keys protect a different relationship; aliases contain no secret bytes.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    psk_ke vs psk_dhe_ke distinct
    Business boundary
    Resumed channel / no commit
  5. Current authorization must be preserved

    After an ordinary verified channel, publish-note still has ordinaryAuthorizationRequired=true. Resumption does not undo logout/account/tenant changes; application policy uses current state.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    Channel resume ≠ current policy allow
    Business boundary
    Resumed channel / no commit
  6. The control outcome kept its required scope

    The selected mode’s secrecy reasoning belongs to its key context. TLS does not retroactively protect endpoint plaintext or log copies; no conclusion covers all data copies.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    Channel resume ≠ current policy allow
    Business boundary
    Mode scope preserved / app unknown

Early action gate

  1. A ticket is not an application role

    atlas-ticket-1 belongs to notes.example.org service context. Resumption eligibility and acceptance establish neither current user role/tenant rights nor active-account state.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    No policy gate
    Business boundary
    No business effect
  2. Mode or early-data scope was explicit

    earlyPolicy.operation=publish-note has mutatesState=true and allowedBeforeHandshake=false. Integrity protection of encrypted early data does not establish once-only processing or freshness.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    publish-note / early withheld
    Business boundary
    No business effect
  3. The business action remained pending

    In early-wait, no mode is selected and the handshake is incomplete. No early data is sent and no business commit occurs. The pending publish-note action is not presented as successfully published.

    Resumption evidence
    Ticket/service context ≠ entitlement
    Early / mode gate
    publish-note / early withheld
    Business boundary
    No early send / no commit
  4. Secret roles were not substituted

    The resumption PSK is a key-schedule input, not sent in plaintext; c-app-new is not the old record key. Certificate signing keys protect a different relationship; aliases contain no secret bytes.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    publish-note / early withheld
    Business boundary
    No early send / no commit
  5. Current authorization must be preserved

    After an ordinary verified channel, publish-note still has ordinaryAuthorizationRequired=true. Resumption does not undo logout/account/tenant changes; application policy uses current state.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    Channel resume ≠ current policy allow
    Business boundary
    No early send / no commit
  6. The control outcome kept its required scope

    The mutating action is held at the early stage. CrossConnectionNonReplayGuaranteed=false and earlyDataForwardSecrecyAssumed=false remain; no replay or business execution is run.

    Resumption evidence
    PSK / new share / new traffic roles
    Early / mode gate
    Channel resume ≠ current policy allow
    Business boundary
    Early withheld / ordinary policy required

ASSUMPTION · BOUNDARY · CONTROL

Which secret affects which past traffic?

A security review needs more than the phrase “the private key leaked.” A certificate signing key, a resumption PSK, a ticket-protection key, and an ephemeral key have different relationships. In the selected psk_ke case, assuming later PSK disclosure changes the assessment of past ordinary application confidentiality; the same conclusion does not directly follow for the fresh-X25519 combined mode. That distinction assumes valid, unreused ephemeral values and appropriate erasure.

TLS cannot reclaim application-memory or log copies after an endpoint compromise either. Identify the data copy and time first: recorded channel traffic, current plaintext, or application persistence? Without that separation the label “forward secret” does not say where a control helps. The artifact performs no compromise; it reasons conditionally from secret roles and the selected mode.

Resumption context is not permission context

Seeing a selected ticket does not show that the browser user still has the same role. An application can receive many resource requests over a connection; even a service-bound ticket belongs to a different layer from resource ownership and current policy. Authorization after logout, a tenant switch, or account disable needs current server-side state.

The review question is which current authorization evidence supports a normal request on a resumed connection. PSK acceptance, application identity verification, and a business commit are distinct events. Keeping them separate reduces false positives and exposes whether the missing control belongs to channel negotiation or application policy.

The necessary condition for encrypted early data

Treating valid integrity as sufficient for 0-RTT breaks an assumption: data may be correctly protected while processing freshness remains a separate question. State in one serving zone does not automatically become shared acceptance state across all zones. Retry and failure recovery can also cause ordinary application duplication; application-level idempotency, operation identity, and deduplication need an explicit scope.

This lesson places the selected boundary at the client policy gate. A mutating operation waits and has no early business effect. That positive outcome is not a test of server-side replay coordination. The server-control requirement is recorded separately; the small model demonstrates only the relationship between earlyDataSent=false and businessCommit=false.

3. Blue · Secure development & defense

Read every scenario without motion

Fallback evidence

  1. Eligibility inputs were recorded separately

    Ticket lifetime 3600, age 900, SHA-256 hash and notes.example.org service context are read together. Ticket/PSK/binder bytes are not copied into diagnostic logs; aliases are used here.

    Ticket-policy evidence
    Age900 / hash / service context
    Negotiation review
    No negotiation review
    Outcome evidence
    No evidence outcome
  2. The eligibility boundary was checked

    The supplied policy considers a ticket eligible at age 3600 seconds but not at 3601. At age 900, incompatible hash or service still blocks eligibility. Time is not the only predicate.

    Ticket-policy evidence
    Age900 / hash / service context
    Negotiation review
    3600 true / 3601 false / compatibility needed
    Outcome evidence
    No evidence outcome
  3. Server acceptance is not eligibility

    In full-fallback, the ticket is eligible but the server declines PSK. Because the client also offers full-handshake parameters, certificate-full can be selected. This branch does not claim the full handshake completed.

    Ticket-policy evidence
    Eligible offer / server may decline
    Negotiation review
    3600 true / 3601 false / compatibility needed
    Outcome evidence
    No evidence outcome
  4. Negotiated-mode evidence is separate

    normal selects psk_dhe_ke while psk-only selects psk_ke. Absent certificate messages alone cannot distinguish them; PSK context and Finished evidence are separate requirements.

    Ticket-policy evidence
    Eligible offer / server may decline
    Negotiation review
    Mode / key share / Finished scope
    Outcome evidence
    No evidence outcome
  5. Fallback is not handshake success yet

    Full-fallback supplies handshakeCompletedSelected=false and businessCommit=false. The certificate flight reached the client, but peer verification remains unfinished. No early data was sent either; these three outcomes are not interchangeable.

    Ticket-policy evidence
    Eligible offer / server may decline
    Negotiation review
    Mode / key share / Finished scope
    Outcome evidence
    Fallback selected; handshake unfinished
  6. The decisions have separate producers

    In an actual review, the client ticket cache and eligibility policy explain offer eligibility, server TLS selection explains PSK acceptance, and endpoint verification explains the handshake outcome. Correlate them to the same new connection. Application commit requires its own application producer.

    Ticket-policy evidence
    Eligible offer / server may decline
    Negotiation review
    Client eligibility / server selection separate
    Outcome evidence
    Handshake unfinished; no commit

Ticket age

  1. The ticket’s time inputs were selected

    The ticket identity alias is atlas-ticket-1; clientReceiptSeconds=1000, elapsedAgeSeconds=900 and lifetimeSeconds=3600 are supplied. These are client-cache example inputs, not TLS ticket bytes or an actual client-clock measurement.

    Ticket-policy evidence
    Receipt 1000; age 900; lifetime 3600
    Negotiation review
    Eligibility not yet evaluated
    Outcome evidence
    Server acceptance unobserved
  2. The ticket at age 900 is eligible

    The first eligibility row satisfies 900 ≤ 3600 with true hashCompatible and serviceCompatible. All three predicates in the supplied policy hold, so expectedEligible=true. Client-side eligibility does not say the server accepted PSK.

    Ticket-policy evidence
    Age 900; hash/service compatible
    Negotiation review
    Eligibility true; server decision separate
    Outcome evidence
    Server acceptance unobserved
  3. Equality and exceeding lifetime differ

    Two separate comparison rows give expectedEligible=true at age 3600 seconds and false at 3601. This equality rule is the example’s explicit policy; it measures no other TLS implementation’s ticket acceptance or clock tolerance.

    Ticket-policy evidence
    Comparison: age 3600 / 3601
    Negotiation review
    Selected policy: true / false
    Outcome evidence
    Server acceptance unobserved
  4. An incompatible hash or service closes the gate

    The last two rows retain age=900. One has hashCompatible=false and the other serviceCompatible=false, making expectedEligible=false in both. A ticket within lifetime can still be ineligible for that context; no secret contents are shown.

    Ticket-policy evidence
    Age 900; two separate incompatible rows
    Negotiation review
    Hash false or service false → ineligible
    Outcome evidence
    Server acceptance unobserved
  5. Eligibility is not server acceptance

    Full-fallback is a separate comparison: ticketEligible=true can coexist with serverAcceptsPsk=false. Ticket-age rows produce no server response. Eligibility therefore establishes neither a selected PSK mode nor a completed handshake.

    Ticket-policy evidence
    Ticket-policy rows reviewed
    Negotiation review
    Client eligibility / server selection separate
    Outcome evidence
    Eligibility known; acceptance unknown
  6. Cache and endpoint evidence remain separate

    Client-cache receipt time, the clock used and hash/service policy produce the eligibility decision. Acceptance remains unknown without server selection for the same connection. This alias example runs no native cache, binder verification or application commit.

    Ticket-policy evidence
    Receipt/clock/policy producer required
    Negotiation review
    Client eligibility / server selection separate
    Outcome evidence
    Eligibility boundary known; runtime unmeasured

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Make mode and ticket policy observable

Configuration review should record negotiated mode, selected group, ticket-lifetime policy, and early-data policy separately. “TLS 1.3 enabled” does not prove selection of psk_dhe_ke. Whether PSK-only mode is accepted depends on the implementation and service profile; document the chosen security argument. Because ticket caches contain secret material, use limited outcome categories and short-lived correlation instead of dumping PSKs, tickets, or binders into diagnostic logs. Deployment BCP RFC9325 §3.4 recommends psk_dhe_ke with a fresh share; ticket-protection-key lifecycle and bounded ticket validity also support the security argument. Its older references to RFC8446 do not replace RFC9846 as the current protocol specification used here.

Define regression branches for normal tickets, expired tickets, hash mismatch, and server refusal. Preserve the condition that a full fallback requires suitable client full-handshake parameters. Absence of a Certificate message is not enough evidence of successful resumption: negotiated PSK context and Finished verification matter. The declarative fixture in this lesson does not substitute for TLS-stack telemetry.

Tie the early-data profile to application behavior

Atlas initially waits on mutating actions during 0-RTT. Opening a read-only class later needs more than a method list: specify side effects, authorization freshness, retries, server topology, and coordinated acceptance. An uncertain operation belongs after ordinary channel verification; resumption performance and early business execution remain separate settings.

Negative evidence is that no early message leaves the client and no application effect occurs. Positive evidence would show a request entering normal policy after a suitable ordinary handshake; this model does not execute that later part. Separate result concepts such as applicationDelivered, authenticatedPeer, and businessCommit. A waiting branch must not manufacture a successful purchase or note-publish outcome.

Preserve the current profile and its limits

RFC9846 replaces and obsoletes RFC8446 while retaining TLS version 1.3. Fresh key_share values must not be reused across connections under the current requirement. The artifact’s X25519 choice is a small example of asymmetric mode, not an implementation of KEM negotiation, actual HKDF bytes, or hardware-key lifecycle. Binder and Finished outcomes are explicit condition inputs rather than claimed cryptographic verification.

Client-cache expiry depends on clock and receipt context. In this fixture, 900≤3600 meets selected eligibility. That comparison does not cover every server ticket-age tolerance or anti-replay-window algorithm. Preserve client ticket eligibility separately from the server’s current acceptance decision.

NOW APPLY IT TO THE CASE

Which separate policy gates govern ticket eligibility and early execution?

The Atlas ticket may be eligible for notes.example.org while the server still declines PSK. The state-changing publish-note action is held during the early stage. Current application authorization remains necessary after establishing an ordinary channel.

Who is the peer of the case’s secure connection? Explain TLS peer trust, browser origin and user object permission as separate decisions.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas · Key exchange and session resumption

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "profile": {
    "protocol": "TLS 1.3",
    "currentSpecification": "RFC9846",
    "previousConnectionVerified": true,
    "newConnection": true,
    "actualTlsRun": false,
    "secretsExported": false
  },
  "ticket": {
    "identityAlias": "atlas-ticket-1",
    "pskAlias": "atlas-resumption-psk-1",
    "clientReceiptSeconds": 1000,
    "lifetimeSeconds": 3600,
    "elapsedAgeSeconds": 900,
    "kdfHash": "SHA-256",
    "originalService": "notes.example.org",
    "newService": "notes.example.org",
    "originalCertificateValidForNewService": true,
    "binderValidSelected": true
  },
  "roles": [
    {
      "alias": "c-x25519-new",
      "role": "fresh public share; private scalar stays local"
    },
    {
      "alias": "s-x25519-new",
      "role": "fresh public share; private scalar stays local"
    },
    {
      "alias": "atlas-resumption-psk-1",
      "role": "secret key-schedule input, not sent as plaintext"
    },
    {
      "alias": "c-app-new",
      "role": "new client application traffic secret alias, not old record key"
    },
    {
      "alias": "leaf-sign-private",
      "role": "certificate-based signature role, not used in selected PSK authentication"
    }
  ],
  "eligibilityCases": [
    {
      "age": 900,
      "hashCompatible": true,
      "serviceCompatible": true,
      "expectedEligible": true
    },
    {
      "age": 3600,
      "hashCompatible": true,
      "serviceCompatible": true,
      "expectedEligible": true
    },
    {
      "age": 3601,
      "hashCompatible": true,
      "serviceCompatible": true,
      "expectedEligible": false
    },
    {
      "age": 900,
      "hashCompatible": false,
      "serviceCompatible": true,
      "expectedEligible": false
    },
    {
      "age": 900,
      "hashCompatible": true,
      "serviceCompatible": false,
      "expectedEligible": false
    }
  ],
  "cases": [
    {
      "case": "normal",
      "offeredModes": [
        "psk_dhe_ke"
      ],
      "ticketEligible": true,
      "serverAcceptsPsk": true,
      "selectedMode": "psk_dhe_ke",
      "serverKeyShare": true,
      "certificateMessages": false,
      "ordinaryForwardSecrecyFromFreshAgreement": true,
      "handshakeCompletedSelected": true,
      "earlyDataSent": false,
      "businessCommit": false
    },
    {
      "case": "psk-only",
      "offeredModes": [
        "psk_ke"
      ],
      "ticketEligible": true,
      "serverAcceptsPsk": true,
      "selectedMode": "psk_ke",
      "serverKeyShare": false,
      "certificateMessages": false,
      "ordinaryForwardSecrecyFromFreshAgreement": false,
      "handshakeCompletedSelected": true,
      "earlyDataSent": false,
      "businessCommit": false
    },
    {
      "case": "full-fallback",
      "offeredModes": [
        "psk_dhe_ke"
      ],
      "ticketEligible": true,
      "serverAcceptsPsk": false,
      "fullParametersOffered": true,
      "selectedMode": "certificate-full",
      "serverKeyShare": true,
      "certificateMessages": true,
      "ordinaryForwardSecrecyFromFreshAgreement": true,
      "handshakeCompletedSelected": false,
      "earlyDataSent": false,
      "businessCommit": false
    },
    {
      "case": "early-wait",
      "offeredModes": [
        "psk_dhe_ke"
      ],
      "ticketEligible": true,
      "serverAcceptsPsk": null,
      "selectedMode": null,
      "serverKeyShare": null,
      "certificateMessages": null,
      "ordinaryForwardSecrecyFromFreshAgreement": null,
      "handshakeCompletedSelected": false,
      "earlyDataSent": false,
      "businessCommit": false
    }
  ],
  "earlyPolicy": {
    "operation": "publish-note",
    "mutatesState": true,
    "allowedBeforeHandshake": false,
    "replayExecutionPerformed": false,
    "ordinaryAuthorizationRequired": true,
    "earlyDataForwardSecrecyAssumed": false,
    "crossConnectionNonReplayGuaranteed": false
  }
}
ticket
Identity alias differs from the secret PSK; lifetime and service context constrain client eligibility.
cases
Selected mode, fresh share, certificate branch, and completion are separate outcomes.
earlyPolicy
A mutating operation waits at its local policy gate; no early message is sent.

Opaque aliases and selected boolean conditions only; no actual ticket, PSK, binder, HKDF, handshake, or repeated-message execution. Age comparison is a bounded client-eligibility check, not full TLS validation.

Two reality checks

Resumption reuses the old TLS key unchanged.

A new transcript produces a new traffic context; the PSK is an input linked to an earlier connection.

Enabling resumption makes 0-RTT safe and mandatory.

0-RTT is a separate choice with weaker cross-connection non-replay and forward-secrecy scope.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

In the PSK-only case, serverKeyShare=false. Is forward secrecy from fresh agreement present?

  1. No; the selected PSK-only branch has no fresh agreement.
  2. Yes; every resumption performs the same fresh ephemeral agreement.
Read the explained answer

No; the selected PSK-only branch has no fresh agreement. — ordinaryForwardSecrecyFromFreshAgreement=false; a resumption label is not a fresh-DHE guarantee.

Why is full-fallback possible while ticket age is within lifetime?

Selected lesson artifact fields; teaching example

ticket.elapsedAgeSeconds
900
ticket.lifetimeSeconds
3600
cases[2].serverAcceptsPsk
false
cases[2].selectedMode
certificate-full
  1. An eligible ticket does not guarantee server acceptance of the PSK.
  2. The server must accept the PSK because its lifetime is valid.
Read the explained answer

An eligible ticket does not guarantee server acceptance of the PSK. — The selected serverAcceptsPsk=false branch falls back to full certificate parameters; the handshake is not yet considered complete.

Why is publish-note disallowed before the ordinary phase? Which application check remains necessary afterward?

Read the explained answer

Publish-note changes state; the selected early policy defers repeated-effect risk to the ordinary handshake phase. Ordinary authorization is still required afterward. PSK identity carries prior context; it supplies neither application user/tenant permission nor business exactly-once outcomes.

□ I tied early-data permission to operation effects.

□ I preserved authorization in the ordinary phase.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope