Skip to content

Add the FAF webclient (webclient.faforever.com) - #350

Merged
Brutus5000 merged 2 commits into
FAForever:developfrom
Nuggets75:develop
Nov 11, 2026
Merged

Brutus5000 merged 2 commits into
FAForever:developfrom
Nuggets75:develop

Conversation

@Nuggets75

@Nuggets75 Nuggets75 commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Add the FAF webclient (webclient.faforever.com)

Deploys FAForever/webclient: FAF in the browser and on phones, in the Rust client's design. Maps, mods, replays, leaderboards, open lobbies, tournaments and events need no account; the chat needs a FAF login.

Set up exactly like faf-tournaments.

apps/faf-webclient (new)

  • Image faforever/faf-webclient:latest, published on every push to main of FAForever/webclient; Keel rolls it out (@every 2m).
  • IngressRoute webclient.$BASE_DOMAIN, port 8098, /healthz probes.
  • Stateless: no volume, no database.
  • FAF_BASE_DOMAIN comes from baseDomain, so the test cluster's copy talks to the test servers (api.faforever.xyz, hydra.faforever.xyz, chat.faforever.xyz, ...).
  • Secret faf-webclient (Infisical), one key: FAF_API_CLIENT_SECRET. The secret is optional; without it the site runs and the Maps, Mods and Replays tabs say the login is missing.

apps/ory-hydra/values.yaml: two clients

  1. "FAF Web (public)": service login, set up like "FAF Website (public)". client_credentials, scope public_profile, secret FAFWEB_M2M_SECRET.
    • Why: every /data read on the API needs a token, so listing maps, mods and replays needs one.
    • The token stays on the server and is only attached to read-only GETs of an allowlisted set of API resources. One cached copy per response (60 s) is shared by every visitor.
  2. "FAF Web": player login for the chat, set up like the desktop clients. Public client with PKCE, no secret.
    • Scope openid,offline,public_profile. No lobby, so no ownership check: it is only used to chat.
    • Redirect https://webclient.$BASE_DOMAIN/auth/callback.
    • The server swaps the code for tokens and fetches the IRC token from user.$BASE_DOMAIN/irc/ergochat/token, the same call the desktop clients make. Hydra and the user service have no CORS, which is why the server does this. The access token never leaves the server.
    • The browser then connects to chat.$BASE_DOMAIN over WebSocket itself, from the player's own IP. Ergo's multiclient keeps the desktop client connected.

Tiltfile

faf-webclient added next to faf-tournaments.

Needs an admin

  1. Infisical, prod and test: one random value, stored twice:
    • FAFWEB_M2M_SECRET in ory-hydra (Hydra creates the client with it)
    • FAF_API_CLIENT_SECRET in a new secret faf-webclient (the app logs in with it)
  2. GitHub: FAForever/webclient needs the org's DOCKER_USERNAME / DOCKER_PASSWORD secrets, like faf-tournaments.
  3. DNS for webclient.faforever.com and webclient.faforever.xyz, unless a wildcard already covers them.

Summary by CodeRabbit

  • New Features
    • Added the FAF web client, available at webclient.<base domain>.
    • Added OAuth sign-in and token-based authentication support for the web client.

## Add the FAF webclient (webclient.faforever.com)

