Admin Login
HomeGuidesAPI ReferenceChangelogBlockdaemon Main Docs
Log In
Guides

customer-config.yml Reference

Field-by-field reference for the customer-owned deployment configuration file.

Overview

customer-config.yml is the single file you own and maintain for your Institutional Vault deployment. It describes every (environment, namespace) pair you operate — QA testnet, production mainnet, staging, etc. — in one place.

Blockdaemon provides:

  • The deployer bundle (Makefile + scripts)
  • Container images (wallet, policy nodes, frontend, NATS)
  • Consulting and support

You provide and maintain customer-config.yml. When you upgrade to a new image version, you update one field. When you add a blockchain or change a DNS name, you edit this file and re-run the deployer — no new bundle from BD required.

How It Works

customer-config.yml
       │
       ▼
make generate-customer-assets
       │
       ▼
target/<env>/<namespace>/
  ├── bd-wallet.yml          # full MPA config, generated — do not edit
  ├── <env>.tfvars           # Terraform variables, generated — do not edit
  ├── values.yml             # Helm values, generated — do not edit
  └── customer-secrets.yml   # secret scaffold, generated — seed once, then leave
       │
       ▼
make deploy-*

You edit customer-config.yml. Everything under target/ is generated output.

📘

Note:

customer-config.yml contains no secrets — only references and plaintext configuration values. Secrets live in your cloud secret store (Azure Key Vault, GCP Secret Manager, or AWS Secrets Manager). The customer_secrets block is an exception: it seeds initial values into the secret store on first deploy only.


Schema

environments:                    # list; one entry per logical environment (e.g. qa, prod, staging)
  - name: <string>               # environment label used for folder naming: target/<name>/<namespace>/
    namespaces:                  # list; one entry per deployment namespace in this environment
      - name: <string>           # Kubernetes namespace and Azure resource identifier
        subscription: <string>   # Azure: friendly subscription name. GCP: omit. EKS: omit.
        subscription_id: <string># Azure: subscription GUID. GCP: use `project`. EKS: use `account_id`.
        testnet: <bool>          # true = testnet/staging network; false = production mainnet
        features: [<string>]     # feature flags. Include "1.3" to enable CWP (Cold Wallet Platform).
        log_level: <int>         # 0=debug 1=info(default) 2=warn 3=error
        no_auth_token: <bool>    # true = deploy without a Blockdaemon API key (no Ubiquity/UTXO service)
        dns_prefix: <string>     # optional override for the per-namespace URL prefix

        management_environment:  # cluster-level (shared across namespaces on the same cluster)
          subscription: <string> # Azure: subscription that owns the DNS zone and management RG
          subscription_id: <string>
          location: <string>     # Azure region, e.g. "East US 2"
          resource_group: <string># management resource group name
          hosted_zone: <string>  # DNS zone, e.g. wallet.company.com
          admin_email: <string>  # email used for cert-manager ACME registration
          key_vault_allowed_ips: # CIDR list allowed to access Key Vault (use ["0.0.0.0/0"] to allow all)
            - <string>

        terraform_extra_vars:    # extra variables merged into the generated <env>.tfvars
          default_host: <string> # FQDN for the wallet API, e.g. api.wallet.company.com
          frontend_host: <string># FQDN for the wallet UI, e.g. app.wallet.company.com

        admins:                  # list of users bootstrapped as wallet administrators on first deploy
          - name: <string>
            email: <string>

        canton:                  # optional; omit entirely if not using Canton/Daml
          ledger_api_url: <string>
          admin_api_url: <string>
          json_ledger_api_url: <string>
          validator_api_url: <string>
          network: <string>      # e.g. mainnet, testnet, devnet
          token_url: <string>    # OAuth token endpoint
          audience: <string>     # OAuth audience

        blockchains:             # optional; list of blockchain networks to enable
          - family_name: <string>         # EVM, UTXO, Solana, etc.
            family_properties:
              evm_properties:
                chain_id: <int>           # EVM chain ID (1=Ethereum mainnet, 137=Polygon, etc.)
            native_symbol: <string>       # e.g. ETH, BTC
            protocol_name: <string>       # e.g. ethereum, bitcoin
            network_name: <string>        # e.g. mainnet, goerli, lower-qa
            mainnet_coin_type: <int>      # SLIP-44 coin type (60=ETH mainnet)
            decimals: <int>               # token decimals (18 for ETH)
            test_network: <bool>
            native_driver_url:            # RPC URL for this chain
              name: <string>              # secret name in your secret store
              type: azureSecret           # azureSecret | gcpSecret | awsSecret

        custom_event_streaming:  # optional; one entry per EVM tracker sidecar
          - name: <string>       # unique tracker name
            rpc_url:
              name: <string>
              type: azureSecret
            env:                 # optional extra env vars for the tracker container
              - name: <string>
                value: <string>
            blockchain:          # same shape as blockchains[] entry above
              native_symbol: <string>
              protocol_name: <string>
              network_name: <string>
              mainnet_coin_type: <int>
              decimals: <int>
              chain_id: <int>
              family_name: <string>
              native_driver_url:
                name: <string>
                type: azureSecret

        customer_secrets:        # optional; values written to your secret store on first deploy only.
                                 # Once seeded, changes here are ignored — update secrets directly in
                                 # Key Vault / Secret Manager instead.
          auth0:
            AUDIENCE: <string>   # Auth0 / OIDC audience
            CLIENT_ID_NATIVE: <string>  # mobile / native app client ID
            CLIENT_ID_SPA: <string>     # SPA client ID
            ISSUER: <string>            # OIDC issuer URL
          ers_public_key: <string>      # DER-encoded RSA public key, base64. See ERS key ceremony docs.
          chainalysis-token: <string>   # Chainalysis API token (leave empty to disable)
          chainalysis-user: <string>
          canton-client-id: <string>    # present only when `canton:` block is set
          canton-client-secret: <string>
          ubiquity_auth_token: <string> # Blockdaemon API key (omit when no_auth_token: true)
          ubiquity_org_username: <string>
          # Blockchain RPC URLs — one entry per blockchain in blockchains[]:
          <protocol>-<network>-native-driver-url: <string>  # HTTP RPC endpoint
          <protocol>-<network>-rpc-url: <string>            # WebSocket RPC endpoint

