Skip to content
Skillv1.0.0

canva-multi-env-setup

Configure Canva Connect API across development, staging, and production environments. Use when setting up multi-environment deployments, managing OAuth credentials per environment, or implementing env

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/canva-pack/skills/canva-multi-env-setup/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill canva-multi-env-setup. Copyright stays with the author (MIT).

Canva Multi-Environment Setup

Overview

Configure Canva Connect API integrations across development, staging, and production. Each environment needs separate OAuth integrations registered in the Canva developer portal with distinct redirect URIs.

Prerequisites

  • Separate reviewed OAuth clients, redirect URIs, secret stores, tenant/asset scopes, and owners for each environment.
  • Synthetic development/staging assets and a deployment process that cannot silently select production configuration.

Instructions

  1. Resolve the environment from an explicit allowlist and fail if its OAuth client, redirect URI, or scope configuration is absent or mismatched.
  2. Keep tokens, caches, queues, and webhook endpoints isolated by environment; never share production credentials with lower environments.
  3. Verify staging with synthetic assets, then promote immutable configuration through the reviewed release path.

Environment Strategy

Environment Canva Integration Redirect URI Data
Development my-app-dev http://localhost:3000/auth/canva/callback Test account
Staging my-app-staging https://staging.myapp.com/auth/canva/callback Staging account
Production my-app-prod https://myapp.com/auth/canva/callback Real users

Important: Register a separate Canva integration per environment. Each gets its own client ID and secret.

Configuration

// src/config/canva.ts
interface CanvaEnvConfig {
  clientId: string;
  clientSecret: string;
  redirectUri: string;
  baseUrl: string;  // Always api.canva.com — Canva has no sandbox API
  scopes: string[];
  debug: boolean;
}

const configs: Record<string, CanvaEnvConfig> = {
  development: {
    clientId: process.env.CANVA_CLIENT_ID!,
    clientSecret: process.env.CANVA_CLIENT_SECRET!,
    redirectUri: 'http://localhost:3000/auth/canva/callback',
    baseUrl: 'https://api.canva.com/rest/v1', // No sandbox exists
    scopes: ['design:content:write', 'design:content:read', 'design:meta:read', 'asset:write', 'asset:read'],
    debug: true,
  },
  staging: {
    clientId: process.env.CANVA_CLIENT_ID!,
    clientSecret: process.env.CANVA_CLIENT_SECRET!,
    redirectUri: process.env.CANVA_REDIRECT_URI!,
    baseUrl: 'https://api.canva.com/rest/v1',
    scopes: ['design:content:write', 'design:content:read', 'design:meta:read', 'asset:write', 'asset:read'],
    debug: false,
  },
  production: {
    clientId: process.env.CANVA_CLIENT_ID!,
    clientSecret: process.env.CANVA_CLIENT_SECRET!,
    redirectUri: process.env.CANVA_REDIRECT_URI!,
    baseUrl: 'https://api.canva.com/rest/v1',
    scopes: ['design:content:write', 'design:content:read', 'design:meta:read'],
    debug: false,
  },
};

export function getCanvaConfig(): CanvaEnvConfig {
  const env = process.env.NODE_ENV || 'development';
  return configs[env] || configs.development;
}

Secret Management

Local Development

# .env.local (git-ignored)
CANVA_CLIENT_ID=OCA_dev_xxxxxxxx
CANVA_CLIENT_SECRET=dev_xxxxxxxx

GitHub Actions / CI

# Per-environment secrets
gh secret set CANVA_CLIENT_ID --env staging --body "OCA_staging_xxx"
gh secret set CANVA_CLIENT_SECRET --env staging --body "staging_xxx"
gh secret set CANVA_CLIENT_ID --env production --body "OCA_prod_xxx"
gh secret set CANVA_CLIENT_SECRET --env production --body "prod_xxx"

Production — Cloud Secret Managers

# GCP Secret Manager
gcloud secrets create canva-client-id-prod --data-file=-
gcloud secrets create canva-client-secret-prod --data-file=-

# AWS Secrets Manager
aws secretsmanager create-secret \
  --name canva/production/client-id \
  --secret-string "OCA_prod_xxx"

