Hacker DirectoryHacker Directory

WEB / WEB-17.04

WebSocket, SSE and webhooks

Which permission and business outcomes remain unproven by an open channel or verified event?

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Allowed message

  1. Message ready

    The browser prepares book-read for book-A on an established channel. The API’s session context is already declared reader-A/tenant-A; this message has not yet reached the API.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Channel established; no message
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  2. Message arrived

    The book-read/book-A message reached the API. It evaluates the object selection using its own reader-A/tenant-A session context; object-tenant and read permission are still undecided.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Message arrived; policy pending
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  3. Local message gate

    The current session is valid and book-A belongs to tenant-A. reader-A is allowed book-read; the API prepares a service read with the subject/object/action context.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Message allowed; service request ready
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  4. Service request arrived

    The owned service received the ordinary read request; its local policy and lookup are still pending.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Message allowed; service request ready
    Book service
    Read request arrived; lookup pending
    Event provider
    Inactive in this branch
  5. Local service read

    The service accepts the declared read context under its own policy, looks up Atlas Notları for book-A locally and prepares the response. The API has not received it yet.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Message allowed; service request ready
    Book service
    book-A title ready; no effect
    Event provider
    Inactive in this branch
  6. Service result arrived

    The service response reached the API; the browser message has not yet been prepared or sent.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Service result arrived; mapping pending
    Book service
    book-A title ready; no effect
    Event provider
    Inactive in this branch
  7. Local channel mapping

    The API checks the selected result shape and correlation, then prepares a title message for the channel.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Browser title message ready
    Book service
    book-A title ready; no effect
    Event provider
    Inactive in this branch
  8. Title message arrived

    The WebSocket message carrying Atlas Notları reached the browser. The title is now known there; message receipt proves neither a DOM update nor handshake/frame-parser execution in this scene.

    Browser
    Title received: Atlas Notları; DOM separate
    Atlas API
    Browser title message ready
    Book service
    book-A title ready; no effect
    Event provider
    Inactive in this branch

Message denied

  1. Normal read ready

    The browser prepares book-read for book-A on an established channel. The API’s session context is already declared reader-A/tenant-A; this message has not yet reached the API.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Channel established; no message
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  2. Message arrived

    The book-read/book-A message reached the API. It evaluates the object selection using its own reader-A/tenant-A session context; object-tenant and read permission are still undecided.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Message arrived; policy pending
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  3. Local deny

    The session is valid, but reader-A belongs to tenant-A and book-A belongs to tenant-B in this branch. Object reading is denied; no service request is prepared, only a denial message.

    Browser
    book-read / book-A ready; no title
    Atlas API
    Policy denied; denial ready
    Book service
    No request; no effect
    Event provider
    Inactive in this branch
  4. Denial arrived

    The ordinary denial reached the browser; no request or resource result passed through the service.

    Browser
    Denial received; no title
    Atlas API
    Policy denied; denial ready
    Book service
    No request; no effect
    Event provider
    Inactive in this branch

SSE duplicate

  1. After resume

    The declared reconnect/history selection is complete; the API prepared event-2 but the browser has not received it.

    Browser
    lastID event-1; apply=0
    Atlas API
    SSE established; event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  2. Block arrived

    The complete SSE text block reached the browser; EventSource parsing and dispatch remain pending here.

    Browser
    Block arrived; parse pending; apply=0
    Atlas API
    SSE established; event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  3. Local event parse

    The selected blank-line block parser reads event-2/data/retry; the application has not yet applied the event.

    Browser
    lastID event-2; event ready; apply=0
    Atlas API
    SSE established; event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  4. Local apply

    The application adds event-2 to its seen-ID set and applies the title once; this is not durable-transaction evidence.

    Browser
    event-2 seen; apply=1
    Atlas API
    SSE established; event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  5. Normal duplicate ready

    Ordinary delivery history prepares the same event-2 block again, exposing the absence of a transport exactly-once guarantee.

    Browser
    event-2 seen; apply=1
    Atlas API
    Duplicate event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  6. Duplicate block arrived

    The second ordinary block reached the browser; the prior title application remains one effect while deduplication is pending.

    Browser
    Duplicate block arrived; apply=1; pending
    Atlas API
    Duplicate event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  7. Local parse again

    The parser produces event-2 again; the same last ID is not a business acknowledgement or unique-event guarantee.

    Browser
    event-2 parsed again; apply=1
    Atlas API
    Duplicate event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch
  8. Local dedupe

    The app seen-ID set recognizes the duplicate and skips a second apply; the final count stays one in this fixed fixture.

    Browser
    Duplicate skipped; apply=1
    Atlas API
    Duplicate event-2 block ready
    Book service
    Inactive in this branch
    Event provider
    Inactive in this branch

