OAuth Security
PKCE (Proof Key for Code Exchange)
Section titled “PKCE (Proof Key for Code Exchange)”Authpipe uses PKCE for all OAuth authorization flows. When creating an auth session:
- A random
code_verifieris generated. - The
code_challenge(SHA-256 hash of the verifier) is sent in the authorization URL. - The
code_verifieris encrypted in the stateless state parameter. - 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.
Stateless state parameter
Section titled “Stateless state parameter”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.
Callback URL allowlisting
Section titled “Callback URL allowlisting”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_uriduring 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.
State validation
Section titled “State validation”On callback, Authpipe:
- Decrypts the state parameter (fails if tampered with)
- Verifies the state contains a valid session
- Extracts the PKCE verifier for the token exchange
- Exchanges the authorization code for tokens
- Encrypts and stores the tokens
- Redirects the user to the developer’s redirect URL
Inbound webhook verification
Section titled “Inbound webhook verification”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.
Outbound webhook signing
Section titled “Outbound webhook signing”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)
Token storage security
Section titled “Token storage security”- 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
getCredentialendpoint - Client secrets are encrypted and never returned in API responses
Credential lifecycle security
Section titled “Credential lifecycle security”- 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_idcascadesneeds_reauthto all downstream installations and connections, since tokens are bound to the OAuth app identity. - Client secret rotation: Changing
client_secretdoes 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.