Skip to content

Security Guidelines

Security Guidelines

How to keep your app (and its users) secure.

At Canva, the security of our platform is paramount, and we expect app developers to maintain similar standards. This page outlines some of the key recommendations to keep your app (and its users) secure.

<Note> Canva maintains some responsibility for security, but not all responsibilities. For a complete list of security responsibilities you'll need to consider for your app, see the Canva Apps SDK Shared responsibility model for Canva Apps </Note>

Use reasonable security measures

Security is a huge topic, and it's beyond the scope of this documentation to explain every measure you could take to keep an app secure, but a good starting point is to ensure your app is not vulnerable to the OWASP Top 10.

Respect Canva's Content Security Policy

Canva applies a Content Security Policy (CSP) to the app's iframe. This policy prevents apps from loading certain resources within the iframe, such as third-party scripts. Apps can't circumvent the policy, but the app may break in surprising ways if it violates the policy, so it's important to be mindful of the restrictions.

To learn more, see Content Security Policy.

Configure Cross-Origin Resource Sharing

Cross-Origin Resource Sharing (CORS) is a security feature of web browsers that blocks client-side HTTP requests between different origins. We recommend setting the most restrictive policy possible.

To learn more, see Cross-Origin Resource Sharing.

Verify HTTP requests

When an app sends an HTTP request to a backend, the backend should verify that the request is from a known, trusted source. This prevents bad actors from sending arbitrary (and potentially malicious) requests to the backend.

For Node.js backends, we recommend using the @canva/app-middleware package, which provides built-in JWT verification, JWKS caching, and error handling.

To learn more, see HTTP request verification.

Store secrets securely

Apps often need to store secrets and tokens, such as API keys or access tokens. There are inherent risks to this, so it's important to consider those risks and mitigate against them.

Here's what we recommend:

  • When extracting information about the current user from a JSON Web Token (JWT), always verify the token. This ensures the token has not been tampered with. For Node.js backends, use the @canva/app-middleware package for secure JWT verification. To learn more, see JSON Web Tokens.
  • When integrating with third-party services, use tokens that have the least amount of access to that service as possible. This reduces the potential impact of a breach.
  • Use storage mechanisms, such as JavaScript closures instead of WebStorage APIs, to store sensitive values such as API keys. WebStorage APIs can be accessed by anyone with access to the machine, simply by opening the browser's developer tools.
  • Keep secrets and tokens masked from users after they are stored in a database; avoid logging them to the console or displaying them after creation.
  • Use rate-limiting to prevent the misuse of tokens.
  • Transmit tokens securely using POST requests rather than including them in the URL query string, to avoid exposure through third-party logging.
  • Always associate access tokens with the combination of the ID of the user and the ID of their team. This ensures that, if a user is removed from the team, their access through the app is also revoked.
  • If an access token is no longer needed, delete the token immediately. For example, delete access tokens as soon as a user deletes their account, data, or connection between Canva and a third-party platform.
  • Maintain strict token and capability isolation, ensuring that all token-bound functionality is available only to the user it was issued to.
  • Use Transport Layer Security (TLS) protocols and ciphers to encrypt traffic between your app, its backend, and other services. This ensures any access tokens or secrets are never transmitted unencrypted.

Maintain ownership of subdomains

Many apps rely on dedicated subdomains to host backend services, identity endpoints, or other functional components. Because these subdomains often represent trusted surfaces to both users and relying parties, it's essential to ensure they remain properly configured and under your control at all times.

A subdomain may become vulnerable if its DNS records point to a resource that's unclaimed, de-provisioned, or misconfigured. This can enable a subdomain takeover, where an attacker gains control of the subdomain and can serve malicious content or impersonate your service.

For example, if an attacker controls any of these subdomains, they may be able to:

  • Issue fraudulent tokens or present malicious signing keys
  • Steal authorization or refresh tokens
  • Spoof authentication or authorization flows
  • Intercept or manipulate redirect flows
  • Masquerade as your IdP or authorization server

Because modern authentication protocols rely heavily on domain trust, you must monitor and secure these subdomains.

