# OpenClaw VPS Hardening Acceptance Contract

Use this contract on a **fresh throwaway Ubuntu 24.04 VPS** before it receives
production credentials or traffic. The checker is a **screening report**, not
final acceptance. It separates automated host checks from the cloud, external
probe, reboot, OpenClaw-audit, and handoff gates that still require an
operator.

- Checker: [openclaw-vps-readiness-check.sh](/openclaw-vps-readiness-check.sh)
- SHA-256: [openclaw-vps-readiness-check.sh.sha256](/openclaw-vps-readiness-check.sh.sha256)
- Checker version: `2.0.0`
- Remote requests made by the checker: none
- Local requests made by the checker: one authenticated loopback RPC readiness
  probe, only after the configured target is proven local
- Configuration changes made by the checker: none
- Hostnames, IP addresses, configuration values, environment values, and
  secret values printed by the checker: none
- Status: a newly built, brand-owned synthetic acceptance asset, not a claim
  about prior customer work
- Boundary: evidence and a repeatable checklist, not a security certification
- Immutable paid-trial matrix:
  [openclaw-vps-hardening-acceptance-matrix-v1.json](/openclaw-vps-hardening-acceptance-matrix-v1.json)
- Matrix contract: `openclaw-vps-hardening-acceptance-matrix/v1`
- Matrix SHA-256:
  `b306dc0a81e8dcea0fba14f266c2d031453ed50b9d540dbe3e6ec6c52efaba48`
- Matrix digest:
  [openclaw-vps-hardening-acceptance-matrix-v1.json.sha256](/openclaw-vps-hardening-acceptance-matrix-v1.json.sha256)

## Freeze the paid-trial acceptance boundary

For a paid fresh-host hardening case, copy the matrix contract and SHA-256 above
into the exact written scope before payment. Freeze the exact versions, selected
SSH abuse-control path, selected health/alert path, selected secret-storage
mechanism, every accepted non-critical warning, every evidence owner, every
pass/fail probe, and every deliverable. Tested provider-console recovery **and**
a usable snapshot or equivalent rollback are both required.

Only a documented customer-controlled loss of required access, information,
approval, or host availability pauses the hardening clock. A third-party outage
does not pause the active clock or void the guarantee. If complete delivery
misses the active deadline, Agent Rescue Desk initiates a refund of exactly
1,000.000000 native USDC on Base Mainnet to the independently verified original
payer within two hours after the missed active deadline, pays the refund gas
without reducing the amount returned, and records the transaction plus
network-finality evidence. A network-finality delay after timely initiation
does not cancel, reduce, or replace that obligation.

## Paid hardening completion and payment contract

Fresh-host hardening payment is exactly 1,000.000000 native USDC on Base
Mainnet only; card payment is unavailable.

Hardening completion requires all five runtime-required deliverables: a
redacted evidence report, a repeatable full runbook, a short screen recording,
an exact version inventory, and the working hardened accepted host. Separate
tested provider-console recovery proof and usable snapshot or equivalent
rollback proof are also required.

## Direct npm install

No npm registry account is required. The measured route records only a bounded
source label, timestamp, and broad browser, crawler, or unknown classification;
it stores no IP address, user-agent string, referrer, email, or package input.
A request is anonymous reach, not proof of an install, lead, buyer, or sale.

```bash
npm install --global 'https://agent-rescue-desk.netlify.app/download/openclaw-vps-readiness-auditor?source=acceptance-markdown'
npm explore --global openclaw-vps-readiness-auditor -- npm run verify
```

- Immutable npm tarball:
  [openclaw-vps-readiness-auditor-2.0.0.tgz](/openclaw-vps-readiness-auditor-2.0.0.tgz)
- Tarball SHA-256:
  [openclaw-vps-readiness-auditor-2.0.0.tgz.sha256](/openclaw-vps-readiness-auditor-2.0.0.tgz.sha256)
