TSG deployment guide
This guide covers deploying the TNO Security Gateway to Kubernetes with the TSG CLI. For a first participant end to end, start with Getting started. The configuration reference documents every input field.
Prerequisites
Client tools
Helm is not used.
npm install -g @tsg-dsp/cli@latest
Cluster
- Kubernetes 1.24 or newer. An ecosystem deployment needs roughly 4 CPU and 8 GB of allocatable capacity; a single participant about half that.
- CloudNativePG 1.30 or newer, for the
DatabaseRoleCRD each component's database login depends on. - An Ingress controller, or the Gateway API CRDs plus a controller.
- cert-manager, if the TLS Secrets the rendered routes reference should be issued automatically.
tsg deploy checks these against what the bundle actually renders and refuses
to start if something is missing or too old. They are cluster-admin concerns;
TSG never installs or removes them.
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm upgrade --install cnpg cnpg/cloudnative-pg \
--namespace cnpg-system --create-namespace
Public HTTPS endpoints are required for DID document resolution, even for a single-cluster deployment.
Deployment shapes
One document describes a deployment. Its stacks determine whether it represents one participant, a complete ecosystem, or a managed service.
| Shape | The question it answers | Example |
|---|---|---|
| Participant | I am one organisation joining a dataspace somebody else runs. | participant.yaml |
| Ecosystem | I want the authority and participants on one cluster. | ecosystem.yaml |
| Managed | I operate TSG on behalf of other organisations. | multi-tenant wallet stacks |
The participant shape is the ordinary production one. The ecosystem shape is for
demonstrations, hands-on sessions, and integration environments. It puts the
authority and every participant in one namespace, usually in shared database
mode so the whole thing fits on a laptop.
The CLI ships more of these under examples/ in the repository, including a
composition cookbook and a use-case-app deployment.
Deploying
1. Write the configuration
Start from participant.yaml and change the marked values: the namespace, the admin username, your host, your participant id and name, and the authority's DID, domain and credential type as given to you by whoever runs the dataspace.
Point DNS at your ingress or gateway address before deploying. Certificate issuance and DID resolution both depend on it.
2. Create the Secrets
Rendered output only references credentials, so the Secrets it names must
exist first. Supply them with SOPS, Sealed Secrets, External Secrets, or plain
kubectl. For a demo, run:
For a participant joining an external authority, first create the namespace and store the pre-authorized code supplied by that authority. The CLI cannot invent this code:
kubectl create namespace tsg-alfa
kubectl -n tsg-alfa create secret generic tsg-alfa-preauth --from-literal=code=YOUR_CODE_HERE
tsg secrets generate participant.yaml --apply
This never overwrites material that already exists.
With auth.clientAuthMethod: private_key_jwt, generate a key pair per client
first. The public half is a render input and can be committed. Keep the private
half out of Git and deliver it as a Secret:
tsg keys generate alfa wallet
tsg keys generate alfa control-plane
3. Review what would change
tsg diff participant.yaml
This renders to a temporary bundle and shows the difference against the cluster,
including anything that would be pruned. Add --verbose for the full object
diff. The CLI redacts Secret values.
4. Deploy
tsg deploy participant.yaml
deploy renders, diffs, applies in ordered waves, waits for readiness, and
prunes what the previous inventory named and this render no longer does. Use
--context to pick a kubeconfig context, and -y for non-interactive runs.
5. Verify
kubectl get pods -n tsg-alfa
tsg status participant.yaml
With the participant example, the services are then reachable at:
- SSO Bridge:
https://alfa.example.com/ - Wallet:
https://alfa.example.com/wallet/ - Control Plane:
https://alfa.example.com/control-plane/ - Data Plane:
https://alfa.example.com/http-data-plane/ - Dataspace Starter:
https://alfa.example.com/dataspace-starter/
Sign in to the SSO Bridge with the administrator credentials and, for anything beyond a test deployment, enable two-factor authentication there.
Continuous deployment
tsg render does not contact a cluster or the network. The same inputs and CLI
version produce the same bytes, so you can commit and review the manifests:
tsg render participant.yaml -o gitops/tsg
Argo CD or Flux then owns apply and prune. Do not use tsg deploy against the
same resources. Pin spec.images.<component>.digest for a committed bundle so
its image references do not change with the CLI version.
The continuous deployment guide has working Flux and Argo CD examples. It also explains ordering, Secret delivery, controller tracking, and the prune settings needed to protect database resources.
Outside a controller-managed deployment, you can apply a bundle rendered earlier without reinterpreting the configuration:
tsg apply gitops/tsg
Ongoing operations
Updating
Change the configuration and rerun tsg diff, then tsg deploy. A full
deployment also reconciles removed stacks and retains their data.
Deploying part of a file
tsg deploy ecosystem.yaml -s alfa -s bravo
A stack-selected run never reconciles, because the stacks it did not render are
unselected rather than absent. Add --include-infra when the shared
infrastructure set also needs to be applied.
Uninstalling
tsg uninstall participant.yaml # retains databases and volumes
tsg uninstall participant.yaml --delete-data # destroys them
Uninstall works from the inventory recorded in the cluster, not from the configuration file, so it removes what was actually deployed.
Gateway API (Envoy Gateway)
The CLI can expose the applications through the Gateway API instead of an
Ingress. This is opt-in. You can enable both while moving traffic one host at
a time.
routing:
ingress:
enabled: false
gateway:
enabled: true
className: eg
clusterIssuer: letsencrypt
Prerequisites:
- The Gateway API CRDs and a controller. The default class is Envoy Gateway
(
eg). - cert-manager started with
--enable-gateway-api, so it issues certificates forGatewaylisteners as it does for ingresses. - The
egGatewayClasscreated withmergeGateways: true.
The mergeGateways setting is easy to miss. TSG renders one Gateway per
distinct host, so without it every host gets its own Envoy proxy fleet and its
own cloud load balancer. An Ingress controller typically serves every host
through one. In a live cluster test, four Gateway objects produced four
separate external IPs before mergeGateways was applied.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: merged-proxy-config
namespace: envoy-gateway-system
spec:
mergeGateways: true
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: merged-proxy-config
namespace: envoy-gateway-system
With mergeGateways: true every Gateway under the eg class shares one Envoy
fleet and one external IP, routed by TLS SNI. See
Deployment Mode
for the constraint this relies on: the (port, protocol, hostname) tuple must
be unique across merged listeners, which holds here because each Gateway uses
a distinct host.
If you point DNS at the merged IP, reserve it as a static cloud address first.
Envoy Gateway creates a Service with a dynamic address, which may change if
Kubernetes recreates the Service.
You do not have to choose an owner within a stack. TSG renders the Gateway on
the first component of each host and attaches the rest as HTTPRoutes.
Changing what is rendered
The typed configuration covers replicas, resources, nodeSelector, ingress
class, and annotations. For other Kubernetes fields, add a patch. The CLI
applies it after rendering and before apply:
patches:
- target:
kind: Deployment
allowMultiple: true
merge:
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
See Patches for targets, operations and ordering.
Related documentation
- Dataset configuration describes how to advertise an offer.
- CLI reference lists every command.
- Configuration reference documents every field.
- Architecture explains how the components fit together.
For the previous Helm-generating CLI format, follow the manual CLI migration guide. tsg migrate does not convert that format.