To reduce the risk of subdomain takeover, we recommend you do the following:

  • Regularly verify that any referenced service is actually running and under your control.
  • If a backend or identity service is decommissioned or migrated, update your DNS configuration immediately.
  • Make sure you have strict lifecycle oversight of these subdomains because of the severe impact of compromise.
  • Check DNS configurations, hosting status, and any service-specific ownership checks.
  • Avoid pointing subdomains to temporary, unmanaged, or short-lived resources unless you have processes ensuring they can't become orphaned.
  • Monitor for misconfigurations or unintended DNS targets. Even short periods of misalignment can be enough for an attacker to claim a subdomain.
  • Document subdomain lifecycle events, including provisioning, migration, and decommissioning, as part of your operational security practices.

Don't require users to download files

Your app should never ask or require users to download external files — especially executable ones. External files are a significant security risk and, at the very least, requiring users to download them erodes trust.

Shared Responsibility

Shared security responsibilities for developing Canva Apps.

Background

Shared responsibility models clarify security responsibility between a platform provider and developers building apps that connect to that platform.

Building apps that connect to Canva means that developers share the same users as Canva. As a result, developers must take some responsibility to protect user data and privacy, which can differ from other Software as a Service (SaaS) product expectations. Canva, as a provider, takes some responsibility, but not all of the security responsibility.

Read through the following sections to understand your security responsibilities, as well as Canva's responsibilities.

<Note> Make sure that you read, and are complying with, the Canva API and App Developer Terms.

Noncompliance may result in Canva:

  • Suspending your app
  • Disabling access to it from the Canva App Marketplace </Note>

We reserve the right to amend this page from time to time at our sole discretion.

<Note> For specific recommendations on how to security harden your app, see the Security guidelines. For more information on authorization security, see the Content Security Policy and the guide on Verifying JWTs. For authentication steps, see the guide on Authenticating users. </Note>

App concepts

Canva apps

Apps are plugins that add features to Canva. They run in the browser and are built with standard web technologies, such as JavaScript. Apps are built using the Canva Apps SDK, which is made up of libraries and capabilities that combine to build feature-rich apps. The Canva Apps SDK enables your app to:

  • Use standard web technologies to render a user interface.
  • Use the Fetch API to integrate with the app's backend.
  • Use the Apps SDK to integrate with the core Canva experience.

App architecture

The App architecture is comprised of the following components:

  • App SDK Libraries - methods that let you invoke App SDK functionality.
  • UI Components (optional) - a component suite that lets you define app user interfaces using a React-based component library.
  • App backend (optional) - an application server that allows you to complete complex computations, expose additional resources, or store additional information your users require.

App changes

Security responsibilities can change as you build your app. For example, if you're providing complex computations through an app backend, and storing additional information for users, you'll have additional responsibilities to maintain the security of the app backend. It's important to be aware of how your responsibilities could change if your app changes scope.

Security operations

Vulnerability management and disclosure

Minimize security incidents through early identification of vulnerabilities and timely remediation. Provide a framework to manage the constantly changing vulnerability landscape.

Your responsibilitiesCanva's responsibilities
Conduct regular security reviews of infrastructure and source code using vulnerability scanning tools, vulnerability disclosure programs, or penetration testing by external parties.Suspend apps that haven't mitigated security vulnerabilities, as explained in the Canva API and App Developer Terms.
Mitigate or remediate app security vulnerabilities, in accordance with the Canva API and App Developer Terms.Communicate with developers about vulnerabilities, in apps or the platform, that may affect their apps.
Notify Canva of critical or high security vulnerabilities discovered in your app, in accordance with the Canva API and App Developer Terms..

Monitoring and alerting

Your responsibilitiesCanva's responsibilities
Ensure adequate monitoring and alerting is implemented for backend functionality to ensure the timely identification and containment of security events or incidents.Ongoing monitoring of App SDK platform health, raising alerts in response to degraded performance, security, or abuse events.

Logging

Your responsibilitiesCanva's responsibilities
Ensure your app doesn't log sensitive security data, personally identifiable information, authentication tokens, and user-generated content, or any other data that might be deemed sensitive by your data classification policy.Maintain robust logging that includes an audit trail of actions performed within Canva.
Ensure you implement adequate logging for backend functionality to ensure the timely identification and containment of security events or incidents.Restrict access to logs based on organization permissions.

