Skip to content

OAuth Security

Authpipe uses PKCE for all OAuth authorization flows. When creating an auth session:

  1. A random code_verifier is generated.
  2. The code_challenge (SHA-256 hash of the verifier) is sent in the authorization URL.
  3. The code_verifier is encrypted in the stateless state parameter.
  4. On callback, the verifier is extracted and sent with the token exchange request.

PKCE prevents authorization code interception attacks, even for providers that don’t require it.

The OAuth state parameter is an encrypted payload containing:

  • Session ID
  • Provider configuration
  • Tenant ID and User ID
  • PKCE code verifier
  • Developer’s post-auth redirect URL
  • Template variables (for token refresh)

This is encrypted with AES-256-GCM, making it tamper-proof and eliminating the need for server-side session storage.

The oauth_redirect_url on a provider config is Authpipe’s own callback endpoint (e.g., https://api.authpipe.dev/oauth/callback). This URL is:

  • Sent to the provider as the redirect_uri during authorization
  • Must match exactly what’s registered in the provider’s developer console
  • Verified by the provider on callback

The developer’s post-auth redirect (where the user goes after Authpipe processes the callback) is passed per-request in redirect_url and encoded in the encrypted state parameter — it’s not stored permanently.

On callback, Authpipe:

  1. Decrypts the state parameter (fails if tampered with)
  2. Verifies the state contains a valid session
  3. Extracts the PKCE verifier for the token exchange
  4. Exchanges the authorization code for tokens
  5. Encrypts and stores the tokens
  6. Redirects the user to the developer’s redirect URL

For providers that send webhooks to Authpipe (e.g., Slack events), the signing_key on the provider config is used to verify inbound webhook signatures.

Set the signing key when configuring the provider:

await authpipe.updateProviderConfig("pcfg_abc123", {
signing_key: "your-provider-signing-secret",
});

Authpipe verifies the signature before processing the webhook. Invalid signatures are rejected with a 401 response.

Authpipe signs outbound webhooks (events sent to your app) with HMAC-SHA256 using the workspace’s webhook secret. See Webhooks for verification details.

The workspace supports two active secrets for zero-downtime rotation:

  • secret_1 — current signing key (used for new signatures)
  • secret_2 — previous key (still accepted for verification)
  • Access tokens and refresh tokens are encrypted with AES-256-GCM before storage
  • Per-workspace encryption key isolation
  • Encrypted fields are excluded from JSON serialization (json:"-")
  • Decrypted values are only returned through the getCredential endpoint
  • Client secrets are encrypted and never returned in API responses
  • Re-authorization: When a user re-authorizes, the existing connection is updated (upsert) rather than creating a duplicate. This prevents credential sprawl.
  • Client ID rotation: Changing a provider config’s client_id cascades needs_reauth to all downstream installations and connections, since tokens are bound to the OAuth app identity.
  • Client secret rotation: Changing client_secret does not invalidate existing tokens. The new secret is used for the next token refresh.
  • Connection revocation: Soft-deleted (status set to revoked). Tokens are not proactively revoked at the provider — that’s the developer’s responsibility if needed.