Webhook duplicate

  1. Receipt prepared

    The provider prepared an ordinary event-W delivery; the owned receiver already marks that event as processed.

    Browser
    Inactive in this branch
    Atlas API
    event-W processed; effect=1; no receipt
    Book service
    No new job; effect=1
    Event provider
    event-W ordinary delivery ready
  2. Webhook arrived

    The HTTP event receipt reached the owned API; exact-byte integrity and delivery-freshness gates remain pending.

    Browser
    Inactive in this branch
    Atlas API
    Raw receipt arrived; verification pending
    Book service
    No new job; effect=1
    Event provider
    event-W ordinary delivery ready
  3. Local receipt gate

    This example declares a trusted endpoint key and a valid signature over the exact raw body. The age of 30 from now=1000 and signedTime=970 is within tolerance=60; deduplication is not yet decided.

    Browser
    Inactive in this branch
    Atlas API
    Receipt valid declared; dedupe pending
    Book service
    No new job; effect=1
    Event provider
    event-W ordinary delivery ready
  4. Local idempotency

    The already-processed consumer-A/event-W ledger skips a second job; effect count stays one and a 200 receipt is prepared.

    Browser
    Inactive in this branch
    Atlas API
    Duplicate accepted; effect=1; 200 ready
    Book service
    No new job; effect=1
    Event provider
    event-W ordinary delivery ready
  5. Receipt ack arrived

    The provider received the owned receiver’s 200 receipt; it is neither a new business-job completion nor a browser update.

    Browser
    Inactive in this branch
    Atlas API
    Duplicate accepted; effect=1; 200 ready
    Book service
    No new job; effect=1
    Event provider
    200 receipt received; effect outcome unknown

ACTORS · STATE · DATA FLOW

WebSocket messages, frames and permission

WebSocket is a long-lived bidirectional message channel: browser and server can send application messages independently. The HTTP/1.1 profile establishes it using a GET/Upgrade handshake and a successful 101 response. With negotiated RFC 8441 support, HTTP/2 uses extended CONNECT and :protocol=websocket rather than copying H1 Connection/Upgrade headers or a 101 response. One H2 stream can carry WebSocket while other streams continue ordinary HTTP work. Support is not assumed for every browser/proxy combination.

One text message can span multiple WebSocket frames; frame boundaries are neither TCP-segment boundaries nor JSON-member boundaries. Masking does not provide confidentiality; wss and correct TLS peer checks are separate secure-transport concerns. Atlas declares an already authenticated connection, but evaluates subject/object/action policy when a book-read message arrives. A permitted message creates an ordinary request to the owned book service; a denial creates no service request. The scene follows this established channel’s message decision without executing the handshake.

SSE: receiving an event is not acknowledging work

Server-Sent Events carries text/event-stream from server to browser in an HTTP response body; EventSource does not send browser-to-server application messages through that same stream. In UTF-8 lines, data supplies payload, event selects the event type, id affects reconnection context, and numeric retry adjusts reconnection timing. A blank line triggers dispatch of accumulated data; a TCP chunk alone is not a complete event. Our block contains id:event-2 and an ordinary book title, keeping the parser’s line buffer separate from UI state.

