The framework side already exists, so this is registration plus secrets: create the OAuth app per provider, then fill config.services.<provider> in each app with clientId, clientSecret and redirectUrl. Apple is the exception and takes teamId, keyId and privateKey instead of a secret.
Providers supported today: Google, GitHub, Facebook, X, Apple.
Current state across the HQ apps
Surveyed 2026-09-28 from each app's config/services.ts and app/Actions/Auth/:
| app | providers declared in config | social auth actions |
|---|---|---|
| analyticshq | google, github, facebook, apple | 2 |
| statushq | google, github, facebook, apple | 2 |
| bughq | google, github, facebook, apple | 2 |
| loghq | google, github, facebook, apple | 2 |
| commshq | google, github, facebook, apple | 0 |
| reportshq | google, github, facebook, apple | 0 |
Two things fall out of that:
- X is declared nowhere. All six apps declare google, github, facebook and apple; none declares
x. If X is in scope, its config block has to be added to each app, not just credentialed. - commshq and reportshq have no social auth actions at all. For those two this is not "registration plus secrets" - the sign-in path itself is missing, so they need the actions wired before credentials mean anything.
Scope
- Register the OAuth app per provider per environment, and note the exact
redirectUrleach one is registered with - Fill
config.services.<provider>in analyticshq, statushq, bughq, loghq - Add the
xprovider block where X is wanted - Wire social auth actions in commshq and reportshq, or decide explicitly that those two stay password-only
- Verify a real sign-in per provider per app after the credentials land
Note on storing the secrets
buddy env:set writes values that cannot be decrypted later - see the existing note in this workspace. Provider secrets must not go through it. Apple's privateKey in particular is multi-line and needs care in whatever store is chosen.