When a WebSocket authorized at open is still accepting commands an hour after its credential expired, what are your options?
answer
- authorized once, at the handshake
- frames carry no credential
- refresh, close, or cap
- pings prove liveness, not identity
- revocation needs a principal-to-connection index
basics
~20 sThree, and they are the whole list: re-authenticate in band over the open socket, close the connection when the credential expires, or cap connection lifetime so a socket never outlives the credential that opened it.
solid answer
~40 sThe WebSocket protocol authorizes once, at the handshake, and then knows nothing about credentials — it will carry frames for as long as the TCP connection survives. So a socket opened at the start of a shift is still carrying commands long after the token behind it expired, and nothing in the protocol notices. The honest answers are: **re-authenticate in band**, sending a fresh credential as an application frame before the old one lapses; **close on expiry**, recording the expiry time at open and sending a close frame when it arrives; or **cap the lifetime** so every socket is reopened, and re-authorized, on a fixed schedule. Revocation is the same problem arriving early: the server must find the connections bound to that principal and close them.
code
pseudocode · 17 lineson handshake_accepted(connection, credential):
connection.principal = credential.subject
connection.expires_at = credential.expires_at
index.add(connection.principal, connection)
schedule expiry_check(connection) at connection.expires_at
function expiry_check(connection):
if connection.expires_at > now(): // refreshed in band already
schedule expiry_check(connection) at connection.expires_at
return
send close frame with a policy-violation status
close connection
on revoked(subject):
for each connection in index.lookup(subject):
send close frame
close connectiongo deeper
Know that a WebSocket is authorized only on the request that opens it, and that afterwards the frames themselves carry no credential of any kind.
Explain the three responses — refresh in band, close at expiry, cap lifetime — and why ping and pong frames prove liveness rather than identity.
Give the costs alongside the options, and treat revocation as separate machinery: a principal-to-connection index and a close frame, not a database write.
Decide the connection lifetime the product can live with, knowing every bound you pick converts a security question into reconnect load you must then absorb.
## The gap the protocol leaves A WebSocket connection is authorized exactly once, on the HTTP request that opens it. After the handshake completes there is no credential on the wire at all: frames carry an opcode, a length, a mask and a payload, and nothing else. The server knows who is on the other end only because it wrote that down at open and attached it to the connection. So a connection outlives its credential trivially. A console opened at the start of a shift holds one TCP connection for eight hours; the credential that opened it was good for fifteen minutes. **Nothing in the protocol notices, and nothing in it will.** On a cabinet that dispenses controlled substances, that is the difference between "this clinician is authorized right now" and "this clinician was authorized this morning." ## The three honest answers ### 1. Re-authenticate in band The client sends a fresh credential as an ordinary application message before the current one lapses; the server validates it and updates the expiry it holds for that connection. The socket never closes. - Keeps the connection, which is the whole reason you opened one. - Costs you a message type, a client that tracks its own expiry, and a decision about what happens when the refresh does not arrive — which is answer 2 with extra steps. - The credential is now in a frame, so whatever logs frames is now a place a credential lands. ### 2. Close when the credential expires Record the credential's expiry at open. When it arrives without a refresh, send a close frame — a policy-violation status is the conventional choice — and drop the connection. The client reconnects, which means a fresh handshake, which means a fresh authorization. - Simple, and it fails closed. - The cost is a reconnect the user may notice, and a fleet of clients that all reconnect when a batch of credentials issued together expires together. Stagger the expiries or the reconnects. ### 3. Cap connection lifetime Decide that no socket lives longer than some bound — shorter than any credential's lifetime — and close every connection at that age regardless of credential state. The question never arises. - Blunt, predictable, and it also solves problems that have nothing to do with credentials: connections pinned to a node that was balanced hours ago, memory that only a reconnect reclaims. - The cost is reconnect churn you now pay unconditionally. | Approach | Connection survives | Client work | Fails | |---|---|---|---| | Re-authenticate in band | yes | tracks expiry, sends refresh | open, unless you also do 2 | | Close on expiry | no | reconnects when told | closed | | Cap lifetime | no | reconnects on a schedule | closed | Most real systems run 1 and 2 together: refresh in band, and close if no refresh arrives. ## Revocation is the same problem, arriving early When a session is revoked — a badge deactivated, a clinician's access pulled mid-shift — the credential has not expired; it has been withdrawn. The socket is unaffected unless something acts. That something is a **reverse index**: the server must be able to go from a principal to the open connections bound to it, and close them. Without that index, revocation is a database write that changes nothing about the connection currently issuing dispense commands. Two details people miss: 1. The index has to be maintained wherever the connection lives, and revocation may be handled by a different process than the one holding the socket. Getting the signal to the right place is part of the design, not an afterthought. 2. "Close them" means sending a close frame and dropping the connection, **not** marking the session invalid and waiting for the client to notice. The client will not notice; there is nothing for it to notice with. ## What does not work - **Waiting for the next ping.** Ping and pong control frames prove the connection is alive. They carry no principal and validate nothing. - **Assuming per-frame checks happen.** No conforming implementation revalidates a credential per frame, because no frame carries one. - **Relying on the client to disconnect.** A client whose token expired may keep the socket open forever, and a malicious one certainly will. ## What an interviewer is listening for That you notice the gap unprompted, that you give three options with their costs rather than one favourite, and that you treat revocation as its own requirement with its own machinery — because that is the one that gets left out.
- If you refresh in band, what does the server do when no refresh arrives?Exactly what it would have done without the refresh mechanism: send a close frame at the recorded expiry and drop the connection. In-band refresh is an optimisation that keeps a healthy connection alive; it is not a replacement for the expiry deadline, and a design that only refreshes and never closes has no enforcement at all.
- Why does a fleet of clients reconnecting on expiry need attention?Because credentials issued together expire together. If a batch of consoles authenticated at shift change, they will all be closed within the same second and all reconnect within the same second, and each reconnect is a fresh handshake plus whatever authentication sits behind it. Stagger the expiry times, or have clients rejoin after a randomised delay.
- Where does revocation fall down most often in practice?In not being able to find the connection. The revocation is recorded correctly, and nothing walks from that principal to the open sockets bound to it — especially when the socket is held by a different process than the one handling the revocation. Without that path, a revoked principal keeps issuing commands until it disconnects on its own.
A badge reader at the door checks you once as you walk in, and then you are simply inside. Nothing re-reads the badge while you are standing there, so if the badge is cancelled at noon, someone has to come and ask you to leave.
saying these in an interview costs you the question
- Believes the protocol closes a socket when its credential expires
- Thinks the server revalidates a credential on every frame
- Uses ping and pong control frames to re-check who is connected
- Assumes revoking a session ends connections already open
- Relies on the client to disconnect when its own token lapses
- Ignores that credentials issued together also expire together