On reconnection, EventSource reports a nonempty last event ID in Last-Event-ID; how much history the server can resume is an application contract. Receiving an event ID does not prove a committed business transaction, and duplicate-event handling requires application deduplication. A normal retry can deliver event-2 again; the fixture keeps the UI apply count at one. Expired history needs recovery such as a full snapshot refresh. The scene begins after reconnection/history selection and does not execute a real EventSource, retry timer or browser reconnect.

Webhook: provider server to owned receiver

A webhook is not a browser-opened stream: a provider server delivers an event to an owned receiver using a separate HTTP request. A 2xx receipt indicates acceptance, not automatic completion of downstream business work. The reviewed Stripe provider profile describes possible duplicates and out-of-order arrivals. Atlas uses a generic book.updated event alias, with no real Stripe event, account or endpoint. A browser reading a book from an API and a provider delivering a webhook have different authentication, direction and lifetimes.

Receipt integrity requires exact raw-byte verification under the provider profile and a previously trusted endpoint key. Equivalent JSON parsed and reserialized is not necessarily the same bytes. Freshness of a signed delivery timestamp differs from the event’s creation time; an ordinary retry can have a new delivery timestamp. A valid receipt can still be a duplicate. The selected idempotency ledger already marks consumer-A/event-W processed, accepts the receipt and creates no second business effect. Cryptographic validity is declared here; no signature generation, replay or provider SDK is executed.

2. Red · Trust & Impact

Read every scenario without motion

Message authority

  1. Channel and message context were separated

    The channel is declared established and the session valid. In the policy-denied message row, reader-A belongs to tenant-A while the requested object belongs to tenant-B.

    Channel/body record
    Channel established
    Resource/verification gate
    Object tenant-B
    Delivery/effect boundary
    No service call
  2. The action and object boundary was selected

    The action is book-read. A well-shaped message arriving on an open connection does not grant permission for a foreign-tenant object.

    Channel/body record
    Action: book-read
    Resource/verification gate
    Subject tenant-A ≠ object tenant-B
    Delivery/effect boundary
    Policy pending
  3. Per-message policy denial was established

    The row declares expected=false. The gate reviews object/action context; an accepted handshake cannot convert this denial into allow.

    Channel/body record
    Session valid=true
    Resource/verification gate
    Object permission=false
    Delivery/effect boundary
    Service call withheld
  4. No downstream transfer was produced

    No book data is prepared and no read is dispatched to the service for the foreign object. An unchanged service after denial is this branch’s concrete boundary.

    Channel/body record
    Message received in ledger
    Resource/verification gate
    Policy deny known
    Delivery/effect boundary
    No downstream read
  5. Connection lifetime was not equated with permission

    A long-lived channel does not prevent session conditions from changing. This row shows a known tenant mismatch; logout, expiry and heartbeat outcomes are separate questions.

    Channel/body record
    Tenant mismatch known
    Resource/verification gate
    Lifetime policy separate
    Delivery/effect boundary
    No object body
  6. Handshake protocol remained separate

    HTTP/1.1 Upgrade and negotiated HTTP/2 extended CONNECT are different bootstrap profiles. This application permission row proves neither frame parsing nor execution of those bootstraps.

    Channel/body record
    Application deny known
    Resource/verification gate
    Bootstrap profile separate
    Delivery/effect boundary
    No broader protocol claim

