Skip to content

Configure the SDK

Each Ripple Custody SDK reads its settings from a config.toml file, from RC_* environment variables, or from values you set in code. This page describes where each SDK looks, which keys and variables it recognizes, and how to configure TLS. For a minimal working setup, see Integrate via SDK.

Configuration sources and precedence

In all three SDKs, an RC_* environment variable overrides the matching key in config.toml, and a key in the file overrides the built-in default. This order lets you keep non-secret settings in a file and supply secrets and per-environment values through the environment.

TypeScriptJavaPython
Load from file and environmentloadConfiguration() or loadConfiguration(path)CustodyClientConfig.loadConfiguration() or loadConfiguration(Path)load_configuration() or load_configuration(config_file)
Load from environment onlyCall loadConfiguration() with no file presentCustodyClientConfig.fromEnvironment()Call load_configuration() with no file present
Configure in codegenerateNewConfiguration() and a Configuration objectApiClient.newBuilder() and CustodyClientConfig settersConfiguration(...)

Configuration file location

All three SDKs search for config.toml in the following order and use the first file that exists:

  1. The path you pass to loadConfiguration (load_configuration in Python).
  2. The path in RC_CONFIG_FILE.
  3. ./config.toml in the working directory.
  4. ~/.config/ripple-custody/config.toml.

If an SDK finds no file, it continues with environment variables only. It fails only when a required setting is missing from every source. In Java, a named file replaces the default locations: the SDK doesn't search them.

Configuration file format

All keys are top-level key = value pairs. The SDKs share one set of key names, so the same config.toml file works in each language. To get a key name, drop the RC_ prefix from the environment variable and lowercase the rest, for example RC_API_BASE_URL becomes api_base_url. The following keys keep the prefix: rc_user_id, rc_domain_id, rc_validate_addresses, rc_verify_derived_addresses, and rc_enforce_immutable_endpoints.

  • Unknown keys. All three SDKs reject a config.toml file with keys that they don't recognize. The error names the key and, for a renamed key, the name to use instead.
  • Secrets. Set RC_CLIENT_SECRET as an environment variable. It has no configuration file key, and the Java SDK rejects client_secret in the file.
  • TOML support. The Java SDK parses a subset of TOML: strings, booleans, and numbers. It doesn't accept arrays or multi-line strings. To put a PEM certificate in ca_cert_data, write it as one string with \n escapes.

Environment variable and key reference

The following tables list the RC_* environment variables by area, with the config.toml key for each. "Environment only" means the setting has no configuration file key.

Connection and authentication

Variableconfig.toml keyPurpose
RC_CONFIG_FILEEnvironment onlyPath to the configuration file.
RC_API_BASE_URLapi_base_urlBase URL of the Ripple Custody API. Required.
RC_OIDC_ISSUER_URLoidc_issuer_urlOpenID Connect (OIDC) issuer URL. The SDK discovers the token endpoint from the issuer's /.well-known/openid-configuration document.
RC_TOKEN_ENDPOINTtoken_endpointOAuth token endpoint URL. Takes precedence over discovery.
RC_CLIENT_IDclient_idOAuth client ID for the client-credentials grant.
RC_CLIENT_SECRETEnvironment onlyOAuth client secret for the client-credentials grant. TypeScript also accepts client_secret in the file and logs a warning.

Each SDK finds the token endpoint from RC_TOKEN_ENDPOINT or, through discovery, from RC_OIDC_ISSUER_URL. Set one of them.

Each SDK chooses the OAuth grant from the credentials you set. When RC_CLIENT_ID and RC_CLIENT_SECRET are both set and not empty, the SDK uses the client-credentials grant. Otherwise, it uses the signed-challenge grant, with the client ID customer_api. Setting a client secret without a client ID is an error. In TypeScript and Python, a client ID without a secret is also an error, so don't set client_id for the signed-challenge grant.

For details about both grants, see Authentication and signing.

Signing and identity

Variableconfig.toml keyPurpose
RC_PRIVATE_KEY_FILEprivate_key_filePath to a PEM private key (P-256, secp256k1, or Ed25519). The SDK uses it to sign the login challenge and intents.
RC_KMS_PROVIDERkms_providerSign with a key management service (KMS) instead of a key file: hashicorp, aws, or azure. The Java SDK has no built-in KMS signer. Use the Java examples instead, as described in KMS provider variables.
RC_USER_IDrc_user_idYour user ID. The SDK uses it as the author of intents.
RC_DOMAIN_IDrc_domain_idYour domain ID. The SDK uses it as the author's domain and the default target domain.

Set either a private key file or a KMS provider, not both. All three SDKs reject a configuration that sets both.

All three SDKs look up your user through the API when you don't set RC_USER_ID and RC_DOMAIN_ID. If you belong to several domains, set RC_DOMAIN_ID to choose one. Otherwise, the lookup fails.

Verification and safety checks

Variableconfig.toml keyPurpose
RC_NOTARY_API_PUBLIC_KEYnotary_api_public_keyNotary API public key, base64-encoded DER. Required while response verification is on.
RC_VERIFY_RESPONSESverify_responsesVerify the signature on API responses. Default true.
RC_VALIDATE_ADDRESSESrc_validate_addressesCheck destination address formats before submitting an intent. Default true.
RC_VERIFY_DERIVED_ADDRESSESrc_verify_derived_addressesRe-derive generated unspent transaction output (UTXO) account addresses from the account's extended public key and compare them with the server's. Default true.
RC_ENFORCE_IMMUTABLE_ENDPOINTSrc_enforce_immutable_endpointsDefault true: the SDK refuses an endpoint update that changes its address, ledger, or parameters. Set false to log a warning and submit the update instead.

