Skip to main content

Prerequisites

The external endpoints, credentials, and cluster capacity a DALP installation needs ready before you run the Helm charts.

A DALP Instance needs a Kubernetes cluster, network endpoints, datastores, registry access, and generated secrets. No chart deploys the datastores: you supply PostgreSQL, Redis, and object storage, and you verify availability, security, and recovery for each dependency. Complete this checklist before installing the charts or changing networks, custody, or hosting.

What the DALP chart runs in your cluster, and what you supply from outside.Two columns. Inside your cluster, the DALP chart runs the Console, the Platform API with its api, runner, indexer, and scheduler roles, and an optional block explorer that ships off by default, plus the docs site, PgBouncer connection pooling, and a PostgreSQL metrics exporter, all on by default. You supply everything else. That is the datastores, namely PostgreSQL, Redis, and object storage, and an ingress controller or Gateway API implementation that serves the class or Gateway the chart names. You also supply an RPC or ledger endpoint per enabled network, an SMTP relay, four generated values for encryption, session signing, governance ballots and custody credential identities, and registry pull access. Two conditional items sit below them: custody provider credentials for managed signing, and an optional SSO provider that replaces local sign-in. A closing rule states that no chart deploys a datastore or an ingress controller: PostgreSQL, Redis, object storage, and routing are services you run and point the charts at.What the DALP chart runs in your cluster, and what you supply from outside.The same figure as the desktop variant, drawn portrait for phone widths. Inside your cluster, the DALP chart runs the Console, the Platform API with its api, runner, indexer, and scheduler roles, and an optional block explorer, plus the docs site, PgBouncer connection pooling, and a PostgreSQL metrics exporter, all on by default. You supply PostgreSQL, Redis, and object storage, an ingress controller or Gateway API implementation, an RPC or ledger endpoint per network, an SMTP relay, two generated secrets, registry pull access, and, conditionally, custody provider credentials and an SSO provider. No chart deploys a datastore or an ingress controller.

The dalp chart runs the platform and nothing it depends on, so datastores, ingress, network endpoints, SMTP, secrets and registry access stay yours.

Decide first: where the datastores run

One fact shapes the rest of this checklist: no chart deploys PostgreSQL, Redis, object storage, or an ingress controller, so each is yours in every environment. The dalp chart's default values name placeholder in-cluster endpoints for the three datastores and placeholder passwords for PostgreSQL and Redis. Nothing resolves those names until you run services under them, so set every one before the first install.

For production, point each datastore at a service that provides replication, patching, and backups, whether a managed offering or one you operate. Confirm the selected service plan and settings, then include its endpoint and credentials in this checklist. Values and secrets shows how the connections are configured, and Topologies covers the deployment shapes.

Each item is marked always yours, conditional or optional.

What you must supply

An RPC endpoint for every network you enable

Always yours. Every network in the networks configuration needs connection details, and the instance refuses to start an EVM entry that has neither a single RPC URL nor a list of upstreams. With more than one upstream, the platform scores upstream health and shifts traffic away from a lagging endpoint.

  • The RPC URL, or the list of upstreams, for each EVM network you plan to enable.
  • An API-key or basic-auth credential for any upstream that requires one.
  • Which network is your default. Exactly one enabled EVM network carries the default flag.

A custody provider, when signing leaves the platform

Conditional. The signer.provider setting decides who holds signing keys. The default, local, is the platform's own key store: keys live encrypted inside the platform, protected by the encryption master password below, and nothing external is needed. The keys and their encryption password sit in the same deployment, so a compromised deployment can sign a transaction and nothing external approves it.

A custody provider adds a separately governed signing path with its own controls. Choosing dfns, fireblocks, luna, ripple or utila moves signing to that provider, and the chart then requires that provider's configuration block, filled with its credentials:

  • DFNS: an auth token, or a credential ID and private key. An organisation ID when your DFNS account is scoped to one.
  • Fireblocks: an API key and private key. A webhook URL when Fireblocks should call back into the platform.
  • Luna HSM: the PKCS11 library path, a token label, and a PIN reference. Client certificate and key references when your HSM requires mutual TLS.
  • Ripple Custody: the user ID, client ID, and private key the integration signs with, plus the vault ID and key strategy for the wallets it manages.
  • Utila: the service account email and its RSA private key, plus a standby key when you rotate keys. Set up Utila custody covers the vault and network names each organisation enters in the Console.

