1. Docs
  2. Keys & Credentials

Keys & Credentials

Every credential Canopy issues, which integration scenario needs which, and exactly what goes in your app's configuration. Each scenario below is self-contained: find yours and you have everything you need, no cross-referencing.

Overview

Canopy issues a small set of credentials, and which ones you need depends entirely on what your app does. There are four integration scenarios: pick yours below and you'll find a complete checklist plus a copy-paste configuration. The only value every scenario shares is CANOPY_API_URL (where the Canopy API lives); everything else is specific to the scenario.

The four scenarios:

Hosted login (OAuth2): Canopy's hosted page signs your end-users in, then your backend exchanges an authorization code for tokens. Needs an OAuth client (client_id + client_secret) and a redirect URI.Direct identity auth: your app renders its own login UI and calls Canopy's identity-auth API directly. Needs the Environment's publishable key.Self-service signup: end-users create their own accounts from your UI via POST /v1/identity/auth/register (or the email-OTP flow). Uses the same publishable key as Direct identity auth, with no extra credential; enable Allow self-signup on the Environment, and the checklist under Direct identity auth covers you.Server-to-server API: backend automation that manages roles, identities, permissions, or evaluates access with no end-user present. Needs an API key.

Hosted login (OAuth2)

Your app redirects the browser to Canopy's hosted login page (/oauth/authorize) using the OAuth 2.0 authorization-code flow with PKCE. After the user signs in, Canopy redirects back to your redirect_uri with a one-time code, and your backend exchanges it for tokens at /oauth/token using the client secret.

When to use: You want Canopy to own the login UI (password handling, email verification, MFA, reset) and just hand your backend a signed JWT.

What you need
CANOPY_API_URL: base URL of the Canopy API (e.g. https://auth.canopy-io.com). Where: your Canopy instance. Not a secret.OAUTH_CLIENT_ID: public identifier of your OAuth client. Where: Console → Integrations → OAuth Clients → your client (visible any time). Publishable: safe in browsers and redirects.OAUTH_CLIENT_SECRET: backend credential used in the /oauth/token exchange. Where: shown once when you register the client (or after Rotate secret). Secret: backend only, never ship to the browser.OAUTH_REDIRECT_URI: where Canopy returns the user after login. Where: must exactly match one of the client's registered redirect URIs. Not a secret.
Your configuration
# Where Canopy lives (every scenario needs this)
CANOPY_API_URL=https://auth.canopy-io.com

# OAuth client: Console → Integrations → OAuth Clients
OAUTH_CLIENT_ID=<your client_id>
OAUTH_CLIENT_SECRET=<shown once at creation>   # secret, backend only
OAUTH_REDIRECT_URI=https://app.example.com/callback   # must match a registered URI

Full walkthrough: Hosted login · register the client under OAuth clients.

Direct identity auth

Your app renders its own sign-in form and posts credentials straight to Canopy's identity-auth endpoints (POST /v1/identity/auth/login, …/register, …/forgot-password, …/reset-password). The same signed JWT comes back: no redirects, no consent screen. The request is keyed to one Environment by its publishable key. When the Environment has self-service signup enabled, the same key also powers browser-direct registration.

When to use: You want full control of the login UI, or to keep users on your domain. It's also the path for flows hosted login can't cover, like native mobile sign-in or custom onboarding.

What you need
CANOPY_API_URL: base URL of the Canopy API (e.g. https://auth.canopy-io.com). Where: your Canopy instance. Not a secret.PUBLISHABLE_KEY: the pk_… key that scopes the identity-auth calls (login, and self-service signup when enabled) to one Environment. Where: Console → the environment card → ⋯ → Publishable Key (visible any time). Publishable: safe to embed in client/browser code; it can't manage anything on its own.
Your configuration
# Where Canopy lives (every scenario needs this)
CANOPY_API_URL=https://auth.canopy-io.com

# Environment publishable key: env card → ⋯ → Publishable Key
PUBLISHABLE_KEY=pk_<your publishable key>   # publishable, safe in client code

Full walkthrough: Direct API.

Server-to-server API

Your backend calls the public API (/api/v1/*) on its own behalf, managing roles, permissions, identities, and the hierarchy, or evaluating access, with no end-user in the loop. Every request carries an API key in the X-API-Key header.

When to use: Automation, CI scripts, trusted backend services, and anything that runs without a logged-in person.

What you need
CANOPY_API_URL: base URL of the Canopy API (e.g. https://auth.canopy-io.com). Where: your Canopy instance. Not a secret.API_KEY: the cnpy_… key sent as X-API-Key; scoped to one Environment with the permissions you grant it. Where: Console → Integrations → API Keys → Create (the value is shown once at creation; rotate to get a new one). Secret: backend only, never commit or expose to a browser.
Your configuration
# Where Canopy lives (every scenario needs this)
CANOPY_API_URL=https://auth.canopy-io.com

# API key: Console → Integrations → API Keys → Create
API_KEY=cnpy_<shown once at creation>   # secret, backend only

Full walkthrough: API keys.

Handling secrets safely

Rules that apply everywhere

A few rules apply across every scenario, worth knowing wherever you landed above.

Secret vs publishable. API_KEY (cnpy_) and OAUTH_CLIENT_SECRET are secrets: keep them server-side, out of client code and version control. PUBLISHABLE_KEY (pk_) and OAUTH_CLIENT_ID are publishable: safe to expose in browsers and redirect URLs.Secrets are shown once. Canopy stores only a hash, so a secret is displayed once at creation and can never be retrieved again. Capture it into a secrets manager (Vault, AWS Secrets Manager, a CI secret) immediately.Lost a secret? Rotate, don't hunt. Both API keys and OAuth client secrets support Rotate, which mints a new value (the old one stops working immediately) without changing the key's identity, scopes, or audit history.Never commit any of it. Inject secrets via environment variables or a secrets manager. CANOPY_API_URL and redirect URIs are plain config, not secrets, and are fine to keep in source.
Environment
API version
v1.0
On this page Was this page helpful?

Tell us how we can improve this guide.