Field Reference

Top-level

FieldTypeRequiredDescription
environmentslistOne entry per logical environment.

environments[]

FieldTypeRequiredDescription
namestringShort label used in folder names (target/<name>/) and Terraform state names. Examples: qa, prod, staging.
namespaceslistOne entry per Kubernetes namespace deployed in this environment.

environments[].namespaces[]

FieldTypeRequiredDescription
namestringKubernetes namespace name and Azure resource identifier prefix. Use lowercase alphanumeric and hyphens.
subscriptionstringAzure ✅Friendly name of the Azure subscription (used for display and Terraform backend naming).
subscription_idstringAzure ✅Azure subscription GUID. GCP: use project. EKS: use account_id.
testnetbooltrue for test/staging networks, false for production. Affects policy node configuration and network selection.
featureslist[string]Feature flags to enable. "1.3" enables the Cold Wallet Platform (CWP). Defaults to ["1.3"] if omitted.
log_levelintLog verbosity: 0=debug, 1=info (default), 2=warn, 3=error.
no_auth_tokenboolSet true to deploy without a Blockdaemon API key. Disables Ubiquity, UTXO service, and staking. Required if you have no BD API key.
dns_prefixstringOverride the auto-generated URL prefix. Default prefix is the namespace name.

management_environment

Describes the cluster-level Azure resources shared by all namespaces on the same AKS cluster (DNS zone, management resource group, cert-manager email).

FieldTypeRequiredDescription
subscriptionstringAzure subscription owning the management resource group and DNS zone. May differ from the namespace subscription.
subscription_idstringGUID of the management subscription.
locationstringAzure region for cluster and DNS resources. Example: East US 2.
resource_groupstringManagement resource group name. Must already exist. Example: acme-core-rg.
hosted_zonestringParent DNS zone under which wallet records are created. Example: wallet.company.com.
admin_emailstringEmail used for Let's Encrypt / ACME TLS certificate registration.
key_vault_allowed_ipslist[string]CIDR list for Key Vault network access. Use ["0.0.0.0/0"] to allow all; tighten for production.

terraform_extra_vars

FieldTypeRequiredDescription
default_hoststringFQDN for the wallet API backend. Example: api.wallet.company.com.
frontend_hoststringFQDN for the wallet frontend. Example: app.wallet.company.com.

For single-namespace clusters these are typically api.<hosted_zone> and app.<hosted_zone>. For multi-namespace clusters use a namespace prefix: api-<namespace>.<hosted_zone>.