Ripple and Utila are the two providers this platform ships switched off. Set global.dalpApp.config.custody.providers.ripple.enabled: true or global.dalpApp.config.custody.providers.utila.enabled: true in your Helm values, or CUSTODY_PROVIDER_RIPPLE_ENABLED=true or CUSTODY_PROVIDER_UTILA_ENABLED=true outside the chart.

Each custody provider has its own switch, global.dalpApp.config.custody.providers.<kind>.enabled. A provider that is off leaves the Console catalogue and the published capability templates, and the platform refuses a new provider configuration that names it. Configurations stored while that provider was on keep signing, and their credentials can still be rotated, because the switch closes intake and does not revoke live accounts. To stop one existing account from signing, quarantine its provider configuration.

Have ready whichever combination your provider's own authentication flow needs. The provider, not the platform, decides which is sufficient. For inbound custody webhooks, DFNS and Ripple each need a webhook secret you supply. Fireblocks webhook verification works against Fireblocks' published key endpoint out of the box. Override it only when your Fireblocks environment publishes keys elsewhere on an https endpoint under fireblocks.io, the only host the platform accepts.

An SMTP relay, because every instance sends email

Always yours. Invitations and notifications go out over SMTP, and the platform has no relay of its own. Nothing checks the relay at boot, so a missing or wrong relay surfaces as the first invitation that never arrives. Confirm delivery before your first user is waiting on one.

  • An SMTP host and port.
  • A username and password for that relay. For a relay that accepts mail from your cluster without authentication, leave both empty. If you set only one of them, the platform sends no email.
  • The sender address the platform sends as, which is required, and optionally a sender name, which defaults to DALP. With no sender address, the platform sends no email.

Every message carries a Message-ID built from the event it announces and the domain of the sender address, in the form <hash@your-sender-domain>. The platform records each message in a send-once ledger in PostgreSQL before it hands the message to the relay, and marks it sent afterwards. A message the ledger shows as sent is never sent again. If the platform stops or the relay times out before it can mark a message, it sends that message again with the same Message-ID. A relay or mailbox that drops repeated Message-ID values then never shows a second copy, and an operator who reads relay logs sees the repeat under one id.

A PostgreSQL database

Always yours. The Platform API stores its state in PostgreSQL and does not start without a reachable database. Provision an instance reachable from your cluster and sized for your load, then set its connection in global.datastores.

  • A PostgreSQL instance, reachable from the cluster.
  • Its connection details: a URL, or hostname, database name, and credentials.
  • A pass over the connection budget when you change replica ceilings. See Values and secrets.

Redis

Always yours. The dalp chart enables the Redis-backed cache by default. The cache is required because the Console and several Platform API roles run more than one pod out of the box, and the cache's in-memory fallback lives per pod. Without a shared Redis, which pod answers a request would decide what a reader sees. Keep the cache on, and point it at your own endpoint.

  • A Redis-compatible endpoint with host, port, and credentials, plus TLS settings when it requires them. DALP's own development and test stacks run Valkey, the BSD-3-Clause fork of Redis, so a managed Valkey service meets this item as well as a managed Redis one.

An object storage bucket

Always yours. Every operation that stores or retrieves a file needs a bucket. The default profile selects the S3-compatible provider against a placeholder endpoint. Set the provider, bucket, and endpoint under global.dalpApp.config.objectStorage. Pick one provider and have its access ready:

  • AWS S3: the bucket's region, plus an access key pair unless you rely on IAM Roles for Service Accounts, the usual workload-identity alternative to a static key.
  • Google Cloud Storage: the project ID and a service account key, or inline credentials, unless you rely on Workload Identity, the usual alternative to a static service account key.
  • Azure Blob Storage: the storage account name plus an account key, a connection string, a SAS token, or Azure AD Workload Identity as the alternative to a static key.
  • Another S3-compatible service: its endpoint, region, access key, and secret key.

A filesystem provider exists for development only. Its default signing key is marked unsuitable for production.

An encryption master password you generate

Always yours. The platform encrypts sensitive data at rest with a master password you generate: at least 16 characters and at least 128 bits of estimated entropy, which in practice means a random string of 40 characters or more. The chart ships the value empty, so leaving it unset prevents the affected application pods from starting at boot. Never re-mint it for an existing environment: data encrypted under the old password becomes unreadable. See Values and secrets for the two-step rotation.

  • A generated master password of at least 16 characters and 128 bits of estimated entropy, such as a random 40-character string, stored with the rest of your secrets.

An auth secret you generate

