fargone / docs / oauth

Fargone as an OAuth provider

Fargone is an OAuth 2.0 provider. Third-party apps — and your own scripts or CLIs — can authenticate users against Fargone accounts. No passwords anywhere, including for API access.

Register a client

Settings → OAuth Apps → New client. You'll get a client_id and client_secret (shown once). Grant types supported: authorization_code, refresh_token, client_credentials, and device_code.

Endpoints

GET  /oauth/authorize                          auth code + PKCE
POST /oauth/token                              token exchange
POST /api/oauth/device                         device flow initiation
GET  /oauth/device                             device code entry page
GET  /oauth/userinfo                           current user (Bearer token)

Authorization code + PKCE

GET /oauth/authorize?response_type=code&client_id=fg_xxx&redirect_uri=https://app/cb&scope=read:user&code_challenge=<s256>&code_challenge_method=S256&state=xyz

The user signs in (passkey / SSO) and approves the consent screen. Fargone redirects back with code and state.

Exchange it:

curl -X POST https://fargone.sh/oauth/token \
  -u fg_xxx:<secret> \
  -d grant_type=authorization_code \
  -d code=<code> \
  -d redirect_uri=https://app/cb \
  -d code_verifier=<verifier>

Response:

{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...",
  "scope": "read:user"
}

Client credentials

curl -X POST https://fargone.sh/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=fg_xxx -d client_secret=...

Device flow (CLIs, TVs, scripts)

  1. POST /api/oauth/device with client_id → returns device_code, user_code, verification_uri
  2. Tell the user to visit the verification URI and enter the code
  3. Poll POST /oauth/token with grant_type=urn:ietf:params:oauth:grant-type:device_code until it returns tokens (authorization_pending until approved)

Calling the API

curl -H "Authorization: Bearer <access_token>" https://fargone.sh/oauth/userinfo
{
  "id": "cm...",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "role": "MEMBER",
  "status": "ACTIVE",
  "scopes": ["read:user"]
}

Scopes

  • read:user — default; the user's public profile
  • More scopes are added as the REST API grows

Security

  • Authorization codes are single-use and expire in 10 minutes
  • PKCE is verified on exchange (S256 recommended)
  • Access tokens expire after 1 hour; refresh tokens rotate
  • Secrets are stored hashed in the database