Incident response

As the frequency of security vulnerabilities increases, your incident response plan becomes crucial. It's essential to have effective measures in place to detect and respond to unauthorized access to your systems and data.

Your responsibilitiesCanva's responsibilities
Promptly notify Canva of any incidents involving Canva SDK app data in accordance with the Canva API and App Developer Terms.Maintain a detailed action plan for responding to security incidents, including steps to contain and remediate the attack, and communicate with stakeholders.
Develop a detailed action plan for responding to security incidents, including steps to contain and remediate the attack, and communicate with users.Regularly test the incident response plan to ensure its effectiveness.
Regularly test your incident response plan to ensure its effectiveness.

Network security

Ensure appropriate network security controls are implemented preventing threat actors from accessing sensitive information while requests are in transit between services.

Your responsibilitiesCanva's responsibilities
Use secure protocols and configurations to encrypt traffic between your integration and backend, and between internal services.Ensure that modern, secure protocols are supported by the platform.
Handle data collected and stored in your backend according to your data classification policy, or with current best practice.

Infrastructure security

Maintain the integrity, confidentiality, and availability of underlying infrastructure, and provide a safe computing environment.

Your responsibilitiesCanva's responsibilities
Ensure that you have hardened the app backend, and any associated services. For more information see OWASP Web Service Security Cheat Sheet and the OWASP Database Security Cheat Sheet.Ensure the platform infrastructure is hardened.
Scan regularly for security misconfigurations and vulnerabilities.Scan regularly for security misconfigurations and vulnerabilities.
Use the provided runtime in a way that doesn't purposely try to bypass security controls.Provide a secure runtime for apps that prevents bypassing security controls.

Disaster recovery

Data, source code, and other business assets underpin your apps and related system functionality. It's important to minimize the impact of accidental or malicious disasters with an action plan or other recovery mechanism.

Your responsibilitiesCanva's responsibilities
Establish a business continuity and disaster recovery plan to minimize the impact of outages to the functionality of your app during incidents, or after an accidental or malicious disaster.Ensure that data stored by Canva on behalf of your app is backed up, and can be reasonably restored in an incident.
Maintain business continuity and disaster recovery plans.

Subdomain ownership and lifecycle management

Subdomains used by apps, especially those hosting authentication, authorization, or identity-related services, must be actively maintained to prevent unauthorized control. Subdomain takeover occurs when a DNS record points to an unclaimed, de-provisioned, or misconfigured resource. If an attacker gains control of such a subdomain, they can impersonate legitimate services, intercept requests, or distribute malicious content under a trusted domain.

This risk is particularly significant when subdomains are used for OAuth/OIDC authorization servers, identity providers (IdPs), or other security-critical surfaces.

Your responsibilitiesCanva's responsibilities
Maintain ownership and active configuration of any service referenced by DNS records (for example, A, CNAME, or ALIAS records).Monitor Canva-owned subdomains for takeover indicators or misconfigurations.
Remove or update DNS entries that point to resources that have been deleted, renamed, expired, or migrated.Suspend or restrict apps that introduce critical subdomain risks, in line with the Canva API and App Developer Terms.
Validate ownership and claim status regularly, ensuring referenced infrastructure is actively provisioned.
Monitor for dangling DNS records, particularly for subdomains associated with OAuth/OIDC authorization servers, identity providers (IdPs), token and introspection endpoints, /.well-known/openid-configuration metadata, JWKS endpoints, and redirect URIs or callback handlers.
Ensure that security-critical subdomains are never delegated to unmanaged or temporary resources without proper lifecycle controls.
Respond promptly to notices about misconfigurations or potential takeover conditions.
Document subdomain lifecycle events, including provisioning, migration, and decommissioning, as part of your operational security practices.

Trust and safety

User identity and access management

Your responsibilitiesCanva's responsibilities
Verify user and team access to content before serving that content to a user using available mechanisms.Authenticate user and team membership.
Use authentication APIs for third-party platform access.Provide authentication APIs for third-party platform access.
Provide a mechanism for apps to verify user and team access to Canva content.