admins[]

List of users created as wallet Admins on first deployment. Requires the users to have active Auth0 / OIDC accounts in the configured identity provider.

FieldTypeRequiredDescription
namestringDisplay name.
emailstringEmail address matching the user's OIDC identity.
📘

Note:

Admins are bootstrapped once. Adding or removing entries after first deploy has no effect — manage users through the wallet UI or API.

canton (optional)

Enables Canton (Daml) ledger integration. Omit this block entirely if you are not using Canton.

FieldTypeDescription
ledger_api_urlstringgRPC Ledger API endpoint. Example: https://ledgerapi.participant.company.com:443.
admin_api_urlstringCanton Admin API endpoint (may be empty).
json_ledger_api_urlstringJSON Ledger API (HTTP) endpoint.
validator_api_urlstringValidator API endpoint.
networkstringNetwork identifier. Examples: mainnet, testnet, devnet.
token_urlstringOAuth 2.0 token endpoint for Canton authentication.
audiencestringOAuth audience for Canton token requests.

When canton: is present, the generated customer-secrets.yml scaffold includes canton-client-id and canton-client-secret entries.

blockchains[] (optional)

Each entry defines a blockchain network the wallet will track and accept transactions on. Omit to use the default chain configured by Blockdaemon.

FieldTypeDescription
family_namestringProtocol family: EVM, UTXO, Solana, Cosmos, etc.
family_properties.evm_properties.chain_idintEVM chain ID. 1=Ethereum mainnet, 137=Polygon, 42161=Arbitrum. Required for EVM family.
native_symbolstringNative currency ticker. Examples: ETH, BTC, SOL.
protocol_namestringProtocol slug used internally. Examples: ethereum, bitcoin, solana.
network_namestringNetwork slug. Examples: mainnet, goerli, lower-qa.
mainnet_coin_typeintSLIP-44 coin type. 60=ETH mainnet, 601=custom/testnet ETH.
decimalsintToken precision. 18 for ETH and most EVM tokens, 8 for BTC.
test_networkbooltrue for testnets and staging networks.
native_driver_urlsecret refRPC endpoint secret reference. The secret value is the HTTP RPC URL.

Secret references

Across all fields that accept a secret reference, the shape is:

name: <secret-name-in-store>   # the key as it appears in your secret store
type: azureSecret               # azureSecret | gcpSecret | awsSecret
type valueCloudSecret store
azureSecretAzureAzure Key Vault
gcpSecretGCPGCP Secret Manager
awsSecretAWS / EKSAWS Secrets Manager

custom_event_streaming[] (optional)

Deploys an EVM tracker sidecar for each entry. Required for EVM chains that need event indexing (e.g. ERC-20 transfers).

FieldTypeDescription
namestringUnique tracker name. Used as the sidecar container name.
rpc_urlsecret refWebSocket RPC URL secret reference.
env[]listOptional extra environment variables injected into the tracker container (e.g. RPC_HEADER_KEY / RPC_HEADER_VALUE for authenticated endpoints).
blockchainobjectSame shape as blockchains[] entry. Must match a configured blockchain.

customer_secrets (optional)

Values written verbatim into your secret store during first deployment only. After initial seeding, changes to this block are ignored — update secrets directly in Key Vault / Secret Manager.

