The Nightshade path (absolute privacy)
This is the deployment for operators who want no footprints: no name on the account, no open port to find, and nothing on any box that points to you even if it is seized and imaged.
It has more moving parts and demands more discipline than the
single host or the Swarm cluster,
but it changes nothing about how Crimson Haven works. It is the same
crimson-client, the same crimson-backend and the same PostgreSQL, wrapped
differently.
The one principle
Section titled “The one principle”Assume every node will eventually be seized, scanned, or subpoenaed. Nothing on a node should point back to a human, and any node must be replaceable within minutes.
Every unusual choice below (paying in crypto, hiding SSH inside Tor, encrypting every disk, refusing to give a box a public port) follows from that sentence. We don’t defend a node. We make losing one not matter.
Threat model
Section titled “Threat model”| Threat | Mitigation |
|---|---|
| Internet-wide port scanners (Shodan, Censys) | The app and data boxes expose nothing publicly. SSH lives inside a Tor hidden service. Only the edge shows 80/443. |
| A hoster watching your traffic | Every node-to-node link is WireGuard (encrypted and authenticated). Every admin session goes over Tor. No plaintext, no leaked intent. |
| A seized or disk-imaged box | LUKS2 full-disk encryption with remote unlock; secrets never baked into the image; no operator identity anywhere. |
| A provider’s KYC or payment trail | VPSes paid in Monero (XMR), prepaid; accounts made with anonymous mailboxes; no reused identifiers. |
| A registrar caving to pressure | Domains are cattle, not pets: DNS-as-code, one-command rotation, spare registrars pre-staged. |
| A poisoned deploy pipeline | Self-hosted Git + CI, pinned digests, signed images, deploys only over the tunnel, least-privilege keys per node. |
Underlying assumption: the hosting provider is not your friend. Treat the hypervisor as hostile. That is why disk encryption, encrypted backups and disposability matter more here than on a box you trust.
Topology: one gate, many rooms
Section titled “Topology: one gate, many rooms”One public gate, and nodes that only ever dial out to it. Three nodes:
- The Gate (
edge): a VPS that is the only thing on the public internet. It runs Pangolin (a self-hosted tunnelled-ingress control plane) with Traefik in front and a WireGuard server (Gerbil) behind. It exposes80,443and the WireGuard port, nothing else. - The Face (
app): a VPS that runs only the statelesscrimson-client. No database, no secrets, nothing worth seizing. Zero public ports. - The Vault (
home): a residential or colocated box behind NAT that holds the state:crimson-backend+ PostgreSQL. No port forwarding, no public ports.
🌍 public internet end users (HTTPS) you, the operator │ (Tor Browser / │ ssh-over-Tor) ▼ ┆ (Tor only) ┌─────────────────────────────────────┐ ┆ │ THE GATE · edge VPS │◀┄┄┄┄┘ onion: edge-ssh │ public: 80 · 443 · 51820/udp (WG) │ │ Traefik ⟵ Pangolin ⟵ Gerbil (WG srv)│ │ sshd → Tor onion only │ └────────┬───────────────────┬─────────┘ WireGuard │ │ WireGuard (host=stream) │ │ (host=api) ▼ ▼ ┌──────────────────────┐ ┌──────────────────────────┐ │ THE FACE · app VPS │ │ THE VAULT · home server │ │ no public ports │ │ no public ports · NAT │ │ Newt ⟶ (dials out) │ │ Newt ⟶ (dials out) │ │ crimson-client (static)│ │ crimson-backend (REST) │ │ sshd → onion only │ │ PostgreSQL (LUKS volume) │ └──────────────────────┘ │ sshd → onion only │ └──────────────────────────┘
the Face and the Vault NEVER talk to each other. only the visitor's browser talks to both, each via the Gate.The single-gate rule
Section titled “The single-gate rule”- Only the Gate has inbound public ports. Everything else dials out.
- The Face and the Vault each run Newt, Pangolin’s tunnel client, which opens an outbound WireGuard tunnel to the Gate. Because the connection is outbound, neither needs an inbound firewall opening, not even for the tunnel.
- A visitor loads
https://stream.<domain>→ Traefik on the Gate → WireGuard → Newt on the Face → the staticcrimson-client. - The browser then calls
https://api.<domain>for accounts and progress → Traefik on the Gate → WireGuard → Newt on the Vault →crimson-backend→ PostgreSQL. - The Face and the Vault never talk to each other. The client is static; only the browser talks to both, each through the Gate.
Scan the Face’s or the Vault’s IP and you get nothing. Only whoever holds the WireGuard keys on the Gate knows they exist.
The three nodes
Section titled “The three nodes”The Gate (edge): the only public surface
Section titled “The Gate (edge): the only public surface”One small, declarative public surface that fronts both other nodes the same way: one ingress, many origins.
| Layer | Choice | Notes |
|---|---|---|
| Reverse proxy / TLS | Traefik (managed by Pangolin) | ACME via DNS-01, so there’s no :80 challenge footprint; wildcard certs per domain. |
| Tunnel server | Pangolin + Gerbil (WireGuard) | Terminates the Newt tunnels from the Face and the Vault. |
| Control plane | Pangolin dashboard/API | Never public: bound to localhost, reached only via a Tor onion or the WG admin subnet. |
| SSH | sshd bound to 127.0.0.1, published as a Tor v3 onion |
No public 22 anywhere. |
| Firewall | nftables, default-deny inbound; allow 80/443 + 51820/udp from the world; drop the rest |
Egress limited to what it needs (ACME, Tor, mirrors over Tor). |
| Disk | LUKS2 full-disk encryption | Remote unlock via dropbear-SSH-over-Tor at boot. |
The Face (app): stateless and burnable
Section titled “The Face (app): stateless and burnable”A minimal Docker Compose stack. No database, no user state, nothing to seize:
app stack├── newt # outbound WireGuard tunnel to the Gate (the ONLY way in)└── client # crimson-client SPA (static, served by caddy/nginx)crimson-clientis a plain static build. It gets the public API base URL (https://api.<domain>) at build time, so the browser callscrimson-backenddirectly through the Gate. The client container never talks to the backend.- Stateless, so disposable. The Face can be destroyed and rebuilt from the CI image with no restore step. Losing it costs only uptime.
- No public ports.
nftablesdrops all inbound; the WireGuard interface Newt creates is the only ingress. Egress is locked down to almost nothing.
The Vault (home): the only real data
Section titled “The Vault (home): the only real data”Everything stateful lives here and only here. A Docker Compose stack:
home stack├── newt # outbound WireGuard tunnel to the Gate (the ONLY way in)├── backend # crimson-backend: accounts + watch-progress + grants├── postgres # accounts, progress, preferences (on a LUKS volume)├── (valkey) # optional session / rate-limit cache└── (other home services)crimson-backenddoes its usual job: metadata, accounts, the login wall, watch progress, and the/sign,/resolve,/scrape-metagrants. It scrapes nothing third-party, as The big picture describes, so nothing here invites a takedown.- PostgreSQL sits on a LUKS-encrypted volume. Daily
age-encrypted dumps ship to an XMR-paid object store (see Data & backups). - CORS allows only the client origin (
https://stream.<domain>), so the browser’s API calls work and everything else is refused. - Behind residential NAT, no port forwarding. Newt dials out to the Gate; Pangolin
publishes the backend as
api.<domain>. - This is the one node you can’t treat as cattle. It is long-lived, so it gets a more conservative unlock policy (e.g. local TPM + PIN rather than remote unlock), the strictest monitoring, and the backups everything else can skip.
Request paths and address plan
Section titled “Request paths and address plan”Two independent routes, both through the Gate; the Face and the Vault never touch.
(1) Load the sanctuary (static):Browser ──TLS──▶ Traefik (edge:443, host=stream.<domain>) ──▶ Gerbil/WireGuard ──▶ Newt (Face) ──▶ crimson-client [static]
(2) Accounts / watch-progress (called by the browser, not by the Face):Browser ──TLS──▶ Traefik (edge:443, host=api.<domain>) ──▶ Gerbil/WireGuard ──▶ Newt (Vault) ──▶ crimson-backend ──▶ PostgreSQLPrivate addressing:
| Network | CIDR | Purpose |
|---|---|---|
| WG tunnel net | 10.88.0.0/24 |
Gerbil ↔ Newt clients. |
edge (Gate) |
10.88.0.1 |
Gerbil server. |
app (Face) |
10.88.0.2 |
Newt on the stateless client node. |
home (Vault) |
10.88.0.3 |
Newt on the stateful backend node. |
| Vault internal Docker | 172.30.0.0/24 |
backend ↔ postgres ↔ valkey. |
Administration never touches the clearnet:
You (Tor Browser / torsocks ssh) │ resolve <random>.onion ▼Tor network ──▶ HiddenServicePort 22 → 127.0.0.1:22 on the target nodeSSH keys are per node, ed25519, and live only in your offline keystore.
Layers of anonymity
Section titled “Layers of anonymity”The protection is layered: procurement → identity → network → host → operations. Remove any one layer and the others still hold.
Procurement
Section titled “Procurement”- Payment: Monero (XMR), prepaid for the longest term the provider allows. No cards, no PayPal, no recurring payment tied to a name.
- Providers: hosters that accept XMR (directly or via a privacy-respecting reseller), need little or no KYC, and offer an API. Keep at least two pre-vetted providers so a burn can land on a different provider and ASN.
- No reuse pattern: vary provider, region and account per node, so seizing one box gives no map to the others.
Identity
Section titled “Identity”- A separate anonymous mailbox per provider account, each created over Tor.
- Unique random usernames and passwords per account, stored only in the secrets vault.
- No phone numbers. If SMS is forced, use a voucher path or drop that provider.
Network
Section titled “Network”- Administration is Tor-only. SSH, Git, CI and the Pangolin admin are all reached via v3 onion services. There is no clearnet management plane to find.
- The data plane is WireGuard-only, always dialled outbound from the resource nodes. The Face and the Vault are invisible to internet scans.
- DNS-01 ACME with an API token scoped to a single zone, stored only on the Gate and rotated when the domain rotates. The app and data nodes have no public DNS at all.
- No third-party CDN, no Cloudflare in front. This is the opposite of the standard path: no extra KYC’d party sees your TLS. The Gate terminates TLS itself.
- Egress hardening: the Face has no general internet egress. OS updates come over Tor during maintenance windows, or are baked into a rebuilt image.
- LUKS2 full-disk encryption on every node; keys never stored on the node.
- No analytics, telemetry or crash reporters in any container.
crimson-clientships with zero third-party SDKs; keep it that way. - Log minimization: access logs off or truncated; no client-IP retention beyond what
Traefik holds in memory; backend logs carry user IDs only (no IPs, no PII) and are
rotated hard. The backend’s security ledger (
security_events) does record client IP and user agent, so setSECURITY_EVENTS_RETENTION_DAYS(default90) as low as you can tolerate. - NTP over Tor or NTS, UTC everywhere, neutral locale, and generic codename hostnames that reveal nothing of your naming style.
Operations
Section titled “Operations”- All infrastructure-as-code and secrets live in a self-hosted Git (onion), never on a public forge tied to a name.
- Your workstation is a hardened, Tor-routed environment (a dedicated VM or a Tails-like setup). Out of scope here, but assumed.
- Burning is cheap and rehearsed, so the answer to any anomaly is “destroy and rebuild”, never “investigate in place”.
Disposability
Section titled “Disposability”Every node is cattle. Its whole life:
You ──▶ provision (XMR-funded account, API token) ──▶ fresh IP / instance ──▶ ansible-playbook site.yml -l <new-node> └─ harden OS · LUKS · nftables · Tor onion · enrol Newt ──▶ register as a deploy target ──▶ CI deploys the stack over the tunnel ══▶ node live. no manual steps. minutes, not hours.What must survive a burn lives outside any single node:
- The IaC repo (Ansible / Terraform), in self-hosted Git, mirrored offline.
- The secrets vault (WG keys, SSH keys, DB creds, API tokens),
age/sops-encrypted and backed up offline. - Database backups:
age-encrypted dumps in XMR-paid object storage. - Tor onion keys, your call: keep stable onion addresses across burns (store the keys), or mint fresh onions per rebuild for maximum unlinkability. Default: fresh onions for admin SSH; stable only if an outside party must keep an address.
Everything else rebuilds from code. A burn is terraform destroy (or stop paying and
wipe) plus a re-run of the provisioning pipeline against a new instance.
Infrastructure as code
Section titled “Infrastructure as code”Everything lives in one repository; no node is configured by hand.
crimson-nightshade/├── terraform/ # optional: provider-API provisioning (XMR-funded)├── ansible/│ ├── inventory/ # logical hosts → ONION addresses (never clearnet IPs)│ ├── roles/│ │ ├── base_hardening/ # nftables, sysctl, auto-updates, no-PII, UTC│ │ ├── luks_remote_unlock/│ │ ├── tor_onion_ssh/ # publish sshd as an onion, kill public 22│ │ ├── pangolin_edge/ # Traefik + Pangolin + Gerbil (Gate only)│ │ ├── newt_client/ # outbound tunnel enrolment (Face + Vault)│ │ ├── client_stack/ # compose: stateless crimson-client (Face)│ │ ├── backend_stack/ # compose: backend + postgres + valkey (Vault)│ │ └── backup_age/ # encrypted DB dumps → object store (Vault)│ └── site.yml├── compose/{client,backend}/docker-compose.yml├── secrets/ # sops/age-encrypted ONLY, plaintext never committed└── pipelines/.woodpecker.ymlRules:
- Idempotent: re-running
site.ymlconverges any node to spec. - No plaintext secrets, ever.
sopswithage; CI gets a scoped, short-lived decrypt key. - Inventory holds onion addresses, not IPs, so a leaked repo reveals nothing scannable.
- Least privilege per node: the Face’s deploy key can only deploy the stateless client; it can’t touch the Gate or the Vault. A separate, more tightly held credential governs the backend on the Vault.
Adding or rotating a node takes four steps: add an inventory entry (codename + role +
onion), terraform apply (or a manual XMR order), ansible-playbook site.yml -l <codename>, and, for the Face, let CI redeploy. Switching providers means a different
Terraform module and nothing else.
Host hardening
Section titled “Host hardening”nftables on the Face and the Vault
Section titled “nftables on the Face and the Vault”Both treat the tunnel as the only way in. They differ only in egress: the Face needs essentially none; the Vault also reaches its own PostgreSQL and Valkey on the internal Docker network.
table inet filter { chain input { type filter hook input priority 0; policy drop; iif "lo" accept ct state established,related accept iif "wg0" accept # the tunnel from the Gate is the ONLY ingress # no public ports. period. } chain output { type filter hook output priority 0; policy drop; oif "lo" accept ct state established,related accept ip daddr 172.30.0.0/24 accept # internal docker (VAULT only) oif "wg0" accept # responses over the tunnel # NO general internet egress. updates happen over Tor, in maintenance mode. }}SSH as an onion service (every node)
Section titled “SSH as an onion service (every node)”# /etc/tor/torrc (excerpt)HiddenServiceDir /var/lib/tor/ssh/HiddenServiceVersion 3HiddenServicePort 22 127.0.0.1:22# sshd binds 127.0.0.1 only; public 22 is firewalled shutConnect with torsocks ssh root@<addr>.onion. With client authorization (onion
auth keys) enabled, the service cannot be reached, or even detected, without your key.
Encrypted disk and remote unlock
Section titled “Encrypted disk and remote unlock”- Root on LUKS2. At boot, an initramfs dropbear SSH server, reachable as a Tor onion, lets you type the passphrase remotely. The key never touches the disk, so a powered-off, seized node is just noise.
- Disposable nodes may instead take a one-time keyfile delivered at provision time and held only in the vault, so rebuilds stay fully automated.
Data & backups
Section titled “Data & backups”All persistent data lives on the Vault (
home). The Face is stateless and has nothing to back up.
| Concern | Approach |
|---|---|
| Where | The Vault only. |
| What’s stored | Accounts (id, handle, and either a PBKDF2 password hash or a mnemonic account’s Ed25519 public key), watch progress, preferences, and the security ledger. No real names; email is optional. |
| At rest | PostgreSQL on a LUKS volume. |
| Backups | pg_dump → age-encrypt (recipient = an offline key) → upload to an XMR-paid, S3-compatible store. |
| Restore | Rebuilt Vault → ansible → pull the latest age dump → pg_restore. Tested as part of burn drills. |
| Retention | Short and rolling (e.g. 7 daily + 4 weekly), to limit the damage of any single leaked backup. |
Data minimization: email is only needed for password accounts and recovery. Steer members to mnemonic accounts, which need no email and have no password to phish or leak.
The pipeline (client to the Face)
Section titled “The pipeline (client to the Face)”The same idea as the normal CI/CD page, except every part of it sits behind Tor and every deploy travels the tunnel, never the clearnet.
git push (over Tor) ──▶ Forgejo (onion) ──webhook──▶ Woodpecker ──▶ build crimson-client image (pinned base, digest) ──▶ push to a PRIVATE registry ──▶ cosign-sign ──▶ deploy over WG/onion ──▶ Face: docker compose pull && up -d (client only) ──▶ healthcheck ──▶ back to CIAn illustrative pipelines/.woodpecker.yml:
steps: test: image: node:lts commands: [ "npm ci", "npm run lint", "npm test" ]
build: image: docker:dind commands: # API base URL baked in at build time; the BROWSER (not the Face) calls it. - docker build --build-arg VITE_API_BASE_URL=https://api.$DOMAIN \ -t $REGISTRY/crimson-client:$CI_COMMIT_SHA . - docker push $REGISTRY/crimson-client:$CI_COMMIT_SHA
sign: image: cosign commands: [ "cosign sign --key $COSIGN_KEY $REGISTRY/crimson-client:$CI_COMMIT_SHA" ]
deploy: image: deploy-agent # has WG/onion access + a scoped Face deploy key commands: - cosign verify --key $COSIGN_PUB $REGISTRY/crimson-client:$CI_COMMIT_SHA - ssh app 'cd /srv/client && \ IMAGE=$REGISTRY/crimson-client:$CI_COMMIT_SHA docker compose up -d --pull always client' when: { branch: main }- Pinned digests for all base images; cosign-signed builds; the deploy verifies the signature before rollout.
- Scoped credentials: the CI deploy key can only
docker composethe client stack on the Face. It cannot configure the host, touch the Gate, or reach the Vault. - Tunnel-only delivery. Image pull and deploy go over WireGuard/onion.
- No public forge, no public artifacts. The whole pipeline is behind Tor; build logs carry no secrets.
- Rollback is one command to the previous SHA, and safe because the client is stateless.
The backend deploys on a separate track: its own image and a tighter deploy credential, targeting the Vault over the tunnel, with a gated migration step that runs only on explicit approval so live data is never touched by accident. A client change never reaches data; a backend deploy never depends on the disposable node.
The burn runbook
Section titled “The burn runbook”anomaly (scan hit · provider notice · integrity alert) │ ├─ the Face (stateless)? │ remove its peer from Gerbil (sever instantly) ──▶ destroy / wipe │ ──▶ re-provision ──▶ ansible ──▶ CI redeploys the client. NO data step. │ ├─ the Gate? │ rotate domain DNS → a pre-staged standby edge ──▶ destroy old ──▶ rebuild │ └─ the Vault (stateful)? sever peer + VERIFY a current age-encrypted backup exists FIRST ──▶ rebuild ──▶ ansible ──▶ CI deploy backend ──▶ restore DB from age dump │ ▼ update inventory: new onion, new WG key; old keys revoked ──▶ live again- The Face is the easy case. It is stateless, so a burn is a pure rebuild: no backup, no restore, no data risk.
- The Vault is the careful case. It holds the only copy of live data, so its burn
path always verifies a current
agebackup before teardown and restores on rebuild. This is why the data sits on the long-lived Vault and not on a burnable VPS. - Severing is instant: remove a node’s WireGuard public key from Gerbil and its only ingress is cut before teardown even begins.
Domain rotation
Section titled “Domain rotation”- Keep multiple domains across multiple XMR-friendly registrars, pre-registered and parked.
- DNS-as-code: a small playbook updates the active zone’s
A/AAAA(and the ACME DNS-01 TXT) to point at the current Gate. Keep TTLs low so changes propagate fast. - Rotate by standing up (or reusing) a Gate, issuing certs for the active domain via DNS-01, flipping DNS, and optionally announcing the new address out of band.
- The Face and the Vault have no DNS at all, so rotating the public domain never touches them. It is purely a Gate concern.
Secrets
Section titled “Secrets”| Secret | Lives where | Rotated |
|---|---|---|
| SSH keys (per node) | offline keystore + sops vault | per burn |
| WireGuard keys | sops vault, deployed by Ansible | per burn / per node add |
| Tor onion keys | sops vault (if persistent) or ephemeral | per policy (default ephemeral for SSH) |
| DB credentials | sops vault → injected as env at deploy | on rebuild |
| DNS API token | sops vault → Gate only | on domain rotation |
| Registry / CI deploy keys | CI secret store (scoped) | periodically |
Backup age key |
offline only, never on any node | rarely, with great care |
| cosign signing key | CI secret store; public key in the repo | periodically |
The rule: no node holds a secret it doesn’t currently need, and no secret survives a burn unless it must (the offline backup key is the one that must).
Monitoring
Section titled “Monitoring”- Local-only metrics: a light node-exporter/cAdvisor scraped by a Prometheus on the Gate over the WG net, its dashboard behind an onion. No monitoring SaaS: it would leak both your existence and your identity.
- Health checks: container healthchecks plus a synthetic “can the client reach the backend reach the DB” probe, surfaced to CI for deploy gating.
- Alerting: pushed to a channel you control over Tor (a self-hosted ntfy on an onion, or a Matrix account reached via Tor). No SMS, no email-to-phone gateways.
- Never collected: user IPs, user agents tied to accounts, geolocation, third-party analytics.
Cold start
Section titled “Cold start”- Identities & funds: create anonymous mailboxes; acquire XMR.
- Self-hosted Git + CI: order the first VPS with XMR; Ansible installs Forgejo +
Woodpecker behind a Tor onion; push the
crimson-nightshaderepo. - The Gate:
ansible site.yml -l edge→ Pangolin + Traefik + Gerbil + onion-SSH + LUKS. - Domain: register at an XMR-friendly registrar; wire the DNS-01 token into the Gate; issue certs.
- The Vault: install Newt;
ansible site.yml -l home→crimson-backend+ PostgreSQL + Valkey, LUKS, onion-SSH; publish asapi.<domain>. Confirm the firstagedump lands in object storage. - The Face: order a VPS with XMR;
ansible site.yml -l app→ Newt dials out, Docker- the client compose skeleton + the CI deploy key. Publish as
stream.<domain>.
- the client compose skeleton + the CI deploy key. Publish as
- The pipeline: push client code → CI builds, signs and deploys
crimson-clientto the Face over the tunnel; the separate backend pipeline deploys to the Vault. - Verify:
https://stream.<domain>serves the site andhttps://api.<domain>serves accounts;nmapagainst the Face’s and the Vault’s IPs shows everything filtered/closed; SSH answers only via onion. - Backups: confirm the Vault’s
agedump is present; run a restore drill. - Burn drills: destroy the Face and rebuild it from code (it should come back green with no data step); then rebuild the Vault and restore the DB. Only then is the setup done.
Trade-offs
Section titled “Trade-offs”| Decision | Why | Cost |
|---|---|---|
| Single Gate ingress (Pangolin) | One small declarative public surface; the other nodes are invisible | The Gate is a single point of failure; soften it with a pre-staged standby + fast domain rotation |
| Outbound-only tunnels (Newt) | The Face and the Vault need zero inbound ports | A few more moving parts than raw WireGuard |
| Tor for all administration | Removes the clearnet management plane entirely | Higher admin latency |
| No CDN / no Cloudflare | No extra KYC’d party; you own the TLS | You absorb DDoS risk at the Gate (lean on provider protection + rate limits) |
| Disposable, code-defined nodes | Burning beats forensics | Demands disciplined IaC + backups |
| Ephemeral onions per rebuild | Maximum unlinkability | You must redistribute admin addresses |
| Data on the Vault, client on a burnable Face | The only data-bearing box is the long-lived one you physically control; the public face is stateless and burnable | The Vault must be reliable and well backed up; it’s the one node you can’t treat as cattle |
Summary
Section titled “Summary”| Node | State | Public ports | Tunnel | Runs | SSH | Disk | Disposable? |
|---|---|---|---|---|---|---|---|
Gate (edge) |
stateless | 80, 443, 51820/udp |
Gerbil/WG server | Pangolin, Traefik | onion only | LUKS2 | yes (standby + DNS flip) |
Face (app) |
stateless | none | Newt → Gate (outbound) | crimson-client (static) |
onion only | LUKS2 | yes: pure CI rebuild, no restore |
Vault (home) |
stateful | none | Newt → Gate (outbound) | crimson-backend + PostgreSQL |
onion only | LUKS2 | no: rebuild + DB restore; the data node |