Denial-of-service prevention

Denial-of-Service (DoS) attacks deliberately and maliciously disrupt API, system, and site operations. DoS attacks degrade user experience. Protect your app with detection and mitigation mechanisms.

Your responsibilitiesCanva's responsibilities
Detect DoS attacks against app backends.Detect DoS attacks executed through app frontends, or caused by apps.
Mitigate DoS attacks against app backends.Mitigate DoS attacks executed through app frontends, or caused by apps.
Suspend apps that might be misbehaving or insufficiently managing high volumes of requests.

Abuse prevention

Your responsibilitiesCanva's responsibilities
Ensure your app works in accordance with the restrictions outlined in Section 5 of the Canva API and App Developer Terms.Detect and mitigate apps that disrupt the normal operations of Canva or other Canva apps.
Ensure your app does not exceed the Canva API and App SDK platform quotas and limits.Enforce platform limits, such as for storage and request throughput.

App

Authenticating requests to the app

Ensure that all requests made to apps are sufficiently authenticated.

Your responsibilitiesCanva's responsibilities
Authenticate users to your app, or the third-party platform, before serving additional content.Provide a secure mechanism to authenticate with apps, or other third-party platforms.
Adhere to current best security practices when authenticating to your platform, or to third-party platforms.Ensure state token authenticity is verified before proceeding to the next step in the authentication workflow.
Ensure you have verified nonce token authenticity before proceeding to the next step in the authentication flow.Authenticate the user to Canva before launching your Canva app.

Authorizing requests from the app

Ensure that every request made from apps to your backend is sufficiently authorized.

Your responsibilitiesCanva's responsibilities
Verify the authenticity of incoming requests to your app backend.Obtain user consent before launching your Canva app.
Verify that the user and team are authorized to access content before serving it.Ensure that only users with access to Canva can interact with apps.
Verify the user and team are authorized to access additional content being served through a third-party platform before providing access.For private apps, ensure that only users with access to the team can interact with the app.
Ensure that adequate controls are in place to prevent cross-site request forgery.

Authorizing requests to the app

Ensure that every request made from your backend to your app is sufficiently authorized.

Your responsibilitiesCanva's responsibilities
Verify the authenticity of incoming requests to your app from your app backend.

App framework

Ensure frameworks and third-party libraries used to build apps are free of security bugs, and you’re applying fixes in line with the Canva API and App Developer Terms.

Your responsibilitiesCanva's responsibilities
Ensure the frameworks and third-party libraries used in your app are up-to-date with the latest security patches.Apply secure development culture and practices when building the app framework.
Remediate defects and vulnerabilities within the App SDK framework.

Input validation and output encoding

Ensure sufficient input validation and output encoding within apps. For example, when returning HTML to render in the app's UI, ensure that you use HTML entity encoding for variables added to the web template. This helps protect users from attacks like cross-site scripting.

Your responsibilitiesCanva's responsibilities
Treat all user input as unsafe and untrusted, regardless of the input source.Appropriately encode all HTML output for UI Components.
Adhere to current best security practices when providing or consuming data from third-party platforms.
Validate data sent to your app, and ensure you encode data appropriately.

Business logic

Protect the legitimate process flow of an app, and don't expose the process flow in ways that results in negative consequences.

Your responsibilitiesCanva's responsibilities
Identify and remediate business logic flaws through regular testing.
Apply security controls in layers to mitigate business logic flaws.

Tenant security

Your responsibilitiesCanva's responsibilities
Ensure isolation between apps. An app, 'App A', cannot communicate with 'App B'.
Ensure isolation between users and teams. For example, 'Team A' can access 'App A'. Even if 'App A' is made available for 'Team B', a user in 'Team A', cannot use 'App A' to access the data of 'Team B'.

Data storage

Appropriately manage data throughout its lifecycle, from data entry to data destruction.