Deploys [FAForever/webclient](https://github.com/FAForever/webclient): FAF in the browser and on phones, in the Rust client's design. Maps, mods, replays, leaderboards, open lobbies, tournaments and events need no account; the chat needs a FAF login.

Set up exactly like faf-tournaments.

### `apps/faf-webclient` (new)

- Image `faforever/faf-webclient:latest`, published on every push to `main` of FAForever/webclient; Keel rolls it out (`@every 2m`).
- IngressRoute `webclient.$BASE_DOMAIN`, port 8098, `/healthz` probes.
- Stateless: no volume, no database.
- `FAF_BASE_DOMAIN` comes from `baseDomain`, so the test cluster's copy talks to the test servers (`api.faforever.xyz`, `hydra.faforever.xyz`, `chat.faforever.xyz`, ...).
- Secret `faf-webclient` (Infisical), one key: `FAF_API_CLIENT_SECRET`. The secret is optional; without it the site runs and the Maps, Mods and Replays tabs say the login is missing.

### `apps/ory-hydra/values.yaml`: two clients

1. **"FAF Web (public)"**: service login, set up like "FAF Website (public)". `client_credentials`, scope `public_profile`, secret `FAFWEB_M2M_SECRET`.
   - Why: every `/data` read on the API needs a token, so listing maps, mods and replays needs one.
   - The token stays on the server and is only attached to read-only GETs of an allowlisted set of API resources. One cached copy per response (60 s) is shared by every visitor.
2. **"FAF Web"**: player login for the chat, set up like the desktop clients. Public client with PKCE, no secret.
   - Scope `openid,offline,public_profile`. No `lobby`, so no ownership check: it is only used to chat.
   - Redirect `https://webclient.$BASE_DOMAIN/auth/callback`.
   - The server swaps the code for tokens and fetches the IRC token from `user.$BASE_DOMAIN/irc/ergochat/token`, the same call the desktop clients make. Hydra and the user service have no CORS, which is why the server does this. The access token never leaves the server.
   - The browser then connects to `chat.$BASE_DOMAIN` over WebSocket itself, from the player's own IP. Ergo's multiclient keeps the desktop client connected.

### `Tiltfile`

`faf-webclient` added next to `faf-tournaments`.

### Needs an admin

1. Infisical, prod and test: one random value, stored twice:
   - `FAFWEB_M2M_SECRET` in `ory-hydra` (Hydra creates the client with it)
   - `FAF_API_CLIENT_SECRET` in a new secret `faf-webclient` (the app logs in with it)
2. GitHub: FAForever/webclient needs the org's `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets, like faf-tournaments.
3. DNS for `webclient.faforever.com` and `webclient.faforever.xyz`, unless a wildcard already covers them.
@coderabbitai

coderabbitai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The pull request adds a Helm chart and Tilt registration for faf-webclient. It also adds two Ory Hydra OAuth client configurations and local secret values for the webclient and its public client.

Changes: faf-webclient integration

Layer / File(s) Summary
Webclient chart and Kubernetes resources
apps/faf-webclient/Chart.yaml, apps/faf-webclient/values.yaml, apps/faf-webclient/templates/*
Adds the chart configuration, ConfigMap, Deployment, Service, Traefik IngressRoute, and a conditional local Secret. The Deployment exposes port 8098 and defines health probes.
Ory Hydra OAuth clients
apps/ory-hydra/values.yaml, apps/ory-hydra/templates/local-secret.yaml
Adds a public client-credentials entry and a webclient authorization-code and refresh-token entry. The local Secret adds the public client’s secret value.
Tilt service registration
Tiltfile
Registers faf-webclient with the misc label and a link using the configured base domain.

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

Change: Feature

Suggested reviewers: brutus5000

Merge Risk: Minimal · up to cb34f

This change adds the webclient deployment and its OAuth client configuration. No concrete merge-blocking problem was found. Before release, an admin still needs to configure the Infisical secrets, Docker credentials and DNS entries listed in the PR description.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "Add the FAF webclient (webclient.faforever.com)" names the main change: a new faf-webclient deployment with its ingress, Helm chart, and Hydra OAuth clients. The raw summary confirms the Ti…
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.
Full details: Title check

Explanation

The title "Add the FAF webclient (webclient.faforever.com)" names the main change: a new faf-webclient deployment with its ingress, Helm chart, and Hydra OAuth clients. The raw summary confirms the Tiltfile, chart, templates, and Hydra client additions all serve that deployment. The title is specific and short, and it has no vague terms or file lists.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c8b4c422-895c-4f5b-9fbe-914ccd0728df
Commits

Reviewing files that changed from the base of the PR and between ee047ee and cb34f76.

Files selected for processing: 10

  • Tiltfile
  • apps/faf-webclient/Chart.yaml
  • apps/faf-webclient/templates/config.yaml
  • apps/faf-webclient/templates/deployment.yaml
  • apps/faf-webclient/templates/ingress.yaml
  • apps/faf-webclient/templates/local-secret.yaml
  • apps/faf-webclient/templates/service.yaml
  • apps/faf-webclient/values.yaml
  • apps/ory-hydra/templates/local-secret.yaml
  • apps/ory-hydra/values.yaml

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

@Brutus5000
Brutus5000 merged commit e012151 into FAForever:develop Nov 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants