Canva Security Basics
Overview
Security best practices for Canva Connect API OAuth 2.0 tokens, client credentials, and webhook verification. The Canva API uses OAuth with PKCE — there are no static API keys.
Token Security
Never Expose Client Secrets
CANVA_CLIENT_ID=OCAxxxxxxxxxxxxxxxx
CANVA_CLIENT_SECRET=xxxxxxxxxxxxxxxx
.env
.env.local
.env.*.local
Token Storage
interface SecureTokenStore {
save(userId: string, tokens: {
accessToken: string;
refreshToken: string;
expiresAt: number;
}): Promise<void>;
get(userId: string): Promise<CanvaTokens | null>;
delete(userId: string): Promise<void>;
}
Token Revocation
async function revokeCanvaToken(token: string, clientId: string, clientSecret: string) {
const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
await fetch('https://api.canva.com/rest/v1/oauth/revoke', {
method: 'POST',
headers: {
'Authorization': `Basic ${basicAuth}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({ token }),
});
}
Least-Privilege Scopes
const SCOPE_PROFILES = {
readonly: ['design:meta:read', 'brandtemplate:meta:read', 'folder:read'],
creator: ['design:content:write', 'design:content:read', 'design:meta:read', 'asset:write', 'asset:read'],
collaborator: [
'design:content:write', 'design:content:read', 'design:meta:read',
'asset:write', 'asset:read', 'comment:read', 'comment:write',
'collaboration:event',
],
};
Webhook Signature Verification
Canva signs webhook payloads with JWK. Verify before processing.
import { createRemoteJWKSet, jwtVerify } from 'jose';
const JWKS = createRemoteJWKSet(
new URL('https://api.canva.com/rest/v1/connect/keys')
);
async function verifyCanvaWebhook(
token: string,
): Promise<{ valid: boolean; payload?: any }> {
try {
const { payload } = await jwtVerify(token, JWKS, {
issuer: 'canva',
});
return { valid: true, payload };
} catch {
return { valid: false };
}
}
app.post('/webhooks/canva', express.text({ type: '*/*' }), async (req, res) => {
const result = await verifyCanvaWebhook(req.body);
if (!result.valid) res.().();
(result.);
res.().();
});
Security Checklist
Error Handling
| Security Issue | Detection | Mitigation |
|---|
| Token in logs | Log audit | Redact before logging |
| Excessive scopes | Scope audit | Reduce to minimum needed |
| Stale refresh token | Auth failures | Re-authorize user |
| Unsigned webhook | Missing verification | Always verify JWK signature |
| Client secret in frontend | Code review | Server-side only |
Resources
Next Steps
For production deployment, see canva-prod-checklist.