Your responsibilitiesCanva's responsibilities
Ensure that data collected and processed is minimized to only collect what's required for the app to function as intended.Maintain web storage separation and cleanup between user sessions.
Ensure that sensitive security data, such as API keys, pre-shared keys, or encryption keys, aren't hard-coded in source code. For more information see the OWASP Secrets Management Cheat Sheet and the OWASP Password Storage Cheat Sheet.
Ensure that sensitive security data, such as API keys, pre-shared keys, and encryption keys, aren't persisted.
Ensure that appropriate processes are in place to handle the revocation and rotation of sensitive security data.
Ensure that any personal information collected by your app is handled in accordance with your data classification policy, applicable data protection, and privacy legislation.
Limit disclosure of confidential information shared with employees, contractors, legal, or financial and accounting advisors to a need to know basis, as outlined in the Canva API and App Developer Terms.

Secure development activities

A secure software development framework is a set of functional practices that, when applied appropriately, can achieve the following:

  • Reduce the number of vulnerabilities in released software.
  • Reduce the potential impact of the exploitation of undetected or unaddressed vulnerabilities.
  • Address the root causes of vulnerabilities to prevent reoccurrences.
Your responsibilitiesCanva's responsibilities
Adopt secure software development frameworks or practices that aid in the identification, prioritization, and remediation of security vulnerabilities. For more information see the OWASP Secure Product Design Cheat Sheet.
Perform regular threat modelling on apps and their critical paths to identify, prioritize, and remediate threats that might impact the security of your app.

Verifying HTTP Requests

How to verify the authenticity of HTTP requests.

At their most basic, apps are web pages embedded in an iframe. As a result, they have access to many standard web APIs, including the Fetch API.

Using the Fetch API in an app is the same as using it anywhere else, but before you can release your app publicly, we require that your app's backend verifies the authenticity of incoming requests. This ensures that requests are arriving from the app and not from some other, potentially malicious source.

For Node.js backends, the @canva/app-middleware package simplifies the verification process by automatically handling token extraction, JWKS fetching, and JWT validation.

Warning: Some standard web APIs aren't available. To learn more, see Content Security Policy.

Step 1: Get a JWT from Canva

Before an app sends an HTTP request to its backend, it must request a JSON Web Token (JWT) from Canva. The app's backend can use this JWT to verify that the request is legitimate.

To get a JWT:

  1. Import the auth namespace from the @canva/user package:

    ts
    import { auth } from "@canva/user";
  2. Call the getCanvaUserToken method:

    ts
    const token = await auth.getCanvaUserToken();

    This method returns a JWT as a string.

