How the Cookie Suffix Prevents Authentication Cookie Collisions in Multi-Instance code-server Deployments
The --cookie-suffix flag generates a unique session cookie name per instance, ensuring browsers store separate authentication tokens for each code-server deployment sharing the same domain.
When running multiple code-server instances behind a reverse proxy or across Kubernetes pods, authentication cookie collisions can cause users to be unexpectedly logged out or authenticated against the wrong instance. The cookie suffix feature in coder/code-server solves this by appending a unique identifier to the session cookie name, creating namespace isolation at the browser storage level.
Why Authentication Cookie Collisions Occur
By default, code-server stores session tokens in a cookie named code-server-session. When several instances are reachable under the same domain (e.g., multiple pods behind a load balancer or different sub-paths on a shared host), the browser treats these as the same cookie scope. The last instance to set a cookie overwrites the others, causing requests to any instance to send the wrong authentication token. This breaks logout functionality and session validation for all but the most recently accessed instance.
How the Cookie Suffix Mechanism Works
Generating Unique Session Cookie Names
In src/common/http.ts, the getCookieSessionName function dynamically constructs the cookie name based on an optional suffix parameter:
export function getCookieSessionName(suffix?: string): string {
return suffix
? `code-server-session-${suffix.replace(/[^a-zA-Z0-9-]/g, "-")}`
: "code-server-session"
}
The function sanitizes the suffix by replacing any non-alphanumeric characters (except hyphens) with dashes, ensuring URL-safe cookie names. When a suffix is provided, the resulting cookie name becomes code-server-session-${suffix}, creating a unique storage key that browsers treat as distinct from other instances.
Configuration via CLI and Environment Variables
As implemented in src/node/cli.ts (lines 76-81), users specify the suffix through either the --cookie-suffix flag or the CODE_SERVER_COOKIE_SUFFIX environment variable. This value propagates through the application to the cookie generation logic, allowing per-instance customization without code changes.
Implementation Across the Request Lifecycle
Route Handler Integration
During startup, src/node/routes/index.ts (lines 64-81) attaches the generated cookie name to every incoming request as req.cookieSessionName. This ensures all route handlers reference the identical cookie name throughout the request lifecycle:
// Simplified excerpt from routes/index.ts
req.cookieSessionName = getCookieSessionName(cookieSuffix);
Login Flow and Cookie Setting
After successful password validation, src/node/routes/login.ts (lines 96-99) sets the authentication cookie using the suffix-aware name:
res.cookie(req.cookieSessionName, hashedPassword, getCookieOptions(req));
This stores the session token in a browser cookie scoped specifically to this instance's suffix.
Logout Flow and Cookie Clearing
The logout handler in src/node/routes/logout.ts (lines 7-10) clears the cookie using the exact same name and options:
res.clearCookie(req.cookieSessionName, getCookieOptions(req));
Critically, both operations invoke getCookieOptions from src/node/http.ts (lines 20-30 and 98-104) to ensure identical domain, path, and sameSite attributes. This guarantees the browser removes exactly the cookie that was set, preventing orphaned tokens or clearance failures.
Deploying Multiple Instances with Cookie Suffixes
To run two code-server instances on the same domain without authentication conflicts:
# Instance A - production environment
code-server --bind-addr 0.0.0.0:8080 --cookie-suffix prodA &
# Instance B - staging environment
code-server --bind-addr 0.0.0.0:8081 --cookie-suffix prodB &
The browser now maintains two independent cookies:
code-server-session-prodA=<token_a>
code-server-session-prodB=<token_b>
Because browsers index cookies by the combination of name + domain + path, these tokens coexist without overwriting each other. Users remain authenticated to both instances simultaneously, and logout actions affect only the targeted instance.
Summary
- Default cookie names collide when multiple code-server instances share a domain, causing browsers to overwrite session tokens.
- The suffix mechanism in
src/common/http.tsgenerates unique cookie names likecode-server-session-prodAviagetCookieSessionName. - Configuration flexibility allows setting the suffix via
--cookie-suffixCLI flag orCODE_SERVER_COOKIE_SUFFIXenvironment variable. - Consistent cookie options through
getCookieOptionsensure login and logout operations target the same browser storage key. - Multi-instance safety enables Kubernetes pods, Docker Swarm services, and reverse-proxy sub-paths to maintain isolated authentication sessions.
Frequently Asked Questions
What happens if I don't specify a cookie suffix in multi-instance deployments?
Without a suffix, all instances use the default code-server-session name. The browser stores only one cookie per domain/path combination, meaning the most recently visited instance overwrites the others' session tokens. This causes authentication failures and forces users to re-login when switching between instances.
Are there restrictions on what characters I can use in the cookie suffix?
Yes. The getCookieSessionName function in src/common/http.ts automatically sanitizes the suffix by replacing any characters that are not alphanumeric or hyphens with dashes using the regex /[^a-zA-Z0-9-]/g. This ensures the resulting cookie name complies with browser cookie naming standards.
Does the cookie suffix affect cookie security attributes like HttpOnly or Secure?
No. The suffix only modifies the cookie name. Security attributes including HttpOnly, Secure, and SameSite are determined separately by getCookieOptions in src/node/http.ts and remain consistent regardless of the suffix value.
How do I configure the cookie suffix in Kubernetes deployments?
Set the CODE_SERVER_COOKIE_SUFFIX environment variable in your pod specification, using values derived from the pod name, namespace, or deployment stage. For example, CODE_SERVER_COOKIE_SUFFIX=prod-pod-$(POD_NAME) ensures each replica maintains isolated sessions while sharing the same service domain.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →