Skip to content

feat(server): exempt Steam-authenticated clients from the Turnstile siteverify - #4702

Merged
Celant merged 4 commits into
mainfrom
steam-turnstile-exemption
Jul 24, 2026
Merged

feat(server): exempt Steam-authenticated clients from the Turnstile siteverify#4702
Celant merged 4 commits into
mainfrom
steam-turnstile-exemption

Conversation

@Celant

@Celant Celant commented Jul 24, 2026

Copy link
Copy Markdown
Member

What

Exempt Steam-authenticated clients from the Turnstile bot-check at the join gate, keying off a signed provider: "steam" claim in the already-verified session JWT.

  • TokenPayloadSchema gains an optional provider field (additive).
  • JoinVerify.ts: isSteamAuthenticated(claims) (claims?.provider === "steam"), and planJoinVerify gains a required steamAuthed input. A Steam-authenticated first join is planned as {action: "verify", token: null} — it rides the existing null-token path that skips the Turnstile siteverify but still runs the /join_verify name check. First joins are never skipped.
  • Worker.ts: passes steamAuthed: isSteamAuthenticated(claims) and logs each exemption (persistentID/gameID).
  • Client (Main.ts): the desktop instance skips Turnstile token acquisition (cosmetic — removes the "Failed to load Turnstile script" console error; grants nothing, the exemption is server-side).

Why

The Steam desktop build can't produce valid prod Turnstile tokens, so Steam players could connect but not join online games. Steam ownership becomes the anti-abuse signal. The exemption keys only off the signed, server-verified claim — never the forgeable client instanceId — and Steam users are still name-censored.

Testing

tests/server/JoinVerify.test.ts extended (20/20): Steam first-join → verify-with-null-token (never reject, never skip); non-Steam behavior unchanged; isSteamAuthenticated exact-match/null-safe. tsc --noEmit clean; full server suite green (235).

Note

The provider: "steam" claim is minted by the closed auth API (deployed first). Until then this code is inert — no token carries the claim, so nothing is exempted.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BWxUzYb2uqjcBFQuNSJhMy

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a7eda500-7d98-4e16-b19a-d6e203ca85c5

📥 Commits

Reviewing files that changed from the base of the PR and between ee8c453 and 88a2f18.

📒 Files selected for processing (1)
  • tests/server/JoinVerify.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/server/JoinVerify.test.ts

Walkthrough

Desktop clients now skip Turnstile token acquisition. Token claims include an optional provider, allowing Steam-authenticated first joins to bypass Turnstile token requirements while preserving readmit handling.

Changes

Join verification flow

Layer / File(s) Summary
Desktop Turnstile bypass
src/client/Main.ts
Desktop initialization and token retrieval now avoid Turnstile requests.
Steam claim and join planning
src/core/ApiSchemas.ts, src/server/JoinVerify.ts, tests/server/JoinVerify.test.ts
Token payloads accept provider, and Steam-authenticated first joins verify with a null Turnstile token. Tests cover Steam, non-Steam, missing, and null claims.
Websocket join integration
src/server/Worker.ts
Join handling passes Steam-authentication and readmit state into the planner and logs skipped Turnstile verification for Steam first joins.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Worker
  participant JoinVerify
  Client->>Worker: submit join
  Worker->>JoinVerify: plan with steamAuthed
  JoinVerify-->>Worker: verify with null token
  Worker-->>Client: continue join flow
Loading

Possibly related PRs

Poem

Desktop tokens quietly sleep,
Steam joins cross the gate,
Claims carry providers deep,
Turnstile can now wait.
A cleaner path, verified straight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the main change: exempting Steam-authenticated clients from Turnstile site verification.
Description check ✅ Passed The description matches the changeset and explains the Steam exemption, client update, and testing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 24, 2026
…-imports)

The `import type { TokenPayload }` belongs directly after the vitest import
per prettier-plugin-organize-imports; CI `prettier --check .` flagged it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWxUzYb2uqjcBFQuNSJhMy
@Celant Celant added this to the v33 milestone Jul 24, 2026
@Celant
Celant merged commit 82fb7de into main Jul 24, 2026
13 of 14 checks passed
@Celant
Celant deleted the steam-turnstile-exemption branch July 24, 2026 14:25
@github-project-automation github-project-automation Bot moved this from Triage to Complete in OpenFront Release Management Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

1 participant