Authorization model
The Vendaze API uses OAuth 2.1 Authorization Code flow withclient_secret. This means:
- Your app is a confidential client. It has a
client_secretthat must stay on your server. - All token exchanges happen server-side. The browser never touches a token directly.
- Users authorize access to a specific workspace. Your token is scoped to that workspace only.
PKCE is handled internally
OAuth 2.1 recommends PKCE (Proof Key for Code Exchange) for all authorization flows. The Vendaze API implements PKCE, but manages it entirely on the server side. Your integration does not need to generate or send acode_verifier.
Here is what happens when a user authorizes your app:
- Your server redirects the browser to
/oauth/authorizewithclient_id,redirect_uri,response_type=code, andstate - The Vendaze API generates and manages the PKCE parameters internally
- After the user approves, the
authorization_codeis returned to yourredirect_uri - When you call
/oauth/token, the API completes the PKCE exchange transparently
authorization_code in transit, they cannot exchange it for tokens. The PKCE verification happens server-side and is never exposed. Combined with client_secret validation, two independent proofs of identity are required to complete the exchange.
Why you do not manage it: PKCE was designed for public clients (mobile apps, SPAs) that cannot store a client_secret. For confidential clients like yours, the client_secret already provides equivalent protection. Exposing PKCE parameters to integrators would add complexity without adding security. The Vendaze API handles it internally so the authorization flow stays clean and compatible with any standard OAuth library.
Token validation is asymmetric
Access tokens are signed using asymmetric cryptography. The API verifies every token against a public key. There is no shared secret involved in token validation. This means:- There is no symmetric key that could be leaked and used to forge tokens
- Only the authorization server can issue valid tokens
- Key rotation on the authorization server side does not require any changes to your integration
/v1/* validates the token’s presence, expiry, signature, and workspace claims before any business logic runs. A revoked token is invalidated immediately and cannot be used again, even if it has not expired yet.
The authorization_code is single-use and short-lived
Authorization codes expire in 10 minutes and can only be used once. After a successful token exchange, the code is consumed and cannot be reused.The client_secret is never returned in any response
Theclient_secret is generated once and delivered exclusively via a secure link sent to the registered email address. The link expires in 15 minutes and is invalidated on first view.
It is never:
- Returned in any API response body
- Logged by the API
- Accessible after the initial delivery window
Credential rotation uses email, not client_secret
To rotate credentials, you sendclient_id and the registered email address. The client_secret is not required.
This is an intentional security decision. If the client_secret is compromised, requiring it for rotation would give the attacker who already has the secret the ability to rotate and take over the app. The registered email address is never returned by any API endpoint. Only Vendaze and the legitimate owner know what it is. Even if an attacker has the client_id (which is public) and discovers the email, the new client_secret is never returned in the response: it is sent as a one-time link to that email address. Completing the rotation requires access to the registered inbox, which is outside the scope of what the API can protect.
workspace_id comes from the token, never from the request
The workspace context for every API call is extracted from theaccess_token claims. Your integration never sends a workspace identifier in request parameters, headers, or body.
This means:
- An integrator cannot access data from a workspace they were not authorized for, even if they know the workspace ID
- There is no way to escalate access by manipulating request parameters
- Multi-tenant isolation is enforced at the token level, not at the application level
Rate limiting is layered
Two independent rate limiting layers apply: Per IP (OAuth endpoints):/oauth/authorize, /oauth/token, /oauth/revoke, and /v1/auth/* are rate-limited by IP address.
Per client_id (resource endpoints): all /v1/* endpoints are rate-limited by the client_id extracted from the token. Limits vary by HTTP method: 1,000 req/min for GET, 200 req/min for POST/PATCH, 100 req/min for DELETE.
This layering means a compromised token has a bounded blast radius. An attacker cannot use a single token to exhaust the API for other integrators.
What this means for your integration
The security model above means your integration has a well-defined responsibility boundary: The API handles: PKCE, asymmetric token signing and verification, workspace isolation, token revocation, rate limiting, credential delivery security. You handle: storing theclient_secret in a secrets manager, storing tokens encrypted server-side, validating the state parameter on the OAuth callback, revoking tokens when users disconnect, rotating credentials if compromised.
Authentication
Token storage, refresh flow, and revocation.
Register your app
Credential delivery and the 15-minute link window.
Rotate app credentials
When and how to rotate the client_secret.
Rate limits
Limits by method and endpoint type.
Incident response
If you suspect yourclient_secret or tokens have been compromised:
- Revoke all active tokens via
POST /oauth/revokefor each affected workspace - Rotate credentials immediately via
POST /v1/auth/rotate-app - Update your secrets manager with the new
client_secret - Contact
security@vendaze.comwith therequest_idof any suspicious requests - Notify affected users that they need to re-authorize
- Review your logs for unauthorized data access during the exposure window