# Bring your own custody, per organization

Source: https://docs.settlemint.com/docs/changelog/dalp-3-1/org-custody
Each organization on a DALP deployment now configures its own custody provider, tests the credentials before adopting them, and rotates them from the Console, with secrets masked and never returned.



**In DALP 3.0 the deployment chose the custody provider. In 3.1 each organization chooses its own. A bank on a shared deployment brings its own vault, proves the credentials work before a single transaction depends on them, and rotates them from the Console without a support ticket.**

<Spotlight
  eyebrow="Custody & Settlement"
  title="One deployment, many vaults"
  aside="
  <FactList
    items={[
      { label: &#x22;Providers&#x22;, value: &#x22;Five, org-selectable&#x22; },
      { label: &#x22;Credentials&#x22;, value: &#x22;Tested before adoption&#x22; },
      { label: &#x22;Secrets&#x22;, value: &#x22;Masked, never returned&#x22; },
      { label: &#x22;Rotation&#x22;, value: &#x22;From the Console&#x22; },
    ]}
  />
"
>
  Custody configuration moves from the deployment to the organization. Each
  organization on a shared DALP deployment selects its own provider, supplies
  its own credentials, and pins its own provider settings. The platform verifies
  the credentials against the live provider before it adopts them.
</Spotlight>

DALP 3.0 established the signing separation: [your vault signs, the platform does everything else](/docs/changelog/dalp-3-0/custody). One constraint remained: the provider was configured once, for the whole deployment.

3.1 removes it. Custody becomes an organization-level setting with its own API surface, its own Console page, and its own credential lifecycle, so two banks on one deployment no longer share one custody decision. You choose your provider, you hold your credentials, and the decision sits where the risk sits: with the institution that owns the assets.

## Choose a provider per organization [#choose-a-provider-per-organization]

An organization owner selects from the same providers the platform already integrates: local signing, DFNS, Fireblocks, Luna HSM, and Ripple Custody. The signing model is unchanged from 3.0. Keys stay inside the provider's vault, and the provider's own approval policy runs before any signature returns.

<LabelCards>
  <LabelCard label="Workspace pins">
    Non-secret provider settings persist on the custody record: the provider
    workspace identity and, for Fireblocks, the vault scope the organization
    operates in.
  </LabelCard>

  <LabelCard label="Pinned API origin">
    An organization can pin the custodian API origin it talks to. The platform
    accepts HTTPS origins only, allowlisted by host suffix per provider, so a
    typo cannot route signing requests to an unknown host.
  </LabelCard>

  <LabelCard label="Network and asset defaults">
    DFNS deployments pin a default network and Fireblocks deployments a default
    asset, per organization. Ripple Custody records carry their domain, ledger,
    and key strategy.
  </LabelCard>
</LabelCards>

Only DFNS and Fireblocks flows carry full end-to-end verification in this release. The other providers are selectable with the same configuration surface; check the custody provider documentation for the current depth of each integration.

## Test before you trust [#test-before-you-trust]

Credential handling is where a shared deployment gets dangerous, so the workflow is explicit. You never adopt a credential the platform has not verified, and the platform never echoes a secret back.

<Steps>
  <Step title="Test the credentials">
    `POST /api/v2/custody/test-credentials` verifies the supplied credentials
    against the live provider before anything is stored. A failing credential is
    rejected here, not discovered later on a stalled transaction.
  </Step>

  <Step title="Adopt them">
    `PUT /api/v2/custody/credentials` stores the verified credentials for the
    organization. From this point, the organization's transactions route to its
    own vault.
  </Step>

  <Step title="Rotate on your own schedule">
    The same route replaces credentials in place. You rotate from the Console
    whenever your policy requires it, without a request to the platform team.
  </Step>
</Steps>

The Console carries the same lifecycle on a dedicated custody page under platform settings, showing which provider is active and which settings are pinned, every secret masked. `GET /api/v2/custody` returns the same view for integrations.

## Admins see state, not secrets [#admins-see-state-not-secrets]

A platform administrator supporting many organizations needs to know how each one is configured without ever holding its credentials. The admin surface is read and revoke only: `GET /api/v2/admin/custody/{organizationId}` returns the masked configuration for any organization, and `DELETE /api/v2/admin/custody/{organizationId}/credentials` revokes credentials when an organization offboards or a credential must be invalidated immediately.

No admin route returns a secret.

<Callout title="Testnet onboarding no longer breaks on defaults">
  The platform now carries explicit defaults for the DFNS network and the
  Fireblocks asset. Before this release, an unset value fell back to mainnet
  networks, which broke onboarding on test networks. An organization-managed
  custody configuration can override the Fireblocks asset per organization on
  top of the platform default.
</Callout>

Three supporting fixes shipped in the same window. Fireblocks vault account creation is idempotent by name, so a retried onboarding cannot create a duplicate vault account. Provider-native Fireblocks custody now runs end to end. And the key-migration path skips wallets held by a custody provider, because there is no platform-side key material to migrate for them.

## Compatibility [#compatibility]

No migration is required. The surface is additive: new v2 routes, a new Console page, and new database objects the upgrade creates on its own.

[How custody signing works →](/docs/changelog/dalp-3-0/custody) · [Security architecture →](/docs/changelog/dalp-3-0/security)
