Skip to content

Stash Cloud: From a Specialized Solution to General Cloud RLN Infrastructure ​

Over the past year, Stash Cloud has evolved from dedicated infrastructure for our own products into cloud RLN infrastructure for the RGB Lightning industry. This post records the core technical challenges we hit, the design decisions we made, and why we believe those choices matter for the wider RGB ecosystem.


1. Why We Did This ​

Original positioning ​

Stash Cloud started as a cloud RLN service tailored to three of our own products: Stash Wallet, RGB Dex, and Flash Dex. RGB uses client-side validation: asset state is maintained and verified locally on each user's node. That makes large-scale node operation, lifecycle management, and node security policies a prerequisite for taking RGB from concept to production.

We staffed a team with more than a decade of DevOps experience and built this infrastructure from scratch on open-source Kubernetes. It solves the hard parts of operating RGB Lightning nodes:

  • Automated lifecycle management — create, start, hibernate, and restore are orchestrated by the platform
  • Elastic scale (Scale to Zero) — zero compute while idle; wake without resyncing chain state, typically back to running within minutes
  • Millions online + tens of millions offline — multi-cluster architecture sized for high concurrency plus massive stored state
  • Trust-minimized security architecture — node-level isolation, dedicated disks, encrypted storage

Why we opened it up ​

After nearly a year of production and architecture work, one fact became clear: this infrastructure can serve the rest of the RGB Lightning ecosystem, not only our three products.

The Kubernetes split between control plane and worker nodes, declarative workloads, network policy, and storage orchestration match shared needs of RGB nodes — not proprietary tricks of a single product.

More importantly: the RGB ecosystem needs a lower ops barrier. A small team should not be locked out of RGB application development because it cannot build and run node infrastructure.

Goal ​

Upgrade Stash Cloud from dedicated infrastructure for our own products into cloud RLN infrastructure for the RGB Lightning industry:

  • Any RGB project or developer can plug into cloud nodes through the standard management API (/v3)
  • No in-house ops team required — focus on the application layer
  • Keep a trust-minimized security architecture so data ownership always belongs to the mnemonic holder

2. From Specialized to General: Challenges and Solutions ​

Turning dedicated infrastructure into general cloud RLN infrastructure is not as simple as "open an API." We had to balance cost, security, and flexibility, and design for ecosystem-scale load.

2.1 Challenge 1: Build on open-source Kubernetes, not managed K8s ​

The problem ​

Managed Kubernetes (AWS EKS, Google GKE, Alibaba ACK) gives you a cluster out of the box. Why did we build a self-managed cluster from scratch?

Start from the official cluster layout (Kubernetes architecture and components):

LayerCore componentsRole
Control planekube-apiserver, etcd, kube-scheduler, kube-controller-manager, optional cloud-controller-managerCluster-wide decisions: declarative API, persistent cluster state, Pod scheduling, control loops, cloud integration
Worker nodekubelet, kube-proxy (or an equivalent), container runtime (containerd / CRI-O)Run and maintain Pods on machines; provide runtime and node network rules
AddonsCluster DNS, CNI plugins, monitoring and loggingService discovery, Pod connectivity, observability

In production, the control plane usually spans multiple machines and worker nodes scale out for fault tolerance. Managed Kubernetes typically abstracts the control plane as a cloud service — less ops burden, but far less room to deeply customize the scheduler, storage classes, network policy, and control loops.

The docs also stress that Kubernetes is not a traditional all-in-one PaaS. It offers deployment, scaling, and load balancing at the container layer, but most defaults are optional and pluggable; the platform builder keeps choices on storage, networking, scheduling, and extension points. Stash Cloud is exactly that: a platform for RGB nodes on this foundation, not a locked managed template.

So our trade-offs:

Cost: managed-control-plane fees add up. Per-node billing does not hold at million-node scale.

Flexibility: RGB Lightning nodes need dedicated disks, node-level network isolation, and different lifecycle policies (user nodes hibernate after 48 hours idle; LSP stays up only after explicit authorization; Hub nodes stay up 24/7). Those do not fit managed-service templates, and we could not customize them for this workload.

Control: we needed full control of control-plane and node-component deployment and policy to reach “millions online + tens of millions stored offline.” That means deep customization of scheduling, storage classes, network policy, and controller behavior — the least open parts of a managed control plane.

The solution ​