- Portable skill ZIP:
  [openclaw-vps-readiness-auditor-v2.0.0.zip](/openclaw-vps-readiness-auditor-v2.0.0.zip)

The previously published `1.0.0` [npm tarball](/openclaw-vps-readiness-auditor-1.0.0.tgz)
and [skill ZIP](/openclaw-vps-readiness-auditor-v1.0.0.zip) remain available
byte-for-byte at their original immutable URLs.

## Inspect, verify, then run

```bash
curl -O https://agent-rescue-desk.netlify.app/openclaw-vps-readiness-check.sh
curl -O https://agent-rescue-desk.netlify.app/openclaw-vps-readiness-check.sh.sha256
sha256sum -c openclaw-vps-readiness-check.sh.sha256
less openclaw-vps-readiness-check.sh

sudo bash openclaw-vps-readiness-check.sh \
  --runtime-user openclaw \
  --openclaw-bin /home/openclaw/.local/bin/openclaw \
  --unit-scope user \
  --unit openclaw-gateway.service \
  --admin-user operator \
  --admin-source 203.0.113.10 \
  --ssh-abuse-control both \
  --health-monitor netdata
```

Substitute the actual dedicated account and user-local paths. Root is required
only to read effective host and service state. Most OpenClaw CLI queries run in
an isolated network namespace. After the checker proves loopback bind,
shared-secret authentication, and no non-loopback remote target, it performs
one local authenticated `gateway status --deep --json --require-rpc` probe.
No hostname, IP, configuration value, or secret is printed. Do not run code
fetched from the internet with `sudo` until you have inspected it.

## Gate 1 — runtime and trust boundary

Pass only when:

1. the host is Ubuntu 24.04;
2. OpenClaw runs as a dedicated non-root account outside `sudo`, `admin`, and
   `wheel`;
3. the explicit OpenClaw binary resolves inside that account's home;
4. the state directory and `openclaw.json` are regular, runtime-owned paths
   with no group or world access;
5. `openclaw config validate --json` and `openclaw secrets audit --check`
   succeed;
6. `gateway.bind` is `loopback` and auth mode is `token` or `password`;
7. no non-loopback remote gateway is configured; and
8. the running gateway passes deep status with required read-scope RPC.

OpenClaw's documented trust model assumes one trusted operator boundary per
gateway. Use separate gateways and preferably separate users or hosts for
mixed or adversarial trust boundaries.

## Gate 2 — SSH and firewall

Pass only when:

1. `sshd -T -C` for the intended admin/source enables public-key
   authentication and disables password, keyboard-interactive, host-based,
   GSSAPI, Kerberos, and empty-password authentication;
2. the corresponding root context disables root login, and SSH uses the
   contract's agreed TCP 22;
3. UFW is active, defaults to deny incoming, and restricts SSH to the declared
   admin source;
4. the buyer-selected SSH abuse-control path is active and queryable;
5. the effective nftables input hook is default-deny;
6. no non-loopback TCP listener exists except an `sshd`-owned port 22; and
7. the VPS-provider firewall separately exposes only the agreed SSH source.

Keep a live recovery session or provider console until a fresh key-only login
succeeds. Verify UDP and provider-private-network exposure separately and run
an external port probe from the agreed source. The checker does not pretend a
local TCP snapshot proves those surfaces.

## Gate 3 — OpenClaw audit

Run these explicitly as the dedicated OpenClaw account:

```bash
openclaw doctor
openclaw security audit
openclaw security audit --deep
openclaw health
```

Resolve every critical finding. Document each intentionally accepted warning
by its `checkId`. The checker deliberately does not run the deep audit because
it probes the live local gateway and deserves an explicit operator action.
`trusted-proxy` is outside this loopback-and-SSH-tunnel contract.

## Gate 4 — systemd and secrets

Pass only when:

1. exactly one declared OpenClaw unit exists across the effective user and
   system managers, and it is active and enabled;
2. a user unit has lingering enabled, or a system unit effectively runs as the
   dedicated account;
