# Utila setup

Source: https://docs.settlemint.com/docs/deployment/utila-setup
What the platform operator and the Utila vault admin prepare before an organisation adds Utila in the Console, how each field maps to Utila, and the limits.

Before an organisation can add Utila in the Console, the platform operator switches Utila on, and the Utila vault admin creates a service account that accepts calls only from DALP's addresses. Without the switch, Utila is not in the Console provider list. Without the service account and its allowed addresses, the first probe fails. Read [Limits](#limits) first to decide whether Utila fits.

Utila is a custody provider that holds keys in a vault and signs when its own policy allows it. In DALP, the platform files each transaction request in your Utila vault. Utila's approvers vote under your Utila policy, and the signing agent, which holds the service account's key share, signs the request designated to it. DALP tracks the request while it waits for a signature. DALP never asks Utila to sign a raw digest, the bare hash of a transaction, which Utila does not sign.

The Utila signing agent is the process that signs the requests DALP filed. Utila's own name for it is the Co-Signer, and its guide is [Utila Co-Signer](https://docs.utila.io/reference/utila-cosigner.md).

[Figure] DALP files each request in the Utila vault, Utila signs it after its approvers decide, and DALP tracks it while it waits for a signature. Two panels show who does what. In the DALP panel, DALP files the request and records it before it submits, and later tracks the request while it waits for a signature, by asking Utila for its status. In the Utila panel, the request is held for the service account, the Utila approvers vote under your policy, the customer-run Utila signing agent decides, and Utila signs it. An accent arrow runs from DALP filing the request to Utila holding it, and a quiet arrow runs from Utila signing back to DALP tracking. DALP never asks Utila to sign a raw digest. Labels: Who does what when DALP uses Utila; DALP; Files the request; Records it first, then submits; Tracks it while it waits; Asks Utila for the signature; Utila; Holds the request; Designated to the service account; Approvers decide; Then the customer-run signing agent; Utila signs; Never a raw digest.

## Before you start [#before-you-start]

- A Utila vault admin, who creates the service account.
- The platform operator, who switches Utila on and supplies the addresses DALP calls Utila from.
- An organisation Owner or a platform administrator who adds the configuration in the Console.
- The vault ID, ready before the Console step.
- The Utila network name for every network the organisation will use.

## What the Utila vault admin prepares [#what-the-utila-vault-admin-prepares]