For more information about the endpoint check, see SDK endpoint immutability check.

Each SDK pins one notary API public key. When the notary key rotates, replace the key and restart the client, as described in Notary key rotation and migration. For how verification works, see Response verification.

In TypeScript, the derived-address check runs only when you pass your own address-derivation function to the address methods. The Java SDK accepts the setting but doesn't perform the check yet.

TLS

Variableconfig.toml keyPurpose
RC_VERIFY_SSLverify_sslVerify the server's TLS certificate. Default true.
RC_TLS_MIN_VERSIONtls_min_versionMinimum TLS version: TLSv1_2 (default) or TLSv1_3.
RC_SSL_CA_CERTssl_ca_certPath to a PEM CA bundle to trust instead of the system trust store.
RC_CA_CERT_DATAca_cert_dataCA bundle content, as an alternative to a file.
RC_CERT_FILEcert_fileClient certificate (PEM) for mutual TLS.
RC_KEY_FILEkey_fileClient private key (PEM) for mutual TLS.
  • Certificate verification. Turn it off only for local development. All three SDKs log a warning when it's off.
  • Minimum version. TLS 1.2 is the minimum in all three SDKs.
  • Custom CA. In TypeScript and Python, set RC_SSL_CA_CERT or RC_CA_CERT_DATA, not both. The Java SDK accepts both together.
  • Mutual TLS. Set RC_CERT_FILE and RC_KEY_FILE together. All three SDKs reject a configuration that sets only one.
  • Custom HTTP client. If you supply your own HTTP client or transport, your client handles TLS, and these settings don't apply. For more information, see Errors and HTTP behavior.

Other settings

Variableconfig.toml keyPurpose
RC_USER_AGENT_SUFFIXuser_agent_suffixText appended to the SDK's User-Agent header, for example my-app/1.0.
RC_LOG_LEVEL_NPMEnvironment onlyTypeScript only. SDK log level: error, warn, info, http, verbose, debug, or silly.
RC_ALLOW_INSECURE_HTTPEnvironment onlyTypeScript only. Set to true or 1 to accept an http:// API URL when the host isn't public. For local development only.

Boolean values are true or false.

KMS provider variables

When you set RC_KMS_PROVIDER, the TypeScript and Python SDKs read the provider's settings from environment variables only. The variable names differ between the two SDKs.

ProviderTypeScriptPython
hashicorpVAULT_ADDR, VAULT_TOKEN, VAULT_TRANSIT_KEY_NAME, VAULT_NAMESPACEVAULT_ADDR, VAULT_TOKEN (or VAULT_ROLE_ID and VAULT_SECRET_ID), VAULT_TRANSIT_KEY_NAME, VAULT_TRANSIT_MOUNT_POINT, VAULT_NAMESPACE
awsRC_KMS_KEY_ID (or KMS_KEY_ID), AWS_REGIONAWS_KMS_KEY_ID, AWS_REGION, AWS_PROFILE
azureAZURE_VAULT_URL, AZURE_KEY_NAMEAZURE_KEY_VAULT_URL, AZURE_KEY_NAME, and optionally AZURE_USE_MANAGED_IDENTITY or the service principal variables AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET

The Java SDK recognizes RC_KMS_PROVIDER but has no built-in KMS signers, so it fails with an error that names the matching example. The Java examples show how to build each signer and read their own environment variables:

ProviderJava exampleVariables
hashicorpExample08HashiCorpVaultTransitVAULT_ADDR, VAULT_TOKEN, VAULT_TRANSIT_KEY_NAME
azureExample09AzureKeyVaultKeysAZURE_KEY_VAULT_URL, AZURE_KEY_NAME, and the tenant, client, and secret variables
awsExample10AwsKmsAWS_REGION, AWS_KMS_KEY_ID, and the standard AWS credentials

The examples aren't in the Java package. To get them, see Examples. For key requirements and setup, see Authentication and signing and HashiCorp Vault.

Configure in code

You can build the configuration in code instead of loading it, for example when your application reads settings from its own secret store. The following examples sign with a local private key and set the same values as the quickstart configuration:

import { readFileSync } from 'node:fs';
import {
  type Configuration,
  CustodyClient,
  generateNewConfiguration,
  makeSoftwareSigner,
} from '@ripple/ripple-custody-client-lib-typescript';

const apiBaseUrl = 'https://<api-host>';
const oidcIssuerUrl = 'https://<auth-host>/realms/<realm>';
const notaryApiPublicKey = '<notary-api-public-key>';
const signer = makeSoftwareSigner(readFileSync('/path/to/signing-key.pem', 'utf-8'));

const config: Configuration = {
  apiBaseUrl,
  oidcIssuerUrl,
  readPublicKey: signer.readPublicKey,
  signString: signer.signString,
  rcDomainId: '<your-domain-id>',
  rcValidateAddresses: true,
  rcVerifyDerivedAddresses: true,
  rcEnforceImmutableEndpoints: true,
  verifyResponses: true,
  notaryApiPublicKey,
  _sdkConfig: generateNewConfiguration({
    apiBaseUrl,
    oidcIssuerUrl,
    readPublicKey: signer.readPublicKey,
    signString: signer.signString,
    notaryApiPublicKey,
    // TLS options: verifySsl, tlsMinVersion, sslCaCert, caCertData, certFile, keyFile
  }),
};

const client = new CustodyClient(config);

generateNewConfiguration builds the HTTP and authentication layer. The outer object holds the settings that the client's methods use. Set verifyResponses and notaryApiPublicKey to the same values in both.