Always yours. auth.secret signs and verifies sessions and must be at least 32 characters, with or without SSO. Unlike the master password, the chart does not ship it empty: the values file commits a placeholder that passes the length check. Every pod the chart deploys runs as a production process, whatever global.deploymentEnvironment says, and refuses to start on that placeholder.

  • A generated secret of at least 32 characters for auth.secret, replacing the chart's committed placeholder.
  • Replace the placeholder before the first install, because the pods refuse to start on it.

Two deployment identity values you set

Always yours. Keep both unique per deployment and never copy them between installs.

  • global.dalpApp.env.DALP_GOVERNANCE_DOMAIN_SCOPE names the domain this deployment signs governance ballots under. The chart refuses to render while it is empty or local.
  • CUSTODY_CREDENTIAL_IDENTITY_KEY, at least 32 characters, keys the hashes of custodian credential identities. The platform refuses to start on the chart's local default. Custody credential identity key covers it.

Pull access to every image registry the charts reference

Always yours. The charts pull the DALP images from ghcr.io and the third-party images from docker.io, quay.io and registry.k8s.io, and the chart itself comes from pkg.distribution.settlemint.com. Allow those hosts, or mirror the images. Either hand the chart registry credentials so it renders the pull secrets for you, or pre-create matching secrets in the target namespace. Without them, pods sit in image-pull errors instead of starting.

  • Registry credentials under global.imagePullCredentials for the chart to render, or pull secrets already present in the namespace.

Optional: a single sign-on identity provider

The Console signs users in locally with email, password, and passkeys by default, and that path needs nothing from you. If you want an external OIDC provider instead, have its issuer URL, client ID, and client secret ready, and read Single sign-on first: a complete provider entry makes the external provider the sole login method the moment it rolls out.

  • The OIDC issuer URL, client ID, and client secret, when you configure SSO.
  • A plan for who at your identity provider can grant the platform administrator role, when you set an admin claim.

Optional: an application secret-manager provider

By default, secrets reach the platform as environment values you inject. If you would rather the platform fetch them at runtime from AWS, Google Cloud, Azure, or Vault, that is a separate configuration layer. See Values and secrets for what each provider needs.

What your hosting must provide

See Hosting and access for how these choices shape topology and access. This section is the checklist to have ready before you install.

Kubernetes 1.23 or later, or OpenShift with the overlay

The dalp chart and the optional observability chart both declare Kubernetes 1.21 or later, but every autoscaler the dalp chart renders uses the autoscaling/v2 API, which Kubernetes serves from 1.23. Plan for Kubernetes 1.23 or later. OpenShift runs the same chart templates through a separate values overlay rather than a different chart. See Deploy DALP to OpenShift for what the overlay changes.

Before any chart, apply the Gateway API CRD bundle once per cluster. No Helm release can carry it, because Helm cannot upgrade CRDs shipped inside a release and the bundle exceeds what a release's stored secret allows.

Skip it and a release that renders an HTTPRoute fails at install time on the unknown resource kind, which a first install on a bare cluster hits by default because the docs site's route renders out of the box. OpenShift is the exception: its overlay renders Routes instead of HTTPRoute resources for every service, so an OpenShift install has no HTTPRoute to fail on and does not need the bundle at all.

Install covers the bundle's version and where it sits in the order.

  • The Gateway API CRD bundle applied to the cluster, before any chart, unless you install on OpenShift, whose overlay renders Routes instead and needs no CRD bundle.
  • A Kubernetes cluster at 1.23 or later, or an OpenShift cluster with the overlay applied.
  • Nodes with x86-64 CPUs. Every DALP image is built for Linux on x86-64.
  • A resource metrics API, such as metrics-server, so the autoscalers can read pod CPU. Without one, every autoscaled component stays at its floor.
  • At least two schedulable nodes. PgBouncer's two replicas must run on different nodes.
  • A default StorageClass that can bind the volumes the charts request, such as the persistent volumes of the observability stores.
  • When you enable the chart's contract-deployment job: a Retain-policy StorageClass for its journal volume, or the cluster's CSI provisioner plus permission to create StorageClass resources so the chart can create the Retain class for you. The job resumes from that journal after a pod restart, and losing the volume forces a fresh deployment at new addresses your running network cannot reconcile.

One exposure mechanism per service, and TLS you bring

The Console ships with ingress enabled. With local sign-in, the first account created on a fresh instance becomes a platform administrator, so create it before the Console's hostname is reachable from outside your network. Every later sign-up is a member, even after the last platform administrator loses the role. A platform administrator grants the role to another account on that account's Platform users page. When no platform administrator is left, Security and compliance posture shows how to restore the role.