# HashiCorp Vault
vault kv put secret/canva/production \
  client_id="OCA_prod_xxx" \
  client_secret="prod_xxx"

Environment Isolation Guards

// Prevent accidental cross-environment operations
function assertEnvironment(expected: string): void {
  const actual = process.env.NODE_ENV || 'development';
  if (actual !== expected) {
    throw new Error(`Expected ${expected} environment, got ${actual}`);
  }
}

// Guard destructive operations
async function deleteAllUserDesigns(userId: string, token: string) {
  assertEnvironment('development'); // Block in staging/production
  // ...
}

Token Storage per Environment

// Development: file-based for convenience
// Staging/Production: encrypted database

function getTokenStore(): TokenStore {
  const env = process.env.NODE_ENV || 'development';

  if (env === 'development') {
    return new FileTokenStore('.canva-tokens.json'); // git-ignored
  }

  return new DatabaseTokenStore({
    connectionString: process.env.DATABASE_URL!,
    encryptionKey: process.env.TOKEN_ENCRYPTION_KEY!,
  });
}

Canva-Specific Considerations

  1. No sandbox API — Canva has no separate sandbox environment. All environments hit api.canva.com/rest/v1. Use separate Canva accounts for dev/staging.
  2. Separate integrations — Each environment should be a distinct integration in the Canva developer portal to avoid redirect URI conflicts.
  3. Scope differences — Use broader scopes in dev for testing, minimal scopes in production.
  4. Token isolation — Never share tokens across environments. Refresh tokens are single-use.

Output

Environment setup yields an approved environment label, configuration/version receipt, OAuth/redirect validation, and scope-isolation result. It excludes client secrets, tokens, tenant identifiers, and design data.

Examples

For a staging release, load the dedicated staging client and redirect URI from protected configuration, verify a synthetic design callback, and record the redacted result. If the environment resolves to production or shares a credential, fail the deployment rather than falling back.

Error Handling

Issue Cause Solution
Wrong redirect URI Environment mismatch Use per-environment integration
Missing secret Not deployed to env Add via secret manager
Token cross-contamination Shared token store Isolate by environment prefix
Production guard triggered Wrong NODE_ENV Set correct environment variable

Resources

Next Steps

For observability setup, see canva-observability.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-canva-multi-e-31d738/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-canva-multi-e-31d738.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-canva-multi-e-31d738",
  "kind": "skill",
  "name": "canva-multi-env-setup",
  "description": "Configure Canva Connect API across development, staging, and production environments. Use when setting up multi-environment deployments, managing OAuth credentials per environment, or implementing environment-specific Canva configurations. Trigger with phrases like \"canva environments\", \"canva staging\", \"canva dev prod\", \"canva environment setup\", \"canva config by env\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "design",
      "canva",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Configure Canva Connect API across development, staging, and production environments. Use when setting up multi-environment deployments, managing OAuth credentials per environment, or implementing environment-specific Canva configurations. Trigger with phrases like \"canva environments\", \"canva staging\", \"canva dev prod\", \"canva environment setup\", \"canva config by env\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/canva-pack/skills/canva-multi-env-setup/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/canva-pack/skills/canva-multi-env-setup/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/canva-pack/skills/canva-multi-env-setup/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(aws:*),",
      "Bash(gcloud:*),",
      "Bash(vault:*)"
    ],
    "license": "MIT"
  },
  "instructions": "# Canva Multi-Environment Setup\n\n## Overview\n\nConfigure Canva Connect API integrations across development, staging, and production. Each environment needs separate OAuth integrations registered in the Canva developer portal with distinct redirect URIs.\n\n## Prerequisites\n\n- Separate reviewed OAuth clients, redirect URIs, secret stores, tenant/asset scopes, and owners for each environment.\n- Synthetic development/staging assets and a deployment process that cannot silently select production configuration.\n\n## Instructions\n\n1. Resolve the environment from an explicit allowlist and fail if its OAu",
  "cost": {
    "context_tokens": 1651
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-canva-multi-e-31d738/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.