KeyDescription
auth0.AUDIENCEOIDC audience, typically the wallet API URL.
auth0.CLIENT_ID_NATIVEClient ID for the mobile / approver app.
auth0.CLIENT_ID_SPAClient ID for the web frontend.
auth0.ISSUEROIDC issuer URL (e.g. https://your-tenant.auth0.com/).
ers_public_keyDER-encoded RSA-3072 public key, base64. Generated during the ERS key ceremony. See Emergency Recovery Secret generation.
chainalysis-tokenChainalysis API token. Leave empty "" to disable transaction screening.
chainalysis-userChainalysis username.
canton-client-idCanton OAuth client ID. Present only when canton: block is configured.
canton-client-secretCanton OAuth client secret.
ubiquity_auth_tokenBlockdaemon API key. Omit or leave empty when no_auth_token: true.
ubiquity_org_usernameBlockdaemon organisation username.
<protocol>-<network>-native-driver-urlHTTP RPC endpoint for each configured blockchain.
<protocol>-<network>-rpc-urlWebSocket RPC endpoint for each configured blockchain.

Complete Annotated Example (Azure)

The following is a minimal production-ready example for a single Azure deployment with one testnet and one mainnet namespace, Ethereum support, and Canton integration.

# customer-config.yml — Azure Institutional Vault deployment
# Edit this file. Re-run `make generate-customer-assets` after any change.
# Do NOT edit files under target/ — they are generated.

environments:
  # ── Production ────────────────────────────────────────────────────────────
  - name: prod
    namespaces:

      # Testnet namespace: used for UAT and pre-production validation
      - name: acme-testnet
        subscription: "acme-wallet-prod"
        subscription_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        testnet: true
        features:
          - "1.3"           # enables Cold Wallet Platform (CWP)
        log_level: 1        # 0=debug 1=info 2=warn 3=error

        management_environment:
          subscription: "acme-wallet-prod"
          subscription_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          location: "East US 2"
          resource_group: "acme-wallet-mgmt-rg"
          hosted_zone: "wallet.acme.com"
          admin_email: "[email protected]"
          key_vault_allowed_ips:
            - "203.0.113.0/24"   # your office/VPN egress range

        terraform_extra_vars:
          default_host: api-testnet.wallet.acme.com
          frontend_host: app-testnet.wallet.acme.com

        admins:
          - name: "Alice Smith"
            email: "[email protected]"
          - name: "Bob Jones"
            email: "[email protected]"

        # Canton integration — remove this block if not using Canton/Daml
        canton:
          ledger_api_url: "https://ledgerapi.canton.acme.com:443"
          admin_api_url: ""
          json_ledger_api_url: "https://jsonapi.canton.acme.com"
          validator_api_url: "https://validator.canton.acme.com:443/api/validator"
          network: testnet
          token_url: "https://auth.acme.com/realms/canton/protocol/openid-connect/token"
          audience: "https://validator.canton.acme.com/api"

        blockchains:
          - family_name: EVM
            family_properties:
              evm_properties:
                chain_id: 11155111      # Sepolia testnet
            native_symbol: ETH
            protocol_name: ethereum
            network_name: sepolia
            mainnet_coin_type: 60
            decimals: 18
            test_network: true
            native_driver_url:
              name: ethereum-sepolia-native-driver-url
              type: azureSecret

        custom_event_streaming:
          - name: evm-tracker
            rpc_url:
              name: ethereum-sepolia-rpc-url
              type: azureSecret
            blockchain:
              native_symbol: ETH
              protocol_name: ethereum
              network_name: sepolia
              mainnet_coin_type: 60
              decimals: 18
              chain_id: 11155111
              family_name: EVM
              native_driver_url:
                name: ethereum-sepolia-native-driver-url
                type: azureSecret

        customer_secrets:
          auth0:
            AUDIENCE: "https://api-testnet.wallet.acme.com"
            CLIENT_ID_NATIVE: "acme-wallet-approver-testnet"
            CLIENT_ID_SPA: "acme-wallet-app-testnet"
            ISSUER: "https://acme.auth0.com/"
          ers_public_key: "<base64-encoded DER public key from ERS key ceremony>"
          canton-client-id: acme-vault-client
          canton-client-secret: "<generated during Canton onboarding>"
          chainalysis-token: ""     # leave empty to disable Chainalysis screening
          chainalysis-user: ""
          ubiquity_auth_token: "<your Blockdaemon API key>"
          ubiquity_org_username: "<your Blockdaemon org username>"
          ethereum-sepolia-native-driver-url: "https://rpc-node.acme.com:8545"
          ethereum-sepolia-rpc-url: "wss://rpc-node.acme.com:8546"

      # Production namespace: mainnet assets
      - name: acme
        subscription: "acme-wallet-prod"
        subscription_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        testnet: false
        features:
          - "1.3"

        management_environment:
          subscription: "acme-wallet-prod"
          subscription_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          location: "East US 2"
          resource_group: "acme-wallet-mgmt-rg"
          hosted_zone: "wallet.acme.com"
          admin_email: "[email protected]"
          key_vault_allowed_ips:
            - "203.0.113.0/24"

        terraform_extra_vars:
          default_host: api.wallet.acme.com
          frontend_host: app.wallet.acme.com

        admins:
          - name: "Alice Smith"
            email: "[email protected]"
          - name: "Bob Jones"
            email: "[email protected]"

        canton:
          ledger_api_url: "https://ledgerapi.canton.acme.com:443"
          admin_api_url: ""
          json_ledger_api_url: "https://jsonapi.canton.acme.com"
          validator_api_url: "https://validator.canton.acme.com:443/api/validator"
          network: mainnet
          token_url: "https://auth.acme.com/realms/canton/protocol/openid-connect/token"
          audience: "https://validator.canton.acme.com/api"

        blockchains:
          - family_name: EVM
            family_properties:
              evm_properties:
                chain_id: 1           # Ethereum mainnet
            native_symbol: ETH
            protocol_name: ethereum
            network_name: mainnet
            mainnet_coin_type: 60
            decimals: 18
            test_network: false
            native_driver_url:
              name: ethereum-mainnet-native-driver-url
              type: azureSecret

        custom_event_streaming:
          - name: evm-tracker
            rpc_url:
              name: ethereum-mainnet-rpc-url
              type: azureSecret
            blockchain:
              native_symbol: ETH
              protocol_name: ethereum
              network_name: mainnet
              mainnet_coin_type: 60
              decimals: 18
              chain_id: 1
              family_name: EVM
              native_driver_url:
                name: ethereum-mainnet-native-driver-url
                type: azureSecret

        customer_secrets:
          auth0:
            AUDIENCE: "https://api.wallet.acme.com"
            CLIENT_ID_NATIVE: "acme-wallet-approver"
            CLIENT_ID_SPA: "acme-wallet-app"
            ISSUER: "https://acme.auth0.com/"
          ers_public_key: "<base64-encoded DER public key from ERS key ceremony>"
          canton-client-id: acme-vault-client
          canton-client-secret: "<generated during Canton onboarding>"
          chainalysis-token: "<your Chainalysis API token>"
          chainalysis-user: "<your Chainalysis username>"
          ubiquity_auth_token: "<your Blockdaemon API key>"
          ubiquity_org_username: "<your Blockdaemon org username>"
          ethereum-mainnet-native-driver-url: "https://rpc-node.acme.com:8545"
          ethereum-mainnet-rpc-url: "wss://rpc-node.acme.com:8546"

Cloud-Specific Differences

Azure

  • Secret type: azureSecret
  • Secrets stored in: Azure Key Vault (one vault per policy node)
  • Subscription fields: subscription (name) + subscription_id (GUID)
  • Cluster addon management: ingress-nginx, cert-manager, and external-dns are managed by the deployer on first install

GCP

  • Secret type: gcpSecret
  • Secrets stored in: GCP Secret Manager
  • Top-level config key: gcp_customer_configurations
  • Cloud-specific fields: project (GCP project ID), region (GCP region)
  • The GCP customer-config.yaml uses a different top-level schema — see the GCP Deployment Process guide for the GCP-specific reference

EKS (AWS)

  • Secret type: awsSecret
  • Secrets stored in: AWS Secrets Manager
  • Cloud-specific fields: account_id (AWS account ID), region
  • Policy nodes may use enclaveSecret for encryptor_master_password when running in AWS Nitro Enclaves
  • See the EKS Deployment Process guide for the EKS-specific reference

Common Operations

Upgrading the wallet version

Update the DEPLOYER_VERSION variable when running make generate-customer-assets:

DEPLOYER_VERSION=v3.7.0 make generate-customer-assets
make deploy-wallet-helm NAMESPACE=<ns> CUSTOMER_MPA_ENVIRONMENT=<env>

No changes to customer-config.yml are required for a version upgrade.

Adding a new blockchain

Add an entry to blockchains[] and a matching custom_event_streaming[] entry (if EVM). Re-run:

make generate-customer-assets
make deploy-wallet-helm NAMESPACE=<ns> CUSTOMER_MPA_ENVIRONMENT=<env>

Seed the new RPC URL secrets into Key Vault before deploying.

Adding a second namespace (multi-tenant cluster)

Add a new entry under namespaces: in the same environment block. Use the same management_environment values. Set FIRST_NAMESPACE to the first namespace deployed on this cluster so that shared cluster addons (ingress, cert-manager) are only installed once:

FIRST_NAMESPACE=<first-ns> make deploy-wallet-tf NAMESPACE=<new-ns> CUSTOMER_MPA_ENVIRONMENT=<env>

🗣️We Are Here to Help!

Please contact us via email or support chat if you encounter an issue, bug, or need assistance. Don't forget to include any relevant details about the problem. To request a wallet form and Institutional Vault Approver form, please click here or contact our sales team.


Did this page help you?