Skip to main content
Sandbox and production are separate environments. Production runs on Moca Chain mainnet and has its own Developer Dashboard. Nothing you set up in sandbox carries over: you register your app, keys, issuer, schemas, and programs again, and you switch your code to the production settings.

What changes in production

Credentials are network-specific. Credentials issued in sandbox do not exist in production. See Environments.

Step 1: Set up your production partner account

  1. Sign in to the production Developer Dashboard.
  2. In Account → General Settings, copy your production Partner ID. Do not assume it matches your sandbox Partner ID.
  3. Fill in your app’s Name, Logo URL, and Website URL. Users see them during login, transactions, issuance, and verification.
  4. Register your production JWKS URL. It must be public HTTPS and reachable from AIR servers. See JWKS endpoint setup.
  5. Under Account → Domains, add the HTTPS domains that load AIR Kit. You can add up to 3, and wildcards such as *.myapp.example.com are supported. localhost is not available in production.
For what each setting does, see Developer Dashboard.

Step 2: Switch the SDK to production

credentialNetwork is only accepted when buildEnv is BUILD_ENV.PRODUCTION.
Keep sandbox and production values in separate environment configurations, so a production build never ships with a sandbox Partner ID or program ID.

Step 3: Point your backend at production

Your Partner JWT endpoint signs tokens for the production Partner ID:
  • Sign with the private key whose public key is in your production JWKS, and set the kid to match.
  • Keep tokens short-lived and generate them on the server only. See SDK authentication.
  • If you call the AIR API directly, for example initialize-user and dstorage/vcs for direct issuance, use the production base URL.

Step 4: Set up credentials in production

Skip this step if you use AIR Kit only for login or wallets. If you issue credentials:
  1. Deploy your issuer service for production on a domain you control, with a durable database and NODE_ENV=production. The reference issuer service uses PostgreSQL. See Issuer backend hosting.
  2. Register the issuer in Issuer → Settings on the production Dashboard: the did:web Issuer DID, the issuer API key, the JWKS URL, and the endpoint URLs.
  3. Recreate your schemas and issuance programs in the production Dashboard, and update the program IDs in your app.
  4. Decide your revocation setup, including whether to enable the token status list, before you issue the first production credential.
  5. If you issue Iden3 credentials, contact the AIR team to enable them in production.
The issuer host becomes your issuer identity once you issue on mainnet, so do not change it afterwards. If you verify credentials:
  1. Recreate your verification programs in the production Dashboard and update the program IDs in your app.
  2. Constrain each program to the production Issuer DIDs you trust.
  3. Verify every presentation on your backend, with a fresh nonce per verification. See Verify SD-JWT on your backend.

Step 5: Set up accounts and gas

Skip this step if you do not use smart accounts.
  • Contact the AIR team to set up gas sponsorship policies and the chains in your partner configuration. See Paymaster.
  • If your app or users pay gas on Moca Chain, see How to get $MOCA.
  • If you use session keys, scope them to the smallest set of actions and give them short expiry times.

Step 6: Test on production before launch

Run your main flows end to end with a real test account on production:
  • Log in and log out, including on each mobile platform you ship.
  • Issue a credential, verify it, revoke it, and confirm that verification then fails.
  • Send a transaction from the smart account, if you use one.
  • Check that a request from a domain that is not on your allowed list is refused.

Go-live checklist

Dashboard and keys
  • Signed in to the production Developer Dashboard, and copied the production Partner ID
  • App name, logo URL, and website URL set
  • Production JWKS URL is public HTTPS and registered
  • Partner JWTs are signed server-side with a key whose kid is in that JWKS, and expire within 5 minutes
  • Allowed domains list only your HTTPS production domains
  • Private keys and API keys are stored in a secrets manager, not in source control or client code
SDK and apps
  • Web apps initialize with BUILD_ENV.PRODUCTION and credentialNetwork: "mainnet"
  • Flutter apps initialize with Environment.production
  • Mobile apps include account.air3.com in their associated domains and asset statements
  • No sandbox Partner ID, program ID, or URL remains in the production build
  • Logging is off or reduced for production
Issuing credentials (if you issue)
  • Issuer service deployed on a domain you control, with NODE_ENV=production
  • The issuer database is durable and its migrations are applied
  • did:web Issuer DID, issuer API key, JWKS URL, and endpoint URLs registered in the production Dashboard
  • Schemas and issuance programs recreated in production, and their IDs updated in your app
  • Revocation tested; token status list partition size final and a publish job scheduled, if you use it
  • Iden3 credentials enabled by the AIR team, if you use them
Verifying credentials (if you verify)
  • Verification programs recreated in production, and their IDs updated in your app
  • Programs limited to the production Issuer DIDs you trust
  • Backend verifies every presentation, including the key-binding JWT, and uses each nonce only once
Accounts and gas (if you use smart accounts)
  • Gas sponsorship policies and chains confirmed with the AIR team
  • Sponsorship spend is monitored
  • Session keys are narrowly scoped with short expiry
Operations
  • All main flows tested end to end on production
  • Alerts set up for failed authentication (spikes in 401 and 403 responses) and unusual issuance volume
  • A key rotation plan: add the new key to your JWKS before removing the old one
For the full list of security practices, see the Security checklist.