We built a self-managed cluster on open-source Kubernetes (https://github.com/kubernetes/kubernetes), with both the control plane and worker nodes inside our ops boundary:

Control plane: declarative API + extensible control loops

  • All orchestration goes through kube-apiserver: create, hibernate, wake, and delete are desired state that controllers converge — not one-shot scripts
  • Cluster state lives in highly available etcd; production needs an explicit etcd backup and restore plan (the architecture docs emphasize this)
  • kube-scheduler binds unbound Pods to suitable worker nodes, considering resources, affinity / anti-affinity, data locality, and policy — we use that to place and lifecycle user, LSP, and Hub nodes differently
  • Controllers inside kube-controller-manager (Node, Job, EndpointSlice, ServiceAccount, and others) handle failure response and object linkage; cloud-specific logic, when needed, stays behind cloud-controller-manager
  • Kubernetes supports custom schedulers, CRDs, and API aggregation; we extend RGB node semantics without forking upstream

Worker nodes: kubelet + runtime for stateful workloads

  • On each worker, kubelet keeps containers running and healthy per PodSpec
  • The container runtime (e.g. containerd) owns container lifecycle; CNI assigns Pod IPs; kube-proxy (or an equivalent) maintains Service-related rules
  • RGB Lightning nodes are stateful workloads on StatefulSet: stable, unique identity and persistent storage per Pod. Unlike Deployment, StatefulSet Pods are not interchangeable; after a rebuild the same ID remounts the same volume — the architectural basis for “wake without resyncing chain state”

Custom StorageClass:

  • Each node gets its own cloud disk; reclaimPolicy: Retain so disks are not auto-deleted when the node is deleted
  • Dynamic expansion as node data grows
  • Scheduled snapshots; encrypted off-site copies go to Arweave and IPFS while the node is live

Custom NetworkPolicy:

  • Default-deny all intra-cluster traffic; nodes are fully isolated (including nodes under the same tenant)
  • All node-to-node communication uses public hostnames, so a misconfigured allowlist cannot open a hole

Custom scheduling and lifecycle:

  • user / lsp / hub follow different lifecycle rules
  • user nodes Scale to Zero after 48 hours with no management-API or runtime access; scaling a StatefulSet to 0 releases compute while volumes stay per policy. Apps can also call stop without waiting 48 hours
  • LSP requires explicit authorization — it does not happen when a wallet is registered or a user node is created; authorized LSP nodes are exempt from idle reclaim
  • Hub nodes stay up 24/7 and are never reaped for idleness

In-house node orchestration:

  • Wraps cluster capabilities behind RGB node semantics (developers see “nodes,” not raw Pods / PVCs)
  • Writes desired state via the API server; the control plane converges actual state
  • Lifecycle: create / start / stop / delete, plus data-export jobs

Stack mapped to architecture:

Open-source Kubernetes 1.30+ (self-managed control plane + workers)
  ├── Control Plane
  │     kube-apiserver / etcd / kube-scheduler / kube-controller-manager
  ├── Node
  │     kubelet + container runtime + CNI (+ kube-proxy or equivalent)
  ├── Workload: StatefulSet (stable identity + volumes + ordered scale)
  ├── Storage: custom StorageClass (dedicated disks, reclaimPolicy: Retain)
  ├── Network: NetworkPolicy (default deny; public hostnames only)
  └── Node orchestration
        └── Lifecycle (create / start / stop / delete) → desired state

Results ​

60%+ lower cost vs managed Kubernetes: no control-plane tax, better utilization via Scale to Zero, storage that grows only when needed.

Multi-cluster architecture sized for 1M+ online nodes and 10M+ stored offline, using a horizontally scalable control plane (e.g. multi-instance kube-apiserver), worker scale-out, and years of cost-control experience. That is an architecture capacity, not a live census of a single cluster.

Boot time from hours to minutes: Scale to Zero plus StatefulSet identity and persistent volumes means a waking node does not resync the chain; it resumes from the last hibernated state.


2.2 Challenge 2: Isolate the internal network — even nodes under the same tenant ​

The problem ​

Typical multi-tenant setups isolate external access and still share an internal network (for example, microservice calls). RGB Lightning nodes need absolute node-level isolation:

  • Even in the same cluster, even under the same tenant (developer / project), node A must not reach node B
  • Sensitive Lightning ports (RPC, P2P) exposed to other nodes are an attack surface
  • Tenancy is for developers / projects, but isolation must go down to each node: two nodes of the same tenant must not talk on the internal network

By default, Pods in a Kubernetes cluster can often discover each other via CNI Pod IPs and cluster DNS / Services — great for microservices, risky when the node is the security boundary.

The solution ​

Kubernetes NetworkPolicy (with a policy-capable CNI):

NetworkPolicy constrains Pod traffic at IP / port (OSI L3/L4). The model separates Ingress and Egress isolation: by default a Pod is non-isolated in both directions (all connections allowed); once a policy selects the Pod and declares the matching policyTypes, only explicitly allowed traffic passes. Policies are additive; a connection from source to destination requires both the source’s egress and the destination’s ingress to allow it.

How we apply that:

  • Independent Namespace per tenant, with policies on node Pods inside it
  • Default-deny undeclared internal Ingress / Egress: turn “Pods can talk” from a default into a prohibition
  • Node A’s Pod cannot rely on in-cluster Service DNS / Pod IP to reach node B
  • Same-tenant nodes are isolated too; business traffic uses the public hostname
  • Prerequisite: NetworkPolicy only works when a supporting network plugin enforces it — creating the object alone does nothing

Dedicated domains:

Each node gets {node-id}-{network}.stashcloud.net

  • Assigned at create time; no extra DNS setup
  • Tenant credentials and node ownership are checked on every request (Bearer API key on the management API)
  • Cross-tenant requests are rejected at the orchestration layer and never reach the Pod

Design philosophy:

Public-path traffic costs extra bandwidth. Not depending on an internal allowlist is the foundation of the security model. The cluster still has a CNI network; NetworkPolicy default-denies Pod-to-Pod paths, and business traffic uses public hostnames.

Internal peering means maintaining which nodes may talk to which ports. A too-wide allowlist, or a stale rule, becomes a hole.

Forbidding internal communication and forcing public hostnames is slightly more expensive and much simpler:

  • No allowlist to get wrong
  • Minimal blast radius — compromising one node does not enable lateral movement to other node Pods inside the cluster

Sketch:

External request
  → Ingress / node orchestration
       └── Management API /v3: Bearer API key + tenant ownership
  → Pod on the target worker node
       └── NetworkPolicy (Ingress/Egress)
             denies Pod ↔ Pod paths on the cluster network
             (including same Namespace / same tenant)

Results ​

A real trust-minimized network: default deny, least privilege, explicit checks — aligned with NetworkPolicy’s “not declared, not allowed” model.

A stolen tenant API key cannot reach another tenant’s nodes: ownership is enforced at Ingress.

Node-level isolation: one compromised node does not take down the rest of that tenant.

No allowlist, no allowlist bugs: forbidding internal communication avoids holes from a too-wide or stale allowlist.

Extra bandwidth is a trade we accept for a simpler, more reliable security model.


2.3 Challenge 3: Dedicated disks, no shared storage ​

The problem ​

Persistent data on an RGB Lightning node (channel state, RGB state, on-chain UTXO set) is extremely sensitive. Leak or corruption can mean permanent loss of funds.

Why shared storage fails here:

NFS or Ceph is common in the cloud — many nodes mount one network volume to save money. For RGB nodes that is a bad deal:

  • Cross-tenant leak risk — access control depends on filesystem ACLs; a misconfig can let tenant A read tenant B
  • I/O bottleneck — shared volumes are slower than dedicated disks; disk latency hits Lightning payments and channel ops
  • Large blast radius — one storage outage takes down every mounted node

The solution ​

Kubernetes storage orchestration separates “who claims a disk” from “who provides it,” which fits dedicated disks:

ObjectMeaning
PersistentVolumeClaim (PVC)The workload’s claim for capacity and access mode
PersistentVolume (PV)An actual volume available in the cluster
StorageClassDynamic provisioning rules: disk type, expansion, reclaimPolicy, etc.

Dedicated PVC + dedicated PV:

  • Creating an RGB node dynamically provisions a dedicated cloud disk via StorageClass and binds it to that StatefulSet Pod’s PVC
  • StorageClass uses reclaimPolicy: Retain: releasing the claim does not auto-delete the volume
  • Access mode is ReadWriteOnce: only one Pod can mount the disk; other tenants cannot attach it
  • This matches StatefulSet design: deleting or scaling a StatefulSet does not delete associated volumes by default, to protect stateful data — we treat that as the basis for soft-delete / hibernate, not an accident

No shared storage:

  • Hard constraint in code: no ReadWriteMany PVCs
  • Every node disk is ReadWriteOnce
  • We do not “save money” by mounting many tenants on one network filesystem

Retention:

  • Hibernate (Scale to Zero): StatefulSet releases compute (Pods); PVC / PV stay
  • Node delete: compute (Pods, StatefulSet) goes away; the hot disk and backups stay under the unified policy — persistent data is not cleared
  • Off-cluster copies: encrypted uploads to IPFS and Arweave start while the node is live. After deletion, IPFS copies stay 180 days as an extra platform recovery window; after 180 days they are written to Arweave, which is permanent once written
  • Ownership: node data belongs to the mnemonic holder, not a vendor or the platform
  • Users can export a disk archive and migrate to self-hosting

Results ​

10x+ disk I/O vs shared storage.

Physical isolation — each node’s disk is an independent PV; no shared-filesystem ACL misconfig can expose another tenant.

User-owned export: see From Managed to Self-Hosted: Giving Node Data Ownership Back to Users.

Delete reclaims compute only + long-lived off-cluster copies: after delete you can still restore from the retained PVC, snapshots, or off-cluster copies; IPFS stays another 180 days. Consistent with Kubernetes’ “prefer keeping stateful data” semantics, with platform-level backup and ownership on top.


2.4 Challenge 4: Access control — API key scopes and who holds the keys ​

The problem ​

Traditional cloud auth is accounts or OAuth. Lightning wallets want no KYC and no platform password. Creating a wallet in Stash Wallet is not a separate Stash Cloud account. Third-party developers get an API key by signing in with a wallet. We still need fine-grained control: one tenant may hold several API keys for read-only, create-node, delete-node, and so on.

Users also need a clear split: Stash Cloud provides compute and storage infrastructure only; mnemonics and private keys stay with the user. Do not assume the platform can “recover my lost private key.”

The solution ​

What an API key is for:

  • An API key lets a project / developer provision wallet nodes on behalf of users; it is not the user’s mnemonic
  • Typical flow: a wallet app creates a node per user with the API key; the user keeps their own mnemonic
  • Management API (/v3) scopes: nodes:read, nodes:write, nodes:delete (not read:nodes)
  • The platform stores only a SHA-256 hash of the key, never plaintext

Key custody:

  • Stash Cloud is non-custodial infrastructure: users hold their own mnemonics / private keys; the platform does not custody them, sign on their behalf, or move node funds
  • If a third-party app custodies user mnemonics, that is the app’s product choice—not Stash Cloud. Confirm key custody with that app before you integrate

Data and responsibility on Stash Cloud:

Stash Cloud is like a cloud VM vendor: compute and storage infrastructure only.

  • Isolation at the infrastructure layer — each node has its own namespace and cloud disk, with network default-deny between nodes, so one compromised node cannot spread to the others
  • No ability to move node funds — node identity keys and internal access tokens are never written to API responses or logs; the platform does not sign on a node's behalf or move its funds
  • Users and developers back up their own mnemonics and keys; Stash Cloud cannot help recover them

This responsibility split is essential:

PartyResponsible for
Stash CloudInfrastructure (compute, disks, isolation, backups)
User / developerKeys (generate, store, back up, recover mnemonic / private keys)

Management API auth (/v3):

Every call sends Authorization: Bearer <API_KEY>. The platform checks:

  1. The key hash exists in the database
  2. The requested node belongs to that key’s tenant
  3. The key’s scopes cover the operation (delete requires nodes:delete)

Kubernetes Namespace + RBAC (aligned with control-plane auth):

Kubernetes uses Namespaces as resource boundaries and RBAC (Role / RoleBinding, ClusterRole when needed) to say who may do what to which API resources. Our orchestration follows the same least-privilege model:

  • The orchestration component can only access node namespaces — no cluster-wide (ClusterRole) write grants
  • Least privilege on resource types (StatefulSet / Pod, PVC, NetworkPolicy, etc.)
  • No “god” service accounts: even if orchestration is compromised, lateral writes into other namespaces stay hard
  • Developer API scopes (nodes:read / nodes:write / nodes:delete) and in-cluster RBAC are layered: the former limits tenants; the latter limits what platform components may touch

Results ​

Trust-minimized auth with no KYC and no platform password: developers get an API key by signing in with a wallet; no personal data required. End users only create a wallet — they do not register a separate Stash Cloud account.

A leaked key can be revoked without touching the others.

Clear responsibility: the platform secures infrastructure; users and developers secure keys — an extension of the trust-minimized architecture, and the real meaning of data ownership.


3. From RGB-specific to general cloud RLN infrastructure: a standard API ​

Third-party developers get a REST management API, not raw Kubernetes. Example base: https://api.stashcloud.net (mainnet). network is bound to the instance — do not put it in the create body. The implementation is rgbldkd; type is only user / lsp / hub. The contract is the management API.

EndpointMethodDescription
/v3/nodesPOSTCreate a node (label / type / wait)
/v3/nodes/{id}GETNode status (including provisioning / running / stopped / deleted)
/v3/nodes/{id}/startPOSTStart a hibernated node
/v3/nodes/{id}/stopPOSTStop a node (PVC retained)
/v3/nodes/{id}/exportPOSTExport node data (lock the node first; archive has no private keys)
/v3/nodes/{id}/lsp/authorizePOSTExplicitly authorize as LSP
/v3/nodes/{id}DELETEDelete the node (compute only; disks and backups stay under the unified policy)

Auth: the management API uses Authorization: Bearer <API_KEY> and an ownership check.

Docs: the management API is Stash Cloud API. Runtime OpenAPI is rgb-ldk-api-public.


4. Security design: five layers of a trust-minimized architecture ​

  1. API key auth: Bearer + hashed storage on the management API; revoke one key without the rest
  2. Node-level isolation: Namespace + NetworkPolicy (default-deny Ingress / Egress); no in-cluster peering (including same tenant); public hostnames for business traffic
  3. Dedicated disks: one PVC / PV per node (ReadWriteOnce + reclaimPolicy: Retain); no shared storage
  4. Dedicated domains: {node-id}-{network}.stashcloud.net with ownership checks
  5. RBAC: orchestration can only touch node namespaces — no cluster-wide writes; developer API scopes and in-cluster RBAC are layered

Extra guarantees:

  • Encrypted backups to Arweave + IPFS while the node is live (Arweave is permanent once written)
  • Node delete: compute released immediately; hot disk and backups stay under the unified policy; IPFS copies stay 180 days after delete
  • Users own the data: it belongs to the mnemonic holder, not a vendor or the platform
  • Export anytime and migrate to self-hosting (see From Managed to Self-Hosted)
  • If the platform goes away, mnemonic + backup file is enough to restore
  • Keys are yours: Stash Cloud is not responsible for managing mnemonics or private keys and cannot recover them. The platform takes responsibility for infrastructure failures, not for lost keys or running two nodes on the same channel state — see Overview — Responsibility

5. Roadmap: from dedicated to open ​

5.1 Done (Q1–Q3 2026) ​

  • ✅ Self-managed cluster on open-source Kubernetes
  • ✅ Node-level NetworkPolicy isolation
  • ✅ Dedicated disks, no shared storage
  • ✅ Node data export and self-hosted migration
  • ✅ Full lifecycle for rgbldkd nodes (developed by Bitlight Labs)
  • ✅ Management API /v3 (Bearer API key) documented — see Stash Cloud API

5.2 In progress (Q4 2026) ​

  • 🚧 Opening API access to third-party developers
  • 🚧 SDKs (TypeScript, Python, Go)
  • 🚧 Multi-region clusters (lower latency); “millions online” is multi-cluster capacity, expanding by region

5.3 Planned (2027) ​

  • 📋 Custom node config (env vars, start flags)
  • 📋 Monitoring and alerting API (Prometheus + Grafana)
  • 📋 More features as the RGB ecosystem needs them

6. Why this matters for RGB ​

Lower barrier ​

Small RGB teams should not need a DevOps hire to offer cloud nodes. Developers build wallets, DEXes, and payment gateways; Stash Cloud runs the nodes.

Example:

A new RGB wallet team of 2–3 engineers. Self-hosting nodes means:

  • Renting servers
  • Standing up Kubernetes (or Docker Compose)
  • Storage, networking, monitoring, alerts
  • Lifecycle scripts
  • Upgrades, incident response, capacity planning

That is at least one full-time DevOps engineer.

With Stash Cloud:

typescript
const client = new StashCloudSDK(apiKey);
const node = await client.nodes.create({
  type: 'user', // rgbldkd is the implementation; type is only user / lsp / hub
  wait: true,
});
// Typically running within minutes (no chain resync)

From "one DevOps hire and months of setup" to "a few lines of code, ready in minutes." The real path is POST /v3/nodes; network comes from the instance you talk to.

Cost ​

Cheaper than owning servers plus managed Kubernetes. Scale to Zero means idle nodes consume no compute.

Security you can leave ​

Trust-minimized architecture plus node-level isolation, with an exit: export and self-host. No vendor lock-in.

What "no lock-in" means here:

Lock-in usually has two layers:

  1. Data format — proprietary dumps that need conversion
  2. API lock-in — app code wedded to vendor-only APIs

Stash Cloud avoids both:

  • Standard data — exports are upstream rgbldkd format, restorable in Bitlight RGB LDK Control Panel
  • Generic semantics — create / start / stop, not Stash Cloud-only features

A user can:

  1. Export (mnemonic + backup file)
  2. Install rgbldkd on their own machine
  3. Restore and keep going

That is a documented, tested path, not a theoretical one.


7. Closing: the philosophy of going open ​

What RGB Lightning taught us ​

RGB's client-side validation — each user verifying state on their own node — is a natural extension of decentralization.

Public blockchains like Ethereum publish all state and have every full node verify every transaction. That is strongly trustless, at the cost of privacy and scale.

RGB's choice: each transfer and channel state is verified locally among the parties involved; the chain only holds unforgeable cryptographic commitments.

The implication: users must actually own their data (mnemonic + node backup), not rent custody from a platform.

That idea pushed Stash Cloud open ​

  • From Stash Wallet, RGB Dex, and Flash Dex only — to every RGB Lightning project and developer
  • From "the platform holds it" — to export and migrate
  • From proprietary infra — to a standard API and open access

How to understand Stash Cloud correctly: the cloud RLN service Stash Cloud provides is the same as cloud servers from cloud vendors — it only supplies compute and storage infrastructure. The goal is to lower the barrier for developers and users entering the RGB ecosystem.

What we believe ​

Real infrastructure should be transparent, open, and portable. Stash Cloud is not trying to lock users in. It exists to lower the ops barrier for RGB Lightning so more teams can ship RGB assets and Lightning apps.

The future we want:

  • Any developer can offer RGB Lightning nodes to users in hours
  • Users know where their data lives, how to back it up, and how to move it
  • Application-layer innovation is not gated by infrastructure

That is why we turned Stash Cloud from a specialized solution into general cloud RLN infrastructure.


Appendix: stack overview ​

┌──────────────────────────────────────────────────────────────┐
│  Stash Cloud stack (RGB Lightning cloud RLN platform)       │
├──────────────────────────────────────────────────────────────┤
│  Application                                                 │
│    - Stash Wallet / RGB Dex / Flash Dex / third-party RGB    │
├──────────────────────────────────────────────────────────────┤
│  API                                                         │
│    - /v3 Bearer                                          │
├──────────────────────────────────────────────────────────────┤
│  Orchestration                                               │
│    - Lifecycle / data export → declarative desired state     │
├──────────────────────────────────────────────────────────────┤
│  Kubernetes 1.30+ (open-source, self-managed)                │
│    Control Plane                                             │
│      kube-apiserver / etcd / kube-scheduler                  │
│      kube-controller-manager (+ optional cloud-controller)   │
│    Worker Node                                               │
│      kubelet + container runtime + CNI (+ kube-proxy)        │
│    Workloads & policy                                        │
│      StatefulSet (stable ID + volumes + Scale to Zero)       │
│      PVC/PV + StorageClass (dedicated, Retain / RWO)         │
│      NetworkPolicy (default-deny Ingress/Egress; public only)│
│      Namespace + RBAC (least privilege; no cluster writes)   │
├──────────────────────────────────────────────────────────────┤
│  Storage                                                     │
│    - Dedicated PVs / snapshots / Arweave + IPFS off-site     │
└──────────────────────────────────────────────────────────────┘

See also: Kubernetes overview, components, architecture.

Trade and secure your RGB assets | Unlock the full potential of the RGB protocol