> For the complete documentation index, see [llms.txt](https://docs.bitsafe.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bitsafe.finance/decentralization-manager/get-started/create-a-decentralized-party.md).

# Create a Decentralized Party

[Overview](/decentralization-manager/overview.md) · [Connect peers](/decentralization-manager/get-started/connect-peers.md)

### Outcome

Coordinate two or more nodes to create a new Decentralized Party. Then store the party credentials on each node and verify the party on Canton.

{% hint style="info" %}
This page creates a new Decentralized Party. Other pages cover the other cases:

* For a party that is local to one participant, see [Decentralize an existing party](/decentralization-manager/operations-and-reference/decentralize-an-existing-party.md).
* For a party whose key a wallet holds, see [Decentralize an external party](/decentralization-manager/operations-and-reference/decentralize-an-external-party.md).
* To add a participant to a Decentralized Party that exists, see [Add a member to a Decentralized Party](/decentralization-manager/operations-and-reference/add-a-member.md).
  {% endhint %}

### Before you start

* All nodes of a Decentralized Party must run the same release. A coordinator invites only peers that use the same Noise wire version and report version `0.1.9` or later.
* Every node lists every other node as a peer. Each peer status reads "Connected via Noise protocol". See [Connect peers](/decentralization-manager/get-started/connect-peers.md).
* Each node reaches the Admin API and the Ledger API of its own Canton participant.
* The organizations agree on the party ID prefix, the participants, and the threshold.
* On each node, the operator holds the admin role when `DECPM_ADMIN_ROLE` is set. The coordinator needs it to start onboarding. Each invited peer needs it to accept.
* Each node on an AWS KMS participant has AWS credentials for Decentralization Manager. See [Sign with AWS KMS](/decentralization-manager/operations-and-reference/sign-with-aws-kms.md).

A Decentralized Party is a shared Canton identity. Treat its participants and threshold as a governed production decision, not as a demo default.

### 1. Plan the party

Record:

* The purpose of the party.
* The party ID prefix. The prefix starts with a letter. It holds only letters, digits, `-` and `_`. It has at most 180 characters.
* The participating organizations and nodes. A Decentralized Party needs at least two participants.
* The threshold.
* The target Canton network and synchronizer.
* The coordinator for this workflow run.
* The review that the organizations need before the party enters production.

The threshold is the number of namespace owners that must sign a topology change for the party. Decentralization Manager also sets it as the confirmation threshold of the party. The confirmation threshold is the number of hosting participants that must confirm each transaction. The default is a majority of the namespace owners, `ceil(owners / 2)`.

The governance threshold is a separate value. You set it later, in the `GovernanceRules` contract of the party.

### 2. Start onboarding

On the coordinator:

1. Open **Parties**, then the **Decentralized Parties** tab.
2. Click the **+** button (**Create Party**) at the bottom right. The **Create a decentralized party** dialog opens.
3. Enter the **Party ID prefix**.
4. Under **Peers to invite**, select the peers. The coordinator is always a namespace owner. The list therefore does not include the coordinator.
5. Check the **Threshold**. The dialog fills in the default. Change it only when the organizations agreed on another value.
6. Click **Start onboarding**.

Before it sends invitations, the coordinator checks three things:

* The prefix is valid, and no Decentralized Party on the coordinator uses it.
* Every invited peer uses the same Noise wire version and reports version `0.1.9` or later.
* Every pair of selected nodes lists each other as peers. See the full-mesh section of [Connect peers](/decentralization-manager/get-started/connect-peers.md#full-mesh).

When a check fails, the coordinator sends no invitations. The dialog shows the reason.

To start onboarding with the API, send an operator access token:

```bash
curl -sS -X POST http://localhost:8080/onboarding \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "party_id_prefix": "my-party",
    "peer_ids": ["participant2::1220...", "participant3::1220..."],
    "threshold": 2
  }'
```

Leave out `threshold` to use the default. The call returns HTTP 202. `GET /onboarding/status` returns the progress of the workflow run.

### 3. Peers accept the invitation

On each invited node:

1. Open **Approvals**. The invitation is under **Needs your action**. Its title is **Join party**, followed by the prefix.
2. Click **Review ▾**, and check the **Prefix**.
3. Confirm that the coordinator, the purpose, and the participant list match the agreed plan.
4. Click **Accept**. Click **Decline** when the invitation does not match the plan.

With the API, `GET /invitations` lists the pending invitations. `POST /invitations/accept` with `{"id": "<invitation-id>"}` accepts one. `POST /invitations/decline` declines one.

The workflow run starts when every invited peer accepts. The coordinator shows the workflow run as a card under **Approvals**, with one dot for each step.

### 4. Generate keys

Each node asks its own participant to generate two keys through the Canton Admin API:

* **Namespace key.** The participant signs topology transactions with it. This key does not leave the participant.
* **Daml signing key.** This key signs the ledger transactions of the party, for example the deployment of the governance contract.

The crypto provider of the participant decides where the participant stores the Daml signing key. It also decides how Decentralization Manager signs with the key:

| Crypto provider | Where the participant stores the Daml signing key | How Decentralization Manager signs                                                                                                                                             |
| --------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| JCE (default)   | The participant vault                             | The node exports the party's Daml private key from the vault with `VaultService.ExportKeyPair` for each signature. It signs on the node with Ed25519 and never stores the key. |
| AWS KMS         | AWS KMS. The key cannot leave AWS KMS.            | Decentralization Manager calls the AWS KMS `Sign` API with its own AWS credentials.                                                                                            |

{% hint style="warning" %}
On a JCE participant, the node exports the party's Daml private key from the vault for each signature and never stores it. The private key therefore leaves the participant vault each time Decentralization Manager signs. Protect the node and its Admin API access at the same level as the key. On an AWS KMS participant, grant `kms:Sign` on each party Daml key before you deploy contracts. See [Sign with AWS KMS](/decentralization-manager/operations-and-reference/sign-with-aws-kms.md).
{% endhint %}

See [Decentralized Party and Canton topology](/decentralization-manager/concepts-and-development/decentralized-party-and-canton-topology.md) for the difference between namespace keys, Daml signing keys, and Noise keys.

### 5. Sign and submit the topology

The workflow run does these steps without operator input:

| Step              | Actor       | What happens                                                                                                                 |
| ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `CreateProposals` | Coordinator | Builds the decentralized namespace (DNS) proposal and the PartyToParticipant proposal.                                       |
| `SignDns`         | Every node  | Signs the DNS proposal with its namespace key.                                                                               |
| `SubmitDns`       | Coordinator | Submits the DNS proposal to Canton and waits for the topology to propagate.                                                  |
| `SignP2p`         | Every node  | Signs the PartyToParticipant proposal with its namespace key.                                                                |
| `SubmitFinal`     | Coordinator | Checks that enough namespace owners signed. Then it submits the PartyToParticipant proposal and waits until it is effective. |
| `Complete`        | Every node  | Disconnects from the workflow run.                                                                                           |

{% hint style="info" %}
Do not remove the propagation waits, and do not skip a failed step by hand. One Canton component can accept a topology proposal before the next component can use it.
{% endhint %}

### 6. Store party credentials

The party now exists on Canton. Each node still needs credentials to act for the party on the Ledger API. Do this step on every node, the coordinator included. Without party credentials, governance calls fail with "No credentials configured for party".

1. Open **Parties** and click the new party.
2. In the **Authentication** section, click **Login**. The **Party Configuration** dialog opens.
3. Enter the identity provider fields. A Keycloak node asks for **URL**, **Realm**, **Client ID**, and **Client Secret**. An Auth0 node asks for **Domain**, **Audience**, **Client ID**, and **Client Secret**.
4. Click **Discover Member Party**. Decentralization Manager fills in the **Member Party ID** and the **User ID**. To type them yourself, click **Enter manually**.
5. Click **Save**.
6. Click **Test Auth**.
7. When the section shows "Missing required user rights.", click **Grant Rights**. Enter the client credentials of an identity that holds `ParticipantAdmin` on this participant, then click **Grant**.

**Grant Rights** gives the ledger user of the party `actAs` and `readAs` on the member party and on the Decentralized Party. Decentralization Manager does not store the admin credentials that you enter there.

These calls do the same steps with the API on a Keycloak node:

```bash
curl -sS -X PUT http://localhost:8080/party-config \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dec_party_id": "my-party::1220...",
    "member_party_id": "participant1::1220...",
    "user_id": "<ledger-user-id>",
    "keycloak_url": "https://keycloak.example.com",
    "keycloak_realm": "<realm>",
    "keycloak_client_id": "<client-id>",
    "keycloak_client_secret": "<client-secret>"
  }'

curl -sS -X POST http://localhost:8080/auth/grant-rights \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "dec_party_id": "my-party::1220...",
    "admin_client_id": "<admin-client-id>",
    "admin_client_secret": "<admin-client-secret>"
  }'
```

An Auth0 node sends `auth0_domain`, `auth0_audience`, `auth0_client_id`, and `auth0_client_secret` instead of the Keycloak fields. `GET /party-config/<dec_party_id>` returns the stored configuration without the secrets. See [Authentication and operator roles](/decentralization-manager/operations-and-reference/authentication-and-operator-roles.md) for the identity provider setup.

{% hint style="warning" %}
**Harden the first credential write.**

* A fresh node, with no stored party credentials, accepts the first `PUT /party-config` without a token. After that, the endpoint requires a token, and the admin role when `DECPM_ADMIN_ROLE` is set. Keep the HTTP port reachable only by your operators until the node stores its first party credentials.
* Set `DECPM_DB_ENCRYPTION_KEY`. Without it, the node stores the client secrets in `decpm.db` without encryption.
  {% endhint %}

### 7. Verify the party

On every node, open the party page and confirm:

* The party ID starts with the planned prefix. The part after `::` is the same on every node.
* **Owners** equals the number of participants.
* **Threshold** shows the agreed value.
* The **Participants** section lists every participant with the permission `confirmation`.
* **Test Auth** succeeds in the **Authentication** section.
* The onboarding card under **Approvals** shows the workflow run as complete, with no peer errors.

With the API, `GET /decentralized-parties` returns each party with its `owners`, `threshold`, and `participants`.

### If the coordinator becomes unavailable

The coordinator controls the workflow run. When the coordinator restarts, it resumes the workflow run from its stored state. On the coordinator, the card of an active workflow run shows **Cancel workflow**. The card of a failed workflow run shows **Retry** and **Dismiss**.

The API calls are `POST /workflows/<instance_name>/cancel`, `/retry`, and `/dismiss`. The `instance_name` of an onboarding workflow run is `<prefix>-creation`. Do not start a second workflow run for the same prefix until the first one ends.

### Membership changes after creation

Adding or removing a participant is a separate workflow. The party ID stays the same. The add-member workflow copies the contracts of the party to the new member. See [Add a member to a Decentralized Party](/decentralization-manager/operations-and-reference/add-a-member.md) and [Membership and governance changes](/decentralization-manager/operations-and-reference/membership-and-governance-changes.md). Do not run onboarding again to change membership.

### Troubleshooting

| Stage              | Check                                                             | Safe response                                                             |
| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Start              | The error in the dialog, the prefix, and the release on each node | Fix the named peer entries, or upgrade the nodes. Then start again.       |
| Invitations        | Whether every invited peer accepted under **Approvals**           | Ask the remaining operators to accept.                                    |
| Key generation     | Admin API access and the participant logs                         | Do not export or move private keys outside the workflow.                  |
| Topology signing   | The owner identity, the target store, and the signer rights       | Inspect the card of the workflow run before you start a new workflow run. |
| Propagation        | Synchronizer connectivity and topology state                      | Let the workflow run finish its waits.                                    |
| Party credentials  | **Test Auth** and the user rights                                 | Correct the identity provider fields, or click **Grant Rights**.          |
| Final verification | Owners, threshold, and participants on every node                 | Do not deploy governed contracts until all nodes agree.                   |

### Technical sources

* [Creating a Decentralized Party and party credentials](https://github.com/DLC-link/decentralization-manager/blob/main/README.md)
* [Onboarding architecture](https://github.com/DLC-link/decentralization-manager/blob/main/docs/ARCHITECTURE.md)
* [Signing with AWS KMS party keys](https://github.com/DLC-link/decentralization-manager/blob/main/docs/KMS_SIGNING.md)
* [Signing backends](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/signing/mod.rs)
* [Vault export signer](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/signing/vault_export.rs)
* [Onboarding workflow steps](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/workflow/onboarding/mod.rs)
* [Onboarding API and preflight checks](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/server/handlers/workflows.rs)
* [Minimum peer version](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/consts.rs)
* [Authentication middleware](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/src/server/middleware/auth.rs)
* [Create Party dialog](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/frontend/src/components/OnboardingDialog.tsx)
* [Party Configuration dialog](https://github.com/DLC-link/decentralization-manager/blob/main/crates/decman/frontend/src/components/PartyConfigDialog.tsx)

### Related pages

* [Decentralized Party and Canton topology](/decentralization-manager/concepts-and-development/decentralized-party-and-canton-topology.md)
* [Complete your first governance action](/decentralization-manager/get-started/complete-your-first-governance-action.md)
* [Membership and governance changes](/decentralization-manager/operations-and-reference/membership-and-governance-changes.md)
* [Sign with AWS KMS](/decentralization-manager/operations-and-reference/sign-with-aws-kms.md)

### Next step

👉 **Validate governance:** [Complete your first governance action](/decentralization-manager/get-started/complete-your-first-governance-action.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.bitsafe.finance/decentralization-manager/get-started/create-a-decentralized-party.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
