Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.busha.io/llms.txt

Use this file to discover all available pages before exploring further.

PKCE is mandatory

Every authorization request must include code_challenge and code_challenge_method=S256. Generate a fresh code_verifier (43–128 URL-safe characters) per authorization request. plain challenges and missing challenges are rejected. PKCE ensures that an attacker who intercepts the authorization code cannot redeem it without also possessing the verifier, which never leaves your backend.

state is required for CSRF protection

Generate at least 16 bytes from a cryptographic RNG, bind the value to the user’s session, and reject any callback where the returned state does not match. Without this guard, an attacker can plant a known authorization code on someone else’s session.

nonce for OIDC ID tokens

When you request openid, include a nonce parameter in the authorization request and validate it inside the id_token. This protects against ID-token replay attacks.

redirect_uri must be exact

Register only redirect URIs your application controls. Production URIs must use HTTPS — HTTP is only allowed for localhost. Busha compares redirect_uri byte-for-byte:
  • https://app.example.com/cb and https://app.example.com/cb/ are different URIs.
  • Port, scheme, path casing, and trailing slashes all matter.
  • A mismatch is rejected immediately.

client_secret belongs in your backend

Never place client_secret in:
  • A mobile application
  • A single-page application
  • A browser extension
  • Any code that ships to users
Store it in a secret manager (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager). If it is ever compromised, rotate it immediately using Rotate Secret on your app’s dashboard page.

Always verify access tokens before trusting them

Anyone can base64-decode a JWT and read its claims. None of those claims are trustworthy until you have verified the RS256 signature against the JWKS. See Token handling → Validating access tokens for the full validation checklist.

Secure refresh token storage

Refresh tokens must be stored:
  • Encrypted at rest with row-level encryption keyed per user.
  • Server-side only — never in browser cookies or localStorage.
  • Persisted atomically — write the new pair before discarding the old one.

Revoke on disconnect

When a user disconnects your integration, call POST /oauth2/revoke with token_type_hint=refresh_token. This immediately prevents new tokens from being minted. The currently-issued access token continues to be valid until exp, but no new session can be started.

Never log sensitive values

Never logSafe to log
client_secretclient_id
access_tokenjti (JWT ID)
refresh_tokensub (user UUID)
code_verifierScope list
Authorization codeRequest / trace IDs
id_token