HTTP forgets you between requests, so a cookie carries an opaque reference that the server looks up to find who is calling. The cookie is a bearer credential: whoever holds it is treated as that signed-in person, which is why its attributes matter and why every request is still checked against what that caller may actually do.
The useful design is the boring one. The cookie holds an unguessable reference and nothing else; the record it points at — who signed in, when, which workspace, whether this is a customer browser — lives on the server. Nothing meaningful travels in the cookie, so nothing meaningful can be read out of it or edited in it, and ending somebody's access is a server-side act rather than a request that the browser please forget something.
Attribute
Effect
What it does not do
HttpOnly
Script cannot read the cookie value
Does not stop script on the page causing requests that the browser attaches the cookie to
Secure
Sent only over HTTPS
Does not protect the value once it reaches a server or a proxy
SameSite
Limits sending on requests initiated by other sites
Not a substitute for a server-side check on state-changing requests
Path / Domain
Narrows where it is sent
Does not isolate one part of an application from another in any security sense
Max-Age / Expires
How long the browser keeps it
Does not control the real lifetime, which the server owns
This is the load-bearing sentence of the page. It identifies the caller. It authorises nothing. In Connect, what a caller may do is decided after identification and independently of it, three times over: the customer_safe allowlist refuses any /api/* path a customer browser is not permitted to call, the SQLAlchemy workspace kernel filters every query to the caller's workspace, and PostgreSQL row-level security filters it again in the database.
Each of those layers is capable of refusing a request on its own. That redundancy is the point: a mistake in a route, in a query, or in a new table's configuration is caught by a layer that was not part of the mistake. It is also why a customer browser hitting an Owner path returns 403 rather than data — tenantAdapt rewrites what it recognises and sends everything else to a blocked path that fails closed.
Used. A person signs in with Google and the browser then carries a session cookie, which is how the application knows on every subsequent request whether it is serving the Owner or a customer. There is no password login behind it and no alternative token a person can paste in.
Machine access does not use it. A developer or an agent authenticates with an integration key, which is issued and revoked on its own terms and is not tied to anybody's browser. Attempting to drive the API with a copied browser credential is unsupported and is exactly the pattern the layered checks are designed to make unproductive.
Screens render, and are empty. An expiry produces 401 answers, and a screen showing you nothing is showing the absence of *data*, not the absence of records. Check who you are signed in as before investigating the feature.
One screen 403s and the rest are fine. That is the allowlist or the path rewrite. The account is not restricted; the path has no customer form.
Signing in again on the same browser ended a colleague's. Expected — replacement ends only what it replaced, on that browser, never their other devices.
An automated check reports signed-in forever. A prober that treats 401 or a redirect as success will report health through a total sign-in outage. Assert on something only a signed-in caller can produce.
Does HttpOnly make a cookie safe from cross-site scripting?
It stops the value being read, which stops the cookie being exfiltrated. It does not stop injected script making requests from the page, which the browser will attach the cookie to. Script running on your page acts as you either way; HttpOnly limits the blast radius rather than removing it.
Can I keep a session alive indefinitely for a background job?
That is the wrong tool. Sessions belong to people and to browsers. A long-running integration uses an integration key, which can be scoped and revoked without disturbing anyone's sign-in.
Why is workspace membership not simply stored in the cookie?
Because then a stale cookie would carry stale authority, and revoking access would mean waiting for a cookie to expire. Resolving the workspace server-side on every request means a change of access takes effect on the next request, not eventually.