3. effective `ExecStart` uses the declared OpenClaw install, launches
   `gateway`, and the active process uses the declared state/config paths;
4. effective service properties include `Restart=always`,
   `RestartPreventExitStatus=78`, nonzero restart/start-limit/timeouts,
   `OOMPolicy=continue`, and `KillMode=control-group`;
5. no secret-shaped value appears in effective `Environment=` or `ExecStart=`;
6. `openclaw secrets audit --check` is clean;
7. any dotenv fallback is a regular, nonsymlink `0600` file with ownership
   appropriate to the unit scope; and
8. local shell-history review confirms no secret value was entered.

Review history locally and record only “clear” or “not clear.” Never copy shell
history or an environment file into a report, ticket, recording, or chat.
Prefer supported OpenClaw SecretRefs. A compatible systemd credential path or a
tightly scoped dotenv is a documented fallback; systemd explicitly does not
treat ordinary environment variables as a secret store.

## Gate 5 — monitoring

Monitoring is buyer-selected, not an OpenClaw platform requirement. Declare
one SSH abuse-control path (`fail2ban`, `crowdsec`, or both) and one
health/alert path (`netdata` or a written custom alternative). A service being
active is only a screen: final acceptance also needs a controlled detection
and enforcement test, alert delivery and ownership, retention, off-host data
disclosure, and reboot recovery. Netdata must remain loopback-only. If CrowdSec
and UFW are combined, document effective rule ordering and enforcement rather
than assuming two active services compose safely.

## Gate 6 — reboot and application readiness

After a controlled reboot, prove the same exact versions, binary, state path,
config path, and systemd unit returned without an interactive shell. Rerun the
screen, then run:

```bash
openclaw gateway status --deep --json --require-rpc
openclaw health --json
openclaw channels status --probe # only when channels are in scope
```

A listening port or active unit is not application readiness. If a channel
probe falls back to config-only output, that gate has not passed.

## Final handoff

Preserve:

1. exact Ubuntu, Node, OpenClaw, and monitoring versions, package integrity,
   and the exact version-pinned install command used before installation;
2. redacted systemd, firewall, listener, audit, health, and reboot evidence;
3. the architecture and trust boundary;
4. disabled automatic update application during acceptance, plus explicit
   backup, upgrade, rollback, credential-rotation, and access-removal steps;
5. a narrated screen recording of the important checks with no secret,
   customer data, public IP, or reusable credential visible; and
6. a completed matrix-v1 gate and evidence inventory.

“Service is running” is not acceptance. A second operator must be able to
identify exposure, reproduce validation, and reverse the change without
guessing.

The checker exits zero only when its automated screen has no failure or
unresolved warning. Even then, its final decision remains `INCOMPLETE` until
every manual gate has redacted evidence.

## Official OpenClaw references

- [Security model and audit](https://docs.openclaw.ai/gateway/security)
- [Security audit check IDs](https://docs.openclaw.ai/gateway/security/audit-checks)
- [Gateway exposure runbook](https://docs.openclaw.ai/gateway/security/exposure-runbook)
- [Linux VPS and systemd guidance](https://docs.openclaw.ai/platforms/linux)
- [Read-only redacted configuration queries](https://docs.openclaw.ai/cli/config)

## Need the fresh host built to this contract?

The [$1,000 OpenClaw VPS hardening trial](/openclaw-vps-hardening-trial?source=openclaw-vps-acceptance)
covers one accepted fresh Ubuntu 24.04 host and the complete five-deliverable
handoff above. Fresh-host hardening payment is exactly 1,000.000000 native USDC
on Base Mainnet only; card payment is unavailable. Its 12-hour clock starts
only after cleared payment, accepted scope frozen to the matrix revision and
SHA-256 above, a fresh host, separate tested provider-console recovery proof
and usable snapshot or equivalent rollback proof, agreed access, and testable
acceptance targets are all in place.
