Authentication
GrooveOS supports two ways to sign in: a native
email + password login that works out of the box with
zero setup (see Local (email + password)
below), and Sign in with GitHub, which additionally
auto-joins you to a team based on your GitHub org membership. The same
"Sign in with GitHub" button works on the web app at
grooveos.app,
in the Chrome extension popup, and in any other GrooveOS surface — they
all share the same identity, and both sign-in methods produce the
identical xbt_ session token described in
Tokens & refresh below.
Local (email + password)
You don't have to connect GitHub or Google. GrooveOS ships a native email + password login that works with zero external OAuth setup — no Google Cloud project, no GitHub App, no callback URLs. This is what lets a fresh self-hosted install work the moment it boots, before you've configured any identity provider: create the first account straight from the app.
- Go to grooveos.app/account/register/ (or your own deployment's
/account/register/). - Enter an email and a password (at least 10 characters).
- You're signed in immediately — no confirmation email, no consent screen.
Already have an account? Sign in at grooveos.app/account/login/.
The three endpoints
| Endpoint | Purpose |
|---|---|
POST /v1/auth/local/register |
Create a brand-new account from an email + password. Returns
409 if that email already has an account, by any
method — sign in with the existing method instead, then attach a
password (below). No new account is ever created on top of an
existing email.
|
POST /v1/auth/local/login |
Exchange email + password for an xbt_ session token.
Repeated wrong-password attempts lock the account for a short
cooldown. A wrong password and a nonexistent email deliberately
produce the exact same response, so a failed login never reveals
whether an email is registered.
|
POST /v1/auth/local/set-password |
Authenticated endpoint — attach or change a password on your own, already signed-in account. This is how a GitHub or Google user adds a local password to their existing account (see One account, two ways in below), and how you change an existing local password. |
Local sign-in authorizes exactly like GitHub sign-in
Local login mints the same xbt_ token
described in Tokens & refresh below — the
identical opaque, revocable API token every other GrooveOS sign-in
method produces. There is no separate "local session" concept: once
you're signed in, a local-auth account is indistinguishable from a
GitHub or Google one to every GrooveOS API and surface.
One account, two ways in
If you already sign in with GitHub or Google, you can add a password to
that same account from your account settings — this is
how GrooveOS converges identities. Because attaching a password requires
you to already be signed in, it's safe: an attacker who merely knows
your email cannot register a competing account and hijack yours — a
cold register against an email that already has an account
is always rejected with 409, no exceptions. Attaching a
password is proven by your live session, never by anything sent in the
request.
Password recovery — no email reset
There is no "forgot password" email link, and there isn't meant to be: a reset-by-email flow needs an outbound SMTP server, which an out-of-the-box self-hosted install should not require. If you're locked out or forgot your password, recovery is a documented operator action against the database — the local-auth recovery runbook walks through both cases step by step. If your deployment also has GitHub or Google configured, the fastest recovery is simply to sign in with that instead and re-attach a password from account settings.
GitHub and Google remain available — this is a default, not a replacement
None of this changes how Sign in with GitHub (documented next) works, and Google sign-in (used by the Chrome extension) is unaffected too. Local email/password is the zero-configuration default that lets a fresh self-hosted install work before any OAuth App is set up — GitHub and Google stay fully available, unchanged, and optional on top of it.
Sign in with GitHub
Behind the scenes GrooveOS uses a GitHub App (the modern successor to OAuth Apps). The difference matters: the GitHub App can be installed on your GitHub organization once, which then lets any org member join your GrooveOS team automatically — no manual invites needed.
The basic flow is the same everywhere:
- Click Sign in with GitHub.
- GitHub shows a consent screen the first time. Approve xbrain.
- You land back on GrooveOS, signed in. Your GitHub avatar and username appear in the top bar.
| Where you sign in | Button location |
|---|---|
| Web app | grooveos.app/account/teams/ — primary button |
| Chrome extension | Extension popup — first launch |
| LibreChat | chat.grooveos.app — "Sign in with GitHub" on the login screen |
Same GitHub account everywhere
The web app, the Chrome extension, and LibreChat all sign in against the
same GitHub App, so your GrooveOS identity is consistent across surfaces.
Tokens you create in one surface (e.g. an xbt_ API token from
the web app) work in all of them.
Installing xbrain on your org
If you sign in for the first time and your primary GitHub organization hasn't installed the xbrain App yet, GrooveOS shows a yellow banner like:
Install xbrain on `your-org-name`
[ Install xbrain on org → ]
What happens next depends on your role inside the GitHub org:
- You are a GitHub org owner / admin. Click the button. GitHub asks you to choose which repos xbrain can see (you can pick "All repositories" or a subset — xbrain doesn't actually need any repo access for sign-in, only the org membership read). Approve. GitHub sends you back to GrooveOS, and the rest of your org can now sign in.
- You are a regular member of the org. Click the button. GitHub will show an "Approval required" page that lets you request the install. Once an owner approves, every org member can sign in.
The install is per-org, not per-user
Once xbrain is installed on your GitHub org, no other member of that org needs to do it again. They just click "Sign in with GitHub" and they're in. The install is what unlocks the auto-join behaviour below.
Auto-join via GitHub org
Every xbrain team can declare a github_org field in its
settings. When you sign in with GitHub, GrooveOS reads the list of
organizations you belong to, and adds you to every team whose
github_org matches one of your orgs — no manual invite needed.
This is the default way to add people to a team:
- Team admin sets
github_org = your-orgin team settings. - Anyone in
your-orgsigns in with GitHub for the first time. - GrooveOS detects the org match and auto-adds them to the team as a Member.
- Team admins receive an email titled "New member auto-joined <team>".
If an auto-join is unexpected, an admin can block the user from the team — see Blocking members below.
Tokens & refresh
Once you're signed in, GrooveOS gives you an xbt_ personal API
token. This is what every GrooveOS surface uses under the hood to call the
API on your behalf:
xbt_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
You can list, name, and revoke your xbt_ tokens from your
profile page. See the API Reference for the full
programmatic surface — xbt_ tokens are how you build your own
scripts and integrations.
Behind the scenes: GitHub tokens
In addition to the xbt_ token, GrooveOS stores two GitHub-side tokens for your account:
| Token | Lifetime | Why |
|---|---|---|
User access token (ghu_) |
8 hours | Used to look up your GitHub profile, verified emails, and org memberships when you sign in. |
Refresh token (ghr_) |
6 months | Single-use; quietly rotates the 8h access token in the background so you don't have to re-sign-in every workday. |
You don't see these — they're managed for you, encrypted at rest, and rotated automatically. After 6 months of no GrooveOS activity the refresh token expires; on your next visit you click "Sign in with GitHub" again and the cycle restarts.
Blocking members
Team admins can block any member at any time from the Settings card on the teams page or from the Options tab of the Chrome extension. Blocked users immediately stop having access:
- Every team-scoped API call returns HTTP 403 — even with a valid
xbt_token created before the block. - The block survives sign-out / sign-in. The user cannot recover access by re-authorizing GitHub.
Pre-blocking a GitHub login
Admins can also pre-block a GitHub username that hasn't signed up yet. The next time that user signs in via your org, the auto-grant pipeline checks the pre-block list before adding them to the team. They will sign in successfully but won't be auto-joined.
Permissions xbrain requests
When you authorize xbrain via GitHub, the App asks for:
- Email addresses (read-only) — to attach your verified email to your user row so admins can invite you and notifications reach you.
- Members (read-only) — so xbrain can read which orgs you belong to and apply the auto-join rule.
That's it. xbrain does not request repo content access,
write access to your account, or any permissions on your code. You can
review the install at any time on GitHub:
github.com/settings/installations (personal) or
github.com/organizations/<your-org>/settings/installations
(org).
Revoking access
To cut all GrooveOS access from your GitHub account, uninstall the xbrain App from GitHub's installation settings. GrooveOS detects the uninstall via webhook and your team memberships become read-only until the App is reinstalled.
Troubleshooting
| Symptom | What's happening | Fix |
|---|---|---|
| "Install xbrain on org" banner doesn't go away after install | GitHub's install webhook hasn't reached GrooveOS yet (usually < 5 s). | Wait a few seconds and refresh the page. GrooveOS also self-heals on the next sign-in by querying GitHub directly. |
| Approval required after clicking Install | You're a regular member of the org, not an owner. | An org owner has to approve the install request. Ask them, then come back and sign in again. |
| Signed in, but no teams listed | Your org isn't tied to any GrooveOS team yet, or you're in a private org GrooveOS can't see without the install. | Ask a team admin to either invite you by email or set github_org on the team to your org. |
| HTTP 401 unauthorized from the API | Your refresh token expired (no GrooveOS activity in 6 months) or your xbt_ was revoked. |
Sign in with GitHub again. If your xbt_ was revoked, mint a new one from your profile. |
| HTTP 403 with "Member blocked from team …" | A team admin blocked you. | Contact the admin. Re-signing-in won't help — the block is server-side. |
What's next
- Onboarding Guide — Step-by-step from sign-in to a working Claude.ai / ChatGPT integration.
- Teams & Projects — Setting
github_org, inviting members, project scopes. - API Reference — Using your
xbt_token programmatically.