The docs site ships with its own ingress enabled too, routing /docs on the Console's hostname. The Platform API stays internal, reached through the Console's own proxy. The block explorer is off by default and brings its own ingress when you enable it. Choose one intended exposure path per service from Ingress, Gateway API HTTPRoute, and OpenShift Route. If multiple objects render, inspect their hostnames and controller ownership for conflicting routes. The OpenShift troubleshooting section shows what that looks like.

Outside OpenShift, bring your own ingress controller. The dalp chart's ingresses name the class dalp-nginx by default, so either your controller registers a class with that name or you set ingressClassName on each ingress to match it. Reach for Gateway API HTTPRoute instead when your cluster standardises on a Gateway API implementation such as Envoy Gateway: each route names the Gateway it attaches to, so create that Gateway or point the route at yours. On OpenShift, skip the ingress controller, since Routes replace ingress there and the controller has nothing to do.

TLS differs by platform. Outside OpenShift, the chart requests no certificates: add cert-manager annotations or pre-created TLS secrets to the ingress, or HTTPS to your hostnames fails while plain HTTP answers. On OpenShift, Routes terminate TLS at the edge with the router's certificate and redirect plain HTTP. HTTPS therefore works without cert-manager. The optional per-Route cert-manager Certificate is off by default. Replace its placeholder issuer with your cluster's issuer before enabling it.

  • An ingress controller, a Gateway API implementation, or OpenShift Routes: exactly one per exposed service.
  • A load balancer the controller can obtain an external address from.
  • A certificate source outside OpenShift: cert-manager wiring or pre-created TLS secrets.
  • DNS entries for every hostname you plan to expose.

Backups decided and tested before production

The platform starts without a backup plan, and production without one leaves a failure with no recovery path. The dalp chart's Velero backup block ships turned off, and the chart never deploys a Velero server. Your database and object store need their own backup story, whether a managed service provides it or you operate it.

  • A backup and restore approach for PostgreSQL and object storage, tested before go-live. See Backup and disaster recovery for what a tested approach covers.

Resource sizing starts from the chart defaults

The chart sets CPU and memory requests and limits for every long-running container, except that the PgBouncer metrics sidecar has a memory limit but no CPU limit. Treat them as a starting footprint that you size for your own load, not a guarantee of capacity. 1000m is one CPU core. Production needs depend on the networks you index and their block volume, the number of participants, and the request rate, and the chart cannot see any of these in advance.

Component
Requests to limits, per pod
Replicas
Platform API api role
600m to 1500m CPU, 1536Mi to 3Gi memory
2 to 24, target 50% CPU
Platform API api role, frozen v1 fleet that serves the older /api/v1 contract
300m to 1000m CPU, 768Mi to 1536Mi memory
1 to 4, target 50% CPU
Platform API runner role
250m to 1500m CPU, 1536Mi to 3Gi memory
2 to 12, target 75% CPU
Platform API indexer role, serving pods
1250m to 2000m CPU, 1536Mi to 3Gi memory
2, fixed. One network's live indexing stays on one pod
Platform API indexer role, rebuild pods
The same as the serving pods
2, fixed
Platform API scheduler role
250m to 1500m CPU, 1Gi to 2Gi memory
1, fixed
Console
50m to 200m CPU, 512Mi to 756Mi memory
2 to 30, target 80% CPU
Docs site
100m to 500m CPU, 756Mi to 1024Mi memory
2 to 5, target 80% CPU
PgBouncer
100m to 500m CPU, 128Mi to 256Mi memory, plus a metrics sidecar at 10m CPU with no CPU limit and 32Mi to 64Mi memory
2, fixed
PostgreSQL metrics exporter
100m to 200m CPU, 32Mi to 128Mi memory
1, fixed
Investor portal, off by default
100m to 500m CPU, 256Mi to 512Mi memory
2 to 5, target 80% CPU
Block explorer backend, off by default
100m to 600m CPU, 640Mi to 1280Mi memory
1, fixed
Block explorer frontend, off by default
100m to 360m CPU, 320Mi to 640Mi memory
1 to 5, target 80% CPU

At their floor replica counts, the pods that run by default request about 7.9 CPU cores and 16.6 GiB of memory in total. The four indexer pods, serving and rebuild, account for 5 of those cores. Each autoscaler adds pods beyond its floor when average CPU passes its target, so plan node capacity for the ceilings you allow, not only the floors. With every default autoscaler at its ceiling, the same pods request about 26.2 CPU cores and 83 GiB of memory.