Signed-byte link

  1. Two webhook body forms were read

    rawBody and reserializedBody can carry the same eventId, type and bookId values. Their byte representations differ in field order and whitespace.

    Channel/body record
    Event: event-W
    Resource/verification gate
    Two byte representations
    Delivery/effect boundary
    Verification pending
  2. The verification input was bounded

    Exact-byte verification is bound to the signed body. Parsing and reserializing JSON cannot be assumed to preserve the signed byte sequence.

    Channel/body record
    Values may match
    Resource/verification gate
    Bytes differ
    Delivery/effect boundary
    Raw body required
  3. Key provenance became a separate check

    In the untrusted-key row, signatureValidDeclared=true but keyProvenanceDeclared=false. A mathematical signature outcome cannot replace trusted endpoint-key provenance.

    Channel/body record
    Signature declared=true
    Resource/verification gate
    Key provenance=false
    Delivery/effect boundary
    Receipt pending
  4. Receipt-gate denial was established

    This row declares receiptAccepted=false and newEffect=0. Fresh signed time and matching bytes cannot create acceptance with untrusted key provenance.

    Channel/body record
    Integrity condition declared
    Resource/verification gate
    Receipt accepted=false
    Delivery/effect boundary
    New effect=0
  5. A signature was not treated as uniqueness

    Even a trusted normal signature does not mean the event was never processed. Signature, freshness and consumer/event deduplication are three separate decisions.

    Channel/body record
    Signature ≠ uniqueness
    Resource/verification gate
    Freshness separate
    Delivery/effect boundary
    Dedupe separate
  6. The concept remained within the byte fixture

    This review compares two inert strings and a declared receipt table. It does not establish actual SDK verification, key management or provider delivery.

    Channel/body record
    Bytes comparison known
    Resource/verification gate
    Key denial known
    Delivery/effect boundary
    No live delivery claim

ASSUMPTION · BOUNDARY · CONTROL

Treating an established channel as unlimited permission

Accepting a WebSocket handshake does not authorize every subsequent message. A subject’s session can expire, an object can belong to another tenant, or an action can lie outside the channel profile. Even a structurally valid message needs a resource decision. The fixture’s policy-denied branch receives an ordinary book-read message, creates no service call when declared object permission is absent, and returns a normal denial result. This models the required control boundary rather than a bypass attempt against a real target.

A service trusting only its connection from the API extends the same problem. A request known to come from the API still needs the right subject/object/context, and the downstream service enforces its owned policy. Browser Origin is useful in handshake review but is not signed identity or business permission for every client. WSS does not approve application work. Red review therefore asks who prepared each message, which actor established trusted context, and which later transfer is entirely absent after denial.

Delivered and processed once are different claims

SSE lastEventId is not an application acknowledgement protocol; updating a parser’s ID and applying an event to UI state are separate events. Likewise, a valid webhook signature promises no exactly-once delivery. If an ordinary duplicate causes a second business effect, the failed assumption equates integrity with idempotency. Normalizing JSON before verification is a different issue: an equivalent value tree can alter the signed byte representation. This lesson demonstrates raw-body inequality with two inert strings rather than generating and redelivering a signed event.

Sorting receipts by event-created timestamps does not create business ordering; distinct events can share the same second. Passing freshness also does not mean the consumer has never seen an event ID. Deduplication retention, durable queues and transaction boundaries must fit together. A correct in-memory processed alias cannot guarantee one effect after a crash or across concurrent workers. The artifact compares a first receipt, a duplicate and a declared stale receipt; it performs no operational replay automation or live provider call.

3. Blue · Secure development & defense

Read every scenario without motion

SSE duplicate

  1. Event-stream fields were read

    The SSE block contains id=event-2, event=book, retry=1000 and data=Atlas Notları. retry expresses reconnection preference, not exact delivery timing or application acknowledgement.

    Delivery observation
    id=event-2
    ID/time/consumer binding
    retry=1000
    Review conclusion
    Apply count pending
  2. Delivery history was bound to the record

    eventDeliveries contains event-2 twice. This previously established history is not read as an exactly-once stream-transport guarantee.

    Delivery observation
    Deliveries: event-2 × 2
    ID/time/consumer binding
    Exactly-once=false
    Review conclusion
    App dedupe under review
  3. Parser ID and effect were separated

    Last-Event-ID state alone does not establish that an event was processed and applied to the UI. Seen-ID deduplication is separate application state.

    Delivery observation
    Parser/event ID state
    ID/time/consumer binding
    Application seen-ID state
    Review conclusion
    Ack=false
  4. The expected apply count was matched

    expectedApplyCount=1 is the expected result for this duplicate history. Two deliveries versus one effect reflects application deduplication, not a duplicate-free stream.

    Delivery observation
    Delivery count=2
    ID/time/consumer binding
    Expected apply count=1
    Review conclusion
    Dedupe boundary known
  5. Resume guarantees were not expanded

    This history does not fully show how retained events are found. Expired-cursor recovery and server-history retention need separate contracts and observations.

    Delivery observation
    Duplicate history known
    ID/time/consumer binding
    Retention evidence separate
    Review conclusion
    No universal resume guarantee
  6. The review conclusion was bound to the application

    The review concerns a policy reducing two ordinary event records to one apply. It establishes neither actual browser reconnection, wall-clock delay nor durable effects.

    Delivery observation
    Expected apply=1
    ID/time/consumer binding
    Transport not exactly-once
    Review conclusion
    Runtime recovery unobserved

