Sign-in & organizations
Accounts, organizations, roles and invitations — and how the API authenticates a signed-in user
Signing in
Foredeck uses Firebase Authentication. Create an account at /sign-up with an email and password, and sign in at /sign-in. Forgot your password? /reset-password emails you a reset link.
If you had an account before the move to Firebase, it was imported with your existing password and user id, so you sign in exactly as before and all of your data is still there.
Personal account and organizations
Everything you send to Foredeck (services, flags, experiments, logs, traces, metrics, monitors) belongs to an account. Every user has a personal account. An organization is a shared account that several people can work in.
- Switch accounts with the account switcher at the bottom of the sidebar. The whole app re-scopes to the account you pick, and your choice is remembered in this browser.
- Create an organization from the same menu (Create organization) or from Settings → Members. You become its admin.
Roles
| Role | Can |
|---|---|
| owner | Everything, in your personal account. |
| admin | Everything in the organization, including members, invitations, API keys and destructive data operations. |
| member | Read and work with the organization's data. No member, key or data management. |
Admins change roles and remove members in Settings → Members. An organization always keeps at least one admin, so the last admin can't be removed. Any member can leave.
Inviting teammates
- Switch to the organization, open Settings → Members, and enter your teammate's email and role.
- Foredeck creates an invitation and shows its accept link. Copy it and send it to them yourself. Foredeck doesn't send invitation emails.
- They open
/invite/…, see which organization and role they're joining, sign in or create an account, and accept. The organization becomes their active account.
Invitation links expire. If one has expired, create a new invitation.
How the API authenticates you
The web app calls the APIs with the signed-in user's Firebase ID token and the active account:
GET /api/events/v1/services
Authorization: Bearer <Firebase ID token>
X-Foredeck-Account: org_01J... # omit, or send your uid, for the personal accountThe server checks that you belong to the organization in X-Foredeck-Account and applies your role. If you don't belong to it, the request fails with 403.
Live tails (logs and traces) use WebSockets. A browser can't set headers on a WebSocket, so the token and account go in the query string, and the socket connects straight to the events API rather than through the main domain:
wss://<events-api host>/v1/logs/tail/<account>?token=<ID token>&account=<account>Your services don't use any of this. SDKs and ingest calls authenticate with an API key from Settings → API keys; see the Quickstart.
API keys and scopes
Admins (and the owner of a personal account) create and revoke keys in Settings → API keys. A server key (fd_server_…) is a secret for your backends and CI. A client key (fd_client_…) is publishable and safe to embed in a browser. Both send events and read the account's data. The full key is shown once, when it's created.
A server key can also carry scopes, which let it call control endpoints that a plain key can't. There's one scope today:
| Scope | Allows |
|---|---|
factory:control | Halting and resuming factory pipelines, and syncing factory policy as code. |
- Scopes are set when the key is created and can't be changed. To change them, create a new key and revoke the old one.
- Client keys can't hold scopes. Asking for one returns
422. - Signed-in users never need a scope. Any member of the account can use the same control endpoints from the app with their ID token.
- A key without the scope gets
403from a control endpoint. A revoked or unknown key gets401.
POST /api/events/v1/api-keys
Authorization: Bearer <admin's Firebase ID token>
X-Foredeck-Account: org_01J...
{"key_type": "server", "label": "factory CI", "scopes": ["factory:control"]}On a self-hosted install, you can also mint a key from the events API directory: python3 api_keys.py mint <account_id> server "factory CI" --scope factory:control.