Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt

Use this file to discover all available pages before exploring further.

Once a sandbox environment is configured the way you want, you can promote that configuration to your live environment with the same config-as-code pair you already use: dyn export and dyn apply. Export captures everything that defines how the environment behaves, so a single apply brings live into line with sandbox. One thing never crosses over: secrets. The IaC commands ignore secrets entirely — dyn export omits every secret field, and dyn apply ignores any secret field even if you add one to the file by hand. So you never put a secret in your YAML (it simply won’t do anything), and you set each secret directly in the live environment instead. This is deliberate: it keeps plaintext secrets out of config files and out of any environment they don’t belong to.
What you need: The CLI installed and authenticated, and the IDs of both environments. See Getting started. This guide builds on Config as code — read it first if dyn export / dyn apply are new to you.
Managing secrets through config-as-code — referencing a secret held in your secret manager or environment and resolving it at apply-time, so the plaintext never touches the file — is on the roadmap. Until then, secrets are set out-of-band as described in step 4.

1. Snapshot the sandbox

Switch to the sandbox environment and export it. Confirm the active environment first so you snapshot the right one.
dyn environments switch <sandbox-env-id>
dyn status                                  # confirm you're on sandbox
dyn export --output-file sandbox.yaml

2. Dry-run against live

Switch to live and preview the plan. The dry-run prints exactly what would be added, updated, or deleted without changing anything.
dyn environments switch <live-env-id>
dyn status                                  # confirm you're on live
dyn apply -f sandbox.yaml --dry-run
Read the plan carefully. Because you’re applying a full environment, expect creates for resources live doesn’t have yet, and updates where the two environments differ.

3. Apply to live

Promoting auth-critical resources (providers, gates, JWT settings) and tightening security settings are gated by default. Opt in explicitly once the dry-run looks right.
dyn apply -f sandbox.yaml --allow-critical-changes
Add --allow-security-downgrades only if the plan intentionally relaxes a security setting, --allow-new-domains if it introduces new trusted hosts, and --allow-delete if you want live resources missing from the file to be removed. See Safety gates for the full set.

4. Set secrets in live

Set each secret directly against the live environment. Secrets are never in the export and are ignored on apply, so this is the only way to get them across.
# OAuth client secret / key-auth API key, per provider
dyn providers update <provider-id> --client-secret <live-secret>

# Mint a fresh API token for live and update your backends / CI
dyn tokens create-post --note "live" --scopes <scopes>
The hCaptcha secret key is marked read-only in the CLI (dyn settings set refuses it), so set it in the Dynamic dashboard under the live environment’s security settings. Webhooks are recreated by the apply with new signing secrets generated by the live environment — update whatever verifies those payloads with the new secret (fetch it with dyn webhooks get <id> --include-secret). See the table below for the complete list.

5. Verify

Re-run a dry-run against live. A clean plan (no changes) confirms the non-secret config matches. Then exercise a real auth flow in live to confirm the secrets you set in step 4 work end to end.
dyn apply -f sandbox.yaml --dry-run         # expect "no changes"

What migrates

dyn export / dyn apply reconcile the full set of admin-controlled configuration:
ResourceNotes
ProvidersProvider config and toggles migrate; the secret does not (below).
WebhooksSubscriptions and event lists migrate; the signing secret does not.
GatesFeature gate configuration.
OriginsAllowed CORS / iframe origins.
Deeplink URLsMobile deeplink allowlist.
AllowlistsWallet / address allowlist entries.
Project settingsThe full settings tree — auth, SDK, and security settings.

What does not migrate

These are never exported and are ignored on apply, so set them directly in the live environment.
SecretWhy it’s not in the exportSet it in live with
Provider clientSecretOmitted from the export; stored KMS-encrypted and never returned by the API. Covers OAuth client secrets and key-auth API keys (e.g. TRM / Chainalysis screening).dyn providers update <id> --client-secret <secret>
Provider auth credentialsApple Sign-In ES256 key, Twilio SMS (accountSid, Verify SID), SendGrid — omitted like clientSecret.dyn providers update <id> … with the matching flags
Webhook signing secretReturned only by the single-webhook GET with --include-secret, never in the collection export. Live generates its own on create.Read with dyn webhooks get <id> --include-secret, then update your verifier
API tokensCannot be read back after creation — there is nothing to export.dyn tokens create-post --note "live" --scopes <scopes>
hCaptcha secretKeyWrite-only setting; the API never returns it in a GET, and the CLI marks it read-only.Dynamic dashboard → live environment security settings
Environment JWKS / signing keysRead-only and per-environment; the server manages them. Live already has its own.Nothing to set — point JWT verifiers at the live JWKS URL
Anything that verifies Dynamic-issued JWTs against the sandbox signing keys (a backend checking session tokens, an external JWT consumer) must switch to the live environment’s JWKS endpoint / public keys. Keys are never shared across environments.

Handle the export file as a secret

Even though secret fields are omitted, treat sandbox.yaml as sensitive: it describes your entire auth surface, and a few settings (such as third-party API tokens stored in the settings tree) are returned in plaintext. Don’t commit it with real values, share it only over trusted channels, and delete local copies once the migration is done.