Receipt and effect

  1. Signed time and event time were separated

    eventCreated=800, deliverySignedTime=970 and now=1000. This example binds freshness to delivery-signature time; event creation time does not guarantee business ordering.

    Delivery observation
    Signed time=970
    ID/time/consumer binding
    now=1000; tolerance=60
    Review conclusion
    Receipt review pending
  2. The freshness condition was assessed

    The normal signed time is 30 units old and within the selected 60-unit tolerance. This is the example’s policy, not a provider default.

    Delivery observation
    Age=30
    ID/time/consumer binding
    Selected tolerance=60
    Review conclusion
    Freshness acceptable
  3. The processed-event binding was found

    initialProcessed contains consumer-A/event-W with initialEffectCount=1. This history is established before the duplicate receipt.

    Delivery observation
    Consumer/event already retained
    ID/time/consumer binding
    Initial effect count=1
    Review conclusion
    Duplicate branch selected
  4. Receipt acceptance created no new effect

    The duplicate row has receiptAccepted=true and newEffect=0. duplicateReceiptStatus can be 200 while finalEffectCount remains 1; acknowledgement is not a new business effect.

    Delivery observation
    Receipt accepted=true
    ID/time/consumer binding
    New effect=0
    Review conclusion
    Final effect count=1
  5. The stale receipt was separated by cause

    The stale-declared row exceeds the selected tolerance with 100 units between signedTime=900 and now=1000. This denial is not confused with duplicate deduplication.

    Delivery observation
    Duplicate: accepted, no effect
    ID/time/consumer binding
    Stale: not accepted
    Review conclusion
    Causes separate
  6. Durability and concurrency remained unknown

    This ledger separates receipt and effect decisions. With concurrencyExecuted=false, it proves neither crash recovery nor a single effect across parallel workers.

    Delivery observation
    Receipt/effect split known
    ID/time/consumer binding
    Concurrency unobserved
    Review conclusion
    No durability guarantee

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Decisions and lifetime at the message boundary

An owned channel profile defines message types, actions, allowed object scope, size and ordinary rate limits. The server establishes trusted session/context, evaluates object/action permission per message and produces protected data only after allowing it. Define channel invalidation after session expiry or logout; a login check performed only at the handshake is insufficient for a long-lived connection. Proxy timeout, application heartbeat and protocol ping/pong are different liveness signals; a pong proves no book-read permission.

Carry the minimum required subject/resource context on API-to-service requests and validate the returned shape. The browser matches message schema and correlation aliases so an old reply is not mistaken for a new read. In the model, the service card must remain unchanged after a local policy denial: the recorded local no-dispatch decision is positive evidence, while a missing service log alone is not. Handshake, TLS, frame parsing and flow control are outside this application scene, so UI-state checks cannot substitute for native browser/WebSocket support tests.

Resume, receipt and durable-effect ledgers

An SSE contract defines retained history, Last-Event-ID interpretation, expired-cursor recovery and application event deduplication. The fixture keeps the UI apply count at one across two ordinary deliveries of event-2; parser ID state and the application’s seen-ID set are distinct. Client close and a server HTTP 204 that stops reconnection belong in recovery design. A numeric retry value is not a delivery guarantee, and browser backoff or network conditions prevent a claim of an exact wall-clock schedule.