Step 2: Send a request

  1. Use the Fetch API, or a library such as axios, to send an HTTP request:

    ts
    const response = await fetch("http://localhost:3001/my/api/endpoint");
  2. In the headers of the request, include an Authorization header:

    ts
    const response = await fetch("http://localhost:3001/my/api/endpoint", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    The header should contain the word Bearer and the JWT, separated by a space.

Step 3: Verify the request

To verify the request, you can either use the @canva/app-middleware package (recommended), or manually implement your own verification.

For Node.js backends, use the @canva/app-middleware package to automatically verify requests:

Express.js middleware

typescript
import express from "express";
import { user } from "@canva/app-middleware/express";

const app = express();

// Apply middleware to verify all requests
app.use("/my/api", user.verifyToken({ appId: process.env.CANVA_APP_ID }));

app.post("/my/api/endpoint", (req, res) => {
  // Access verified user information
  const { userId, brandId } = req.canva.user;

  // Your application logic here

  res.sendStatus(200);
});

app.listen(process.env.PORT || 3000);

For more information, see user.verifyToken.

Framework-agnostic approach

For other Node.js environments:

Alternative: Manual verification

If you're using a non-Node.js backend, you can manually extract and verify JWTs. Here's an example using Python with Flask:

Step 3a: Extract the JWT

When the backend receives a request, extract the JWT from the Authorization header:

python
from flask import Flask, request, jsonify
from functools import wraps

app = Flask(__name__)

def extract_token(auth_header):
    """Extract JWT from Authorization header"""
    if not auth_header:
        return None

    parts = auth_header.split()

    if len(parts) != 2 or parts[0].lower() != 'bearer':
        return None

    return parts[1]

@app.route('/my/api/endpoint', methods=['POST'])
def api_endpoint():
    auth_header = request.headers.get('Authorization')
    token = extract_token(auth_header)

    if not token:
        return jsonify({'error': 'Unauthorized'}), 401

    # Verify token (see next step)
    # ...

    return jsonify({'message': 'Success'}), 200

If the Authorization header doesn't contain a token, reject the request with a 401 status code.

Step 3b: Verify the JWT

By itself, the JWT is an indecipherable string. To get useful information out of the JWT, it needs to be decoded and verified. To learn how to do this, see JSON Web Tokens.

Step 3c: Reject invalid requests

The verified JWT is an object that should contain the following properties:

  • aud - The ID of the app.
  • brandId - The ID of the user's team.
  • userId - The ID of the user.

If any of these properties aren't available, reject the request with a 401 status code:

python
if not verified.aud or not verified.brandId or not verified.userId:
    return jsonify({'error': 'Unauthorized'}), 401

API reference

  • auth.getCanvaUserToken

Verifying JWTs

How to verify a JSON Web Token (JWT).

For security reasons, Canva uses JSON Web Tokens (JWTs) to encode certain information, such as the ID of the user or the ID of a user's design. To access this information, apps must decode and verify the JWTs.

Danger: Apps must only verify JWTs through the app's backend — never through the frontend.

<Note> For Node.js backends: We recommend using the @canva/app-middleware package, which provides built-in verification for both user tokens and design tokens, along with JWKS caching and error handling. This package simplifies the verification process and follows security best practices. </Note>

Types of tokens

In the Apps SDK, there are two types of tokens:

  • Design tokens - Encode information about the current design, such as the ID of the design
  • User tokens - Encode information about the current user, such as the ID of the user and their team

The steps for verifying each type of token are the same, but the tokens encode different information, and apps access them in different ways:

  • An app can call the getDesignToken method. This method returns a design token, which the app can use to get the ID of a design and associate data with that design. To learn more, see Using design IDs.
  • An app can start an authentication flow. This redirects the user to the app's Redirect URL. Canva appends a user token to the URL. The app's backend can use this token to authenticate the user using a third-party platform.
  • An app can call the auth.getCanvaUserToken method. This method returns a user token, which the app can use to verify HTTP requests or identify users (for example, to check if they're authenticated).

Verifying JWTs with @canva/app-middleware

For Node.js backends, the @canva/app-middleware package provides a simple and secure way to verify JWT tokens.

Installation

shell
npm install @canva/app-middleware

Express.js middleware

For Express.js applications, use the built-in middleware:

<Tabs> <Tab name="User tokens" />

<Tab name="Design tokens" /> </Tabs>

Framework-agnostic function

For other Node.js environments (Next.js, AWS Lambda, Cloudflare Workers, and so on):

<Tabs> <Tab name="User tokens" />

<Tab name="Design tokens" /> </Tabs>

Manually verifying JWTs

If you're using a non-Node.js backend, you can manually verify JWTs. The following steps show how to implement JWT verification from scratch in TypeScript, which you can then adapt to your preferred language or framework.

Step 4: Verify the token

Use the public key to verify the JWT:

ts
const verified = jwt.verify("JWT_GOES_HERE", publicKey, {
  audience: "YOUR_APP_ID",
});

The exact syntax will depend on the library you're using.

If the token is valid, the verified token will be a dictionary. The properties in this dictionary will depend on whether the token is a design token or a user token.

Design tokens

If the token is a valid design token, the object will contain the following properties:

  • aud - The ID of the app.
  • designId - The ID of the current design.

If these properties aren't available, it means the token or public key are invalid:

tsx
if (!verified.aud || !verified.designId) {
  throw new Error("The design token is not valid");
}

User tokens

If the token is a valid user token, the object will contain the following properties:

  • aud - The ID of the app.
  • brandId - The ID of the user's team.
  • userId - The ID of the user.

If these properties aren't available, it means the token or public key are invalid:

tsx
if (!verified.aud || !verified.brandId || !verified.userId) {
  throw new Error("The user token is not valid");
}

Canva Developer Documentation SOP Site