These totals count the long-running pods and leave out one-off Jobs. To change a row, set dapi.v2.autoscaling, dapi.v1.autoscaling, dapi.runnerDeployment.autoscaling, dapi.indexerDeployment.replicaCount, dapi.indexerDeployment.rebuild.replicas, dapi.schedulerDeployment.replicaCount or the matching block of another component. The rebuild pods idle while no reindex build exists. dapi.indexerDeployment.rebuild.enabled: false removes them, and every serving pod then also writes reindex builds. Topologies covers what each role does and what a failure of each costs.

Your datastores add their own footprint, which the table does not count. Supply a StorageClass that can bind the volumes the charts request and a load balancer that can assign an address to your controller. On managed clouds, workload identity can replace the static keys in the checklists. A self-managed or bare-metal cluster brings its own load balancer and injects every credential as a secret.

How a missing item shows up

You are ready to install when you have confirmed every item in both checklists and can name where each credential lives. If something slips through anyway, this is the signal each gap gives:

Missing or wrong
Signal
When
Gateway API CRDs not applied before the charts
The release fails at install time on the unknown HTTPRoute kind
At install
Master password unset, too short or too weak
Pods crash-loop, and the log names the failed length or entropy check
At boot, right after install
Auth secret left at the chart's committed placeholder
Pods crash-loop, and the log names the rejected default
At boot, right after install
DALP_GOVERNANCE_DOMAIN_SCOPE empty or local
The render fails and names the value
At install
Custody credential identity key left at the local default
Pods crash-loop, and the log names the rejected default
At boot, right after install
An EVM network with no RPC URL or upstream list
Pods crash-loop, and the error asks for a URL or upstreams
At boot
No default network, or two of them
Pods crash-loop, and the error names the offending entries. See Networks
At boot
A managed custody provider selected without its config block
Pods crash-loop, and the error names the missing section
At boot
signer.provider naming a provider this deployment switched off
Pods crash-loop, and the error names CUSTODY_PROVIDER_<KIND>_ENABLED
At boot
Pull secrets absent
Pods never start and report image-pull errors
At rollout
SMTP relay unreachable or wrong
The first invitation email never arrives, with no boot error
In use
Custody credentials present but invalid
The first signing request against that provider fails
In use
No certificate source outside OpenShift
HTTPS to exposed hostnames fails while HTTP answers
At first access

Frequently asked questions

Can I run each datastore on a different service, such as a managed Redis with a self-operated PostgreSQL?

Yes. The dalp chart points each dependency at its own connection details independently, so each datastore can run on a different service. Each one carries the limits of whoever operates it, so a production setup needs a tested backup plan for every datastore your own team runs.

Can a deployment sign through two custody providers at once, such as DFNS for one network and the local key store for another?

The deployment has a default signer.provider, while an organisation can select a configured provider during onboarding. That organisation choice becomes fixed once its first wallet is created. Review Custody providers and configure the required provider credentials before onboarding.

What changes when I add a network or move custody after go-live?

Adding a network touches only the network checklist: give the new entry its RPC URL or upstream list, and decide whether it becomes the default, since exactly one enabled EVM network carries that flag. The SMTP relay, the generated values and registry access stay as configured.

Moving custody touches only the custody checklist: set signer.provider, supply its configuration block, and add a webhook secret for DFNS or Ripple Custody's inbound webhooks. Moving to Ripple Custody adds one step: switch Ripple on with global.dalpApp.config.custody.providers.ripple.enabled: true, because the platform ships Ripple off. The master password and auth secret stay untouched.

They protect data at rest and sessions, not who holds the signing keys.

I do not plan to use Gateway API. Why does the Gateway API CRD bundle still block my first install?

Because the docs site renders both a classic Ingress and a Gateway API HTTPRoute by default, so its manifest names a resource kind the cluster must already recognise even though no Gateway controller is running to serve it. No Gateway controller ships with the charts, so the route does nothing until you supply a Gateway. Skipping the bundle only moves the failure earlier, to the unrecognised kind. Apply the CRDs or turn off every rendered HTTPRoute, including docs.httpRoute.enabled. On OpenShift, its overlay renders Routes instead of HTTPRoute for every service, so the bundle has nothing to guard there and you can skip it entirely.

See also

Was this page helpful?