The webhook receiver preserves raw content, selects an approved endpoint key from trusted configuration and evaluates signed delivery time under its tolerance policy. The artifact’s 60 seconds are an instructional choice, distinct from the Stripe library default of five minutes. After integrity/freshness pass, bind the consumer/event key to durable acceptance and the business effect within a consistent boundary; an early 2xx must not conceal lost work. A duplicate may receive a successful acknowledgement without changing effect count. Crash recovery and concurrent storage atomicity additionally require durable ledger and commit behavior.

NOW APPLY IT TO THE CASE

Which business decision is not proved by an open channel or accepted receipt?

WebSocket object policy, SSE event deduplication and webhook receipts have different gates. Normal delivery history, signed bytes and effect counts are read in context.

Examine the case API contract separately from the representation readable by the browser. Discuss sufficient evidence for envelope, data, errors and resource permission.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Atlas channel and receipt decision table

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

Read the raw artifact and field explanations
{
  "profile": {
    "actualNetwork": false,
    "actualProtocol": false,
    "actualCrypto": false,
    "channelEstablishedDeclared": true,
    "sessionValidDeclared": true,
    "serviceTransport": "ordinary owned read request",
    "webhookProviderExample": "Stripe documentation only; generic Atlas aliases"
  },
  "channelComparison": [
    {
      "kind": "WebSocket",
      "direction": "browser <-> API",
      "lifetime": "established bidirectional message channel"
    },
    {
      "kind": "SSE",
      "direction": "API -> browser",
      "lifetime": "HTTP event stream"
    },
    {
      "kind": "Webhook",
      "direction": "provider -> owned API receiver",
      "lifetime": "separate HTTP deliveries"
    }
  ],
  "websocketProfiles": [
    {
      "http": "HTTP/1.1",
      "method": "GET",
      "bootstrap": "Upgrade",
      "success": 101,
      "stream": "connection"
    },
    {
      "http": "HTTP/2 with RFC8441 negotiated support",
      "method": "CONNECT",
      "protocol": "websocket",
      "success": 200,
      "stream": "single H2 stream",
      "connectionUpgradeHeaders": false
    }
  ],
  "messageLayers": {
    "application": "one JSON book-read message",
    "websocketFrames": "one or more; boundaries not fixed by app",
    "tcpSegments": "byte stream segmentation independent",
    "maskingIsEncryption": false
  },
  "messageRows": [
    {
      "case": "normal",
      "subject": "reader-A",
      "tenant": "tenant-A",
      "objectTenant": "tenant-A",
      "action": "book-read",
      "sessionValid": true,
      "expected": true
    },
    {
      "case": "policy-denied",
      "subject": "reader-A",
      "tenant": "tenant-A",
      "objectTenant": "tenant-B",
      "action": "book-read",
      "sessionValid": true,
      "expected": false
    }
  ],
  "sse": {
    "block": "id: event-2\nevent: book\nretry: 1000\ndata: Atlas Notları\n\n",
    "initialLastId": "event-1",
    "parsed": {
      "id": "event-2",
      "event": "book",
      "retry": 1000,
      "data": "Atlas Notları"
    },
    "eventDeliveries": [
      "event-2",
      "event-2"
    ],
    "expectedApplyCount": 1,
    "selectedHistoryEstablishedBeforeScene": true,
    "exactlyOnceTransport": false,
    "appAck": false
  },
  "webhook": {
    "rawBody": "{\"eventId\":\"event-W\",\"type\":\"book.updated\",\"bookId\":\"book-A\"}",
    "reserializedBody": "{\"bookId\": \"book-A\", \"eventId\": \"event-W\", \"type\": \"book.updated\"}",
    "configuredKeyAlias": "trusted-endpoint-key-A",
    "consumer": "consumer-A",
    "eventId": "event-W",
    "eventCreated": 800,
    "deliverySignedTime": 970,
    "now": 1000,
    "tolerance": 60,
    "toleranceIsProviderDefault": false,
    "signatureValidDeclared": true,
    "exactBytesVerifiedDeclared": true,
    "keyProvenanceDeclared": true,
    "initialProcessed": [
      "consumer-A/event-W"
    ],
    "initialEffectCount": 1,
    "receiptRows": [
      {
        "case": "first",
        "signedTime": 970,
        "now": 1000,
        "signatureValidDeclared": true,
        "exactBytesVerifiedDeclared": true,
        "keyProvenanceDeclared": true,
        "previouslyProcessed": false,
        "receiptAccepted": true,
        "newEffect": 1
      },
      {
        "case": "duplicate",
        "signedTime": 970,
        "now": 1000,
        "signatureValidDeclared": true,
        "exactBytesVerifiedDeclared": true,
        "keyProvenanceDeclared": true,
        "previouslyProcessed": true,
        "receiptAccepted": true,
        "newEffect": 0
      },
      {
        "case": "stale-declared",
        "signedTime": 900,
        "now": 1000,
        "signatureValidDeclared": true,
        "exactBytesVerifiedDeclared": true,
        "keyProvenanceDeclared": true,
        "previouslyProcessed": false,
        "receiptAccepted": false,
        "newEffect": 0
      },
      {
        "case": "untrusted-key",
        "signedTime": 970,
        "now": 1000,
        "signatureValidDeclared": true,
        "exactBytesVerifiedDeclared": true,
        "keyProvenanceDeclared": false,
        "previouslyProcessed": false,
        "receiptAccepted": false,
        "newEffect": 0
      }
    ],
    "finalEffectCount": 1,
    "duplicateReceiptStatus": 200,
    "concurrencyExecuted": false
  },
  "boundaries": {
    "connectionGrantsObjectPermission": false,
    "receiptEqualsBusinessCompletion": false,
    "eventCreatedOrdersBusiness": false,
    "signatureMeansUnique": false
  }
}
channelComparison
Three different actor directions and lifetimes.
websocketProfiles
H1 Upgrade differs from negotiated H2 extended CONNECT.
messageRows
Selected per-message resource gate after connection establishment.
sse
Normal event block, parser ID and separate application apply count.
webhook
Raw bytes and declared integrity/freshness/idempotency receipt ledger.

