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.
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.
| TypeScript | Java | Python | |
|---|---|---|---|
| Load from file and environment | loadConfiguration() or loadConfiguration(path) | CustodyClientConfig.loadConfiguration() or loadConfiguration(Path) | load_configuration() or load_configuration(config_file) |
| Load from environment only | Call loadConfiguration() with no file present | CustodyClientConfig.fromEnvironment() | Call load_configuration() with no file present |
| Configure in code | generateNewConfiguration() and a Configuration object | ApiClient.newBuilder() and CustodyClientConfig setters | Configuration(...) |
All three SDKs search for config.toml in the following order and use the first file that exists:
- The path you pass to
loadConfiguration(load_configurationin Python). - The path in
RC_CONFIG_FILE. ./config.tomlin the working directory.~/.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.
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.tomlfile 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_SECRETas an environment variable. It has no configuration file key, and the Java SDK rejectsclient_secretin 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\nescapes.
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.
| Variable | config.toml key | Purpose |
|---|---|---|
RC_CONFIG_FILE | Environment only | Path to the configuration file. |
RC_API_BASE_URL | api_base_url | Base URL of the Ripple Custody API. Required. |
RC_OIDC_ISSUER_URL | oidc_issuer_url | OpenID Connect (OIDC) issuer URL. The SDK discovers the token endpoint from the issuer's /.well-known/openid-configuration document. |
RC_TOKEN_ENDPOINT | token_endpoint | OAuth token endpoint URL. Takes precedence over discovery. |
RC_CLIENT_ID | client_id | OAuth client ID for the client-credentials grant. |
RC_CLIENT_SECRET | Environment only | OAuth 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.
| Variable | config.toml key | Purpose |
|---|---|---|
RC_PRIVATE_KEY_FILE | private_key_file | Path to a PEM private key (P-256, secp256k1, or Ed25519). The SDK uses it to sign the login challenge and intents. |
RC_KMS_PROVIDER | kms_provider | Sign 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_ID | rc_user_id | Your user ID. The SDK uses it as the author of intents. |
RC_DOMAIN_ID | rc_domain_id | Your 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.
| Variable | config.toml key | Purpose |
|---|---|---|
RC_NOTARY_API_PUBLIC_KEY | notary_api_public_key | Notary API public key, base64-encoded DER. Required while response verification is on. |
RC_VERIFY_RESPONSES | verify_responses | Verify the signature on API responses. Default true. |
RC_VALIDATE_ADDRESSES | rc_validate_addresses | Check destination address formats before submitting an intent. Default true. |
RC_VERIFY_DERIVED_ADDRESSES | rc_verify_derived_addresses | Re-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_ENDPOINTS | rc_enforce_immutable_endpoints | Default 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.
| Variable | config.toml key | Purpose |
|---|---|---|
RC_VERIFY_SSL | verify_ssl | Verify the server's TLS certificate. Default true. |
RC_TLS_MIN_VERSION | tls_min_version | Minimum TLS version: TLSv1_2 (default) or TLSv1_3. |
RC_SSL_CA_CERT | ssl_ca_cert | Path to a PEM CA bundle to trust instead of the system trust store. |
RC_CA_CERT_DATA | ca_cert_data | CA bundle content, as an alternative to a file. |
RC_CERT_FILE | cert_file | Client certificate (PEM) for mutual TLS. |
RC_KEY_FILE | key_file | Client 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_CERTorRC_CA_CERT_DATA, not both. The Java SDK accepts both together. - Mutual TLS. Set
RC_CERT_FILEandRC_KEY_FILEtogether. 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.
| Variable | config.toml key | Purpose |
|---|---|---|
RC_USER_AGENT_SUFFIX | user_agent_suffix | Text appended to the SDK's User-Agent header, for example my-app/1.0. |
RC_LOG_LEVEL_NPM | Environment only | TypeScript only. SDK log level: error, warn, info, http, verbose, debug, or silly. |
RC_ALLOW_INSECURE_HTTP | Environment only | TypeScript 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.
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.
| Provider | TypeScript | Python |
|---|---|---|
hashicorp | VAULT_ADDR, VAULT_TOKEN, VAULT_TRANSIT_KEY_NAME, VAULT_NAMESPACE | VAULT_ADDR, VAULT_TOKEN (or VAULT_ROLE_ID and VAULT_SECRET_ID), VAULT_TRANSIT_KEY_NAME, VAULT_TRANSIT_MOUNT_POINT, VAULT_NAMESPACE |
aws | RC_KMS_KEY_ID (or KMS_KEY_ID), AWS_REGION | AWS_KMS_KEY_ID, AWS_REGION, AWS_PROFILE |
azure | AZURE_VAULT_URL, AZURE_KEY_NAME | AZURE_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:
| Provider | Java example | Variables |
|---|---|---|
hashicorp | Example08HashiCorpVaultTransit | VAULT_ADDR, VAULT_TOKEN, VAULT_TRANSIT_KEY_NAME |
azure | Example09AzureKeyVaultKeys | AZURE_KEY_VAULT_URL, AZURE_KEY_NAME, and the tenant, client, and secret variables |
aws | Example10AwsKms | AWS_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.
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.