A Utila service account is a non-human user that DALP signs in as. The vault admin creates it, and Utila describes the screens in [Creating a Service Account](https://docs.utila.io/reference/set-up-a-service-account.md).

**Step 1 of 4**

### Create the service account [#create-the-service-account]

As an admin of the vault, open Vault Settings, then Service Accounts, and add a service account. Enter a name and an email. DALP asks for the email in the "Service account email" field, so note it.

**Step 2 of 4**

### Add a public key [#add-a-public-key]

Utila controls the service account with RSA key pairs and asks you to paste the public half. You must add at least one key when you create the account, and an account holds up to three active keys. Keep the private half. You enter it in DALP as the "Service account private key (PEM)", and DALP stores it with the configuration's credentials.

A second key lets you rotate without a gap. If you add one, give its private half to DALP as the "Standby private key (PEM)". When Utila rejects the main key as no longer active, DALP authenticates with the standby key instead. The key signs the API token DALP presents to Utila, not the transactions.

**Step 3 of 4**

### Restrict the service account to DALP's addresses [#restrict-the-service-account-to-dalps-addresses]

Utila requires you to choose how the account may be accessed. It recommends trusted IPs only. Each entry is a single IPv4 or IPv6 address, and Utila does not support CIDR ranges, so the vault admin lists every address DALP calls Utila from, one by one. The platform operator provides that list, because only the operator knows which egress addresses the deployment uses. Take them from the outbound addresses of the network the DALP cluster runs in. DALP calls Utila at `https://api.utila.io` unless the organisation sets its own "API base URL", and uses port 443. A request from an address that is not listed is rejected, so a missing address shows up as a failed probe. Changing the list later needs an admin approval in Utila.

**Step 4 of 4**

### Choose the role [#choose-the-role]

Utila asks for a role in the last step, or lets you skip it. Utila's page does not list the roles, so take the role from your Utila policy: the account must be able to file and sign transactions in the vault. Assigning the role can need approval from further vault admins, so allow for that wait before you probe.

## What the platform operator switches on [#what-the-platform-operator-switches-on]

Utila is off in every deployment until the operator switches it on. Set `global.dalpApp.config.custody.providers.utila.enabled: true` in your Helm values, or `CUSTODY_PROVIDER_UTILA_ENABLED=true` outside the chart, as [Prerequisites](https://docs.settlemint.com/docs/deployment/prerequisites) describes. Until you do, "Utila custody" is not in the Console provider list, and the platform refuses a new Utila configuration. The same switch leaves existing configurations signing if you switch it off later, so switching off closes intake and does not stop signing. Quarantine a configuration to stop it.

Give the vault admin the list of addresses DALP calls Utila from.

## How each Console field maps to Utila [#how-each-console-field-maps-to-utila]

The organisation Owner fills these fields when adding the configuration, as [Organisation custody](https://docs.settlemint.com/docs/console/organisation-settings/custody) describes. Every value comes from the vault admin's steps in Utila.

| Console field | Where the value comes from |
| --- | --- |
| "Vault ID" | The ID of the Utila vault that holds the wallets. |
| "API base URL" | Optional. Leave it empty unless Utila gave you a different API address. It must be https on a `utila.io` host, on port 443, with no path. The platform refuses any other value when it probes. |
| "Networks" | One line per network: the chain ID, a space, then the Utila network name, for example `11155111 networks/ethereum-testnet-sepolia`. Utila's [Supported Blockchains](https://docs.utila.io/reference/supported-blockchains.md) page lists no network names. It points to the ListNetworks call and a support article, so take the names from there. |
| "Service account email" | The email you entered when you created the service account. |
| "Service account private key (PEM)" | The private half of the RSA key whose public half you gave Utila. |
| "Standby private key (PEM)" | Optional. The private half of a second key on the same service account. |
| "Signing agent secret" | Optional. At least 32 characters, using only letters, digits, `.`, `_`, `~` and `-`, because the signing agent sends it inside a URL. `openssl rand -hex 32` gives a valid value. The Console refuses a shorter one. |

A chain ID can have only one Utila network. The form refuses two lines with the same chain ID. A chain with no line in "Networks" cannot sign, as [The signing lanes](#the-signing-lanes) explains.

## Add the configuration [#add-the-configuration]

### Add and probe [#add-and-probe]

In the Console, open "Organisation settings", then "Custody". Select "Utila custody" in "Add custody provider", fill in the fields in [How each Console field maps to Utila](#how-each-console-field-maps-to-utila), and select "Add and probe provider". The platform probes Utila before the configuration accepts new accounts.

### Rotate when a key changes [#rotate-when-a-key-changes]

Open the configuration, change the fields that changed, and select **Probe and rotate credentials**. The platform probes the replacement before it saves it, so a failed probe leaves the stored credentials in place. Credential fields you leave empty keep their stored values. The other fields open with the stored values and are saved as the form holds them. After a rotation DALP keeps the current and the previous credential stored, and a later rotation removes older ones after a one-hour grace period.

### Stop signing through a configuration [#stop-signing-through-a-configuration]

Use "Quarantine execution", which [Organisation custody](https://docs.settlemint.com/docs/console/organisation-settings/custody) describes. Quarantine stops new execution through the configuration, and "Recover execution" reverses it. It does not cancel a request already filed in Utila. In webhook mode the signing agent gets no decision from DALP for a quarantined configuration, so that request stays pending in Utila until it expires or you cancel it there.

## The signing agent [#the-signing-agent]

The Utila signing agent is a component of the Utila CLI. [Utila Co-Signer](https://docs.utila.io/reference/utila-cosigner.md) states how the agent works:

- It polls a vault and acts only on transactions that wait for a signature and are designated to its service account.
- Transfers created in the Utila console are not sent to it. Only transactions created through the API reach it, which is how DALP files them.
- It runs in one of two modes. In sign-all mode, it signs every transaction designated to the service account. In webhook mode, it forwards each transaction to a URL and signs or cancels as the reply says. Utila suggests sign-all mode for a first test.
- In webhook mode, if the endpoint is unreachable, times out or answers with anything other than 200, the agent neither signs nor cancels. The transaction stays pending.

The "Signing agent secret" field is optional, and you need it only when a signing agent asks DALP for a decision. When you set it, DALP stores it with the configuration's credentials. A signing agent that asks DALP for a decision must present that secret. DALP gives no decision to a wrong secret, to an unknown or quarantined configuration, or to a configuration of another organisation. DALP also answers only for a request it filed itself, and tells the agent not to sign when a field of the held request differs from what DALP filed. A request DALP never filed stays pending in Utila.

The signing agent does not judge the request. In webhook mode it asks DALP, and DALP says yes to every request it filed whose fields still match. That protects against a request changed after DALP filed it. It does not protect against DALP filing a request you would refuse, so put a Utila approval policy on the vault for any request that needs a person.

To run the agent and point it at DALP, see [Utila signing agent](https://docs.settlemint.com/docs/deployment/utila-signing-agent).

## The signing lanes [#the-signing-lanes]

A signing lane is how a provider signs one kind of request on one chain. Utila declares the same lanes on every network that has a line in "Networks".

| What is signed | Lane on a chain with a bound Utila network |
| --- | --- |
| A wallet's own transactions | Utila sends the transaction from the vault. |
| A smart-account operation | Utila files the operation. |
| A typed payload | Utila signs it as typed data. |
| A request that is still pending | DALP reads its status from Utila, and can withdraw it. |
| A raw digest | Not signed. Utila signs none. |
| Any request on a chain with no network | A missing lane. The refusal names the fix: bind the chain to a Utila network, then probe the configuration again. |

For a typed payload or a smart-account operation, DALP asks Utila for the signature once a second for up to 300 seconds, then reports that signing failed and that the request may still be pending in Utila. When the request may wait for an approver, DALP checks for 15 seconds, then holds it as waiting for approval. A wallet transaction is filed and returns at once. A request that Utila declines, blocks by policy or cancels reads as rejected, and one that expires reads as expired.

## Limits [#limits]

- A chain with no network in "Networks" is refused, at creation and at "Add network". The message names the fix.
- "Networks" needs at least one line, and the networks you list are the only ones Utila can serve. To add a chain to an existing configuration, rotate the credentials with the new line in "Networks", then use **Add network**.
- The service account's allowed addresses are single addresses. A deployment with a changing egress address needs the list updated, with an admin approval in Utila, each time it changes.
- DALP holds a Utila request that waits for an approver as waiting for approval. When Utila reports the decision, by signed webhook (`POST /api/webhooks/utila`) or on DALP's own re-read, DALP resumes the request. A request still undecided at DALP's approval deadline ends as expired.
- Switching Utila off closes new intake and leaves stored configurations signing. A quarantined configuration does not execute. A rotation saves the new credentials only after they pass the probe, so a failed rotation leaves the stored ones in use.

## Troubleshooting [#troubleshooting]

**The probe fails**

Read the reported error first. An authentication failure points to the service account email or the private key:
confirm that the key is still active on the service account in Utila. A message that the vault, wallet or transaction
is not found points to the vault ID, or to a service account whose role does not cover the vault. Then confirm that
every address DALP calls Utila from is on the service account's list, because Utila rejects any other address. Correct
the value and probe again. If the reported error does not explain the failure, send the error text to your DALP
support contact. Questions about the vault, the service account or its allowed addresses go to Utila support.

**The refusal says no Utila network is bound to a chain**

The chain has no line in "Networks". Rotate the credentials with a `chain ID network name` line for it, then add the
chain with "Add network". The refusal asks you to probe again after you bind the chain.

**A request stays pending in Utila**

Utila holds a request until its approvers vote and its designated signer signs. If you use the signing agent in
webhook mode, a webhook that is unreachable, times out or answers other than 200 leaves the request pending. A request
created in the Utila console is never sent to the signing agent.

**The Console refuses the signing agent secret**

The secret is shorter than 32 characters. Enter a longer value, or leave the field empty. Use only letters, digits,
`.`, `_`, `~` and `-`, because the signing agent sends the secret inside a URL.

## You should see [#you-should-see]

- The configuration in the "Custody" list, with its health, its networks and the accounts it accepts.
- Health that reads "Healthy", which shows that the probe succeeded and that Utila accepted the service account's key from a listed address.

## Utila sources [#utila-sources]

- [Creating a Service Account](https://docs.utila.io/reference/set-up-a-service-account.md)
- [Utila Co-Signer](https://docs.utila.io/reference/utila-cosigner.md)
- [Supported Blockchains](https://docs.utila.io/reference/supported-blockchains.md)