Inert ordinary event/read data; cryptography is declared, while raw-body string differences and selected gates are calculated. No actual channel, reconnect, SDK, signature, queue or concurrent durable storage is executed.

Two reality checks

An authenticated WebSocket permits every message.

Each action/object needs trusted session/context policy; an established channel is only a transport state.

A signed webhook and an SSE ID provide exactly-once work.

Integrity and resume context do not eliminate duplicate delivery; application idempotency and durable-effect boundaries remain separate.

YOUR TURN

Work through this story.

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

WebSocket sessionValid is true; the message objectTenant is tenant-B and the subject tenant-A. Is the selected message accepted?

  1. Yes; the opening handshake authorizes every subsequent object.
  2. No; the message is policy-denied.
Read the explained answer

No; the message is policy-denied. — An established channel provides no object entitlement for all messages; current tenant/action must be checked.

A duplicate receipt is accepted but newEffect is 0. Is that contradictory?

Selected lesson artifact fields; teaching example

webhook.receiptRows[1]
{"case":"duplicate","signedTime":970,"now":1000,"signatureValidDeclared":true,"exactBytesVerifiedDeclared":true,"keyProvenanceDeclared":true,"previouslyProcessed":true,"receiptAccepted":true,"newEffect":0}
webhook.finalEffectCount
1
  1. No; an authenticated duplicate is acknowledged without repeating the effect.
  2. Yes; every accepted delivery requires a new business write.
Read the explained answer

No; an authenticated duplicate is acknowledged without repeating the effect. — PreviouslyProcessed=true is consumer/event dedupe context. A valid signature does not guarantee uniqueness.

Which three distinct boundaries are provided by SSE retry/id, WebSocket frames and exact webhook-body verification?

Read the explained answer

SSE provides reconnect id/history correlation on a server→client stream, not exactly-once or an app ACK. A WebSocket message may span multiple frames; TCP segments are independent and masking is not encryption. Webhook verification requires a trusted endpoint key and exact received bytes; reserialization may preserve object meaning without preserving signed bytes.

□ I did not count an SSE id as exactly-once.

□ I separated WebSocket framing from webhook-byte authenticity.

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

Sources and scope