Documentation
Authentication
Last updated
Overview
Every Farshore Labs API and web surface requires authentication and an active subscription for the requested service. There are two credential types — one for humans, one for machines — and a single “smart” authentication scheme inside each service that picks the right handler based on what the caller presents.
Web sessions
The web application signs users in with email + password (and optional TOTP). On success, the identity service issues an opaque session identifier in a __Host-session cookie. The cookie is HttpOnly, Secure, and SameSite=Lax with no Domain attribute, so it is bound to the origin that issued it.
State-changing requests must include a CSRF token. The web app handles this transparently; if you build your own client against the cookie-based endpoints, you must read __Host-csrf and echo it as the X-CSRF-Token header.
Bearer tokens (programmatic)
Every service API accepts an Authorization: Bearer <token> header. Two token formats are recognised:
- Farshore API keys — strings that start with
fsl_live_. See API keys for creation, scoping, and rotation. This is the right credential for backend integrations. - Short-lived JWTs issued by the identity service for first-party clients. Anything in the
Authorizationheader that does not start withfsl_is treated as a JWT and validated against the configured issuer and audience.
A service inspects the prefix and forwards the request to the matching handler — there is one [Authorize] attribute on the endpoint and both credential types are interchangeable from the caller’s perspective.
Failure modes
Common authentication failures (with the exact WWW-Authenticate values when applicable):
| Status | Cause | WWW-Authenticate |
|---|---|---|
| 401 | Token not recognised. | Bearer error="invalid_token", outcome="unknown_token" |
| 401 | Key revoked from the dashboard. | Bearer error="invalid_token", outcome="revoked" |
| 401 | Key past its expiry date. | Bearer error="invalid_token", outcome="expired" |
| 401 | Key valid but not scoped to this service. | Bearer error="invalid_token", outcome="service_not_allowed" |
| 429 | Monthly quota exhausted. | + Retry-After: <seconds> |
Treating credentials as secrets
- Never commit a key to a repository. The
fsl_prefix is recognised by GitHub secret scanning and exposed keys will be auto-revoked. - Store keys in a real secret manager (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, GitHub Actions secrets, etc.).
- Rotate keys at least every 90 days. Revocation is immediate; the dashboard ages-out caches within 60 seconds.
- Scope keys to the smallest set of services they need. Avoid broad “any service” keys in production.