Back to skill

Security audit

Healthy Backup

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent backup skill, but it can include raw sensitive OpenClaw configuration in default backups despite promising that sensitive config is scrubbed.

Review carefully before installing. Use only after fixing or accepting the raw openclaw.json backup issue, because default migratable/full backups may contain unredacted OpenClaw configuration even though the documentation says it is scrubbed. Keep rclone sync disabled unless you trust the remote, leave crontab and npm collection off unless needed, and rotate any credentials that may already have been stored in affected backups.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
healthy-backup.sh:58
Finding

Raw OpenClaw Configuration Is Included in Migratable and Full Backups

Content
View full analysis

Vulnerability Details

File Location: healthy-backup.sh:58-62, 188-193, 222-230
Vulnerability Type: Sensitive data exposure caused by incomplete backup exclusions
Risk Level: High

Vulnerable Code:

bash
EX=(--exclude=shared/secrets/ --exclude=credentials/
    --exclude='*.key' --exclude='*.pem' --exclude='*.env'
    --exclude='*.secret' --exclude='.env'
    --exclude='.git/' --exclude='node_modules/' --exclude='BACKUPS/')
bash
sync_dir() {
    local s="$1" d="$STAGING/$2"
    shift 2
    mkdir -p "$d"
    rsync -a "${EX[@]}" "$@" "$s/" "$d/"
}

stage_config() {
    mkdir -p "$STAGING/config"
    jq 'walk(if type=="object" then with_entries(
        if (.key|test("password|token|secret|key";"i")) then .value="<redacted>" else . end) else . end
    )' "$OC_CFG" > "$STAGING/config/openclaw.json"
    ok "openclaw.json (scrubbed)"
}
bash
case "$TIER" in
    migratable)
        stage_config
        sync_dir "$OC" openclaw --exclude='logs/' --exclude='media/' --exclude='browser/'
        ok "~/.openclaw"; stage_deps ;;
    full)
        stage_config
        sync_dir "$OC" openclaw --exclude='logs/' --exclude='media/' --exclude='browser/'
        ok "~/.openclaw"; stage_deps
        [ -d "$WORKSPACE" ] && { sync_dir "$WORKSPACE" workspace --exclude='canvas/'; ok "workspace"; } || warn "workspace not found"
        [ -d "$SKILLS" ]    && { sync_dir "$SKILLS" skills --exclude='.venv/'; ok "skills"; } || warn "skills not found" ;;
esac

Technical Analysis

stage_config correctly creates a scrubbed copy at config/openclaw.json. However, the migratable and full tiers then recursively synchronize the entire ~/.openclaw directory into openclaw/.

The exclusion list removes credential directories and selected filename patterns, but it does not exclude the root-level openclaw.json. Consequently, the archive can contain both:

  • `config/op ...[truncated 1772 chars]
Remediation
View remediation

Remediation Suggestions

  1. Explicitly exclude the source configuration when synchronizing ~/.openclaw:
    bash
    sync_dir "$OC" openclaw \
        --exclude='/openclaw.json' \
        --exclude='logs/' \
        --exclude='media/' \
        --exclude='browser/'
    
  2. Keep only the scrubbed config/openclaw.json in the archive.
  3. Apply the exclusion as a source-root-relative rule so similarly named nested files are not unintentionally affected.
  4. Add automated tests for every backup tier that decrypt the resulting archive and assert:
    • No openclaw/openclaw.json exists.
    • Exactly one intended scrubbed configuration copy exists.
    • Known test secrets do not appear anywhere in extracted archive content.
  5. Treat backups created by affected versions as potentially containing raw credentials. Rotate sensitive credentials and securely delete or replace affected local and remote archives.
  6. Update release checksums and documentation after publishing the corrected script.

T09 · Insecure Skill Coding Practices

Warning
Location
healthy-backup.sh:210
Finding

Incomplete Crontab Redaction Can Leak Credentials into Backups

Content
View full analysis

Vulnerability Details

File Location: healthy-backup.sh:210-213
Vulnerability Type: Inadequate sanitization of sensitive command data
Risk Level: Medium

Vulnerable Code:

bash
echo; echo "## Cron (values redacted)"
[ "$C_CRON" = "true" ] && crontab -l 2>/dev/null \
    | sed 's/\([A-Za-z_][A-Za-z0-9_]*\)=[^ ]*/\1=<REDACTED>/g' \
    || echo "(opt-in off)"

Technical Analysis

The sanitization expression only recognizes text shaped like an unquoted NAME=value token and consumes characters until the next space. It is not a general secret detector and cannot safely sanitize arbitrary shell commands stored in a crontab.

Sensitive information can remain visible when represented as:

  • Positional command arguments
  • HTTP authorization headers
  • URL query parameters
  • Quoted values containing spaces
  • Tokens without a preceding variable assignment
  • Credentials embedded in URLs
  • Arguments passed through shell commands or scripts

For example, a cron entry such as the following is not adequately redacted:

cron
0 * * * * curl -H "Authorization: Bearer sensitive-token" https://example.invalid/task

The complete command is written to DEPENDENCIES.md, then included in the encrypted backup and potentially synchronized to a configured rclone destination.

Crontab collection is explicitly opt-in and disabled by default, which reduces likelihood. Nevertheless, the interface and documentation characterize the collected crontab as sanitized, potentially causing users to rely on a protection that is incomplete.

Attack Path

  1. The user's crontab contains an API token, password, authorization header, signed URL, or another secret outside an unquoted NAME=value pattern.
  2. During setup, the user enables sanitized crontab collection.
  3. The backup script executes crontab -l.
  4. The sed expression fails to identify the sensitive argument or only partially redacts it.

...[truncated 736 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not archive complete cron command strings. Prefer collecting only non-sensitive metadata such as:
    • Schedule expressions
    • Whether entries are enabled
    • Executable basenames or user-approved labels
  2. If commands must be collected, require explicit review and confirmation of the exact generated manifest before staging it.
  3. Clearly state that automatic redaction cannot guarantee removal of secrets from arbitrary shell syntax.
  4. Consider replacing command text with a stable hash so users can compare configurations without storing the commands.
  5. Add tests covering authorization headers, signed URLs, positional tokens, quoted assignments, escaped characters, and shell pipelines.
  6. Advise affected users to rotate any credentials stored in collected crontabs and replace previously generated archives.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (41)

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · CHANGELOG.md (reported line 133)May include surrounding context.

md
tegrity, key directories, disk space, encryption readiness, secrets file permissions, cloud remote (if rclone), Ollama models
- Three backup tiers: `minimal` (openclaw.json + secrets manifest), `migratable` (+ full `~/.openclaw` + `DEPENDENCIES.md`), `full` (+ workspace + skills)
- `DEPENDENCIES.md` generated at migratable/full tiers: binary versions, OS info, optional npm globals, ollama models, crontab
- AES256 GPG symmetric encryption
- Retention: keeps last N healthy backups (default 5), prunes older archives automatically
- Optional rclone cloud sync
- Config resolution hierarchy: skill config → env var → auto-detect
- Health report (`HEALTH_REPORT.txt`) embedded in every archive
- Inspired by **simple-backup** (VACInc) and **claw-backup** (vidarbrekke)

---

## [1.3.0] — compaction & verify merge

### Changed
- `verify-backup.sh` eliminated — merged into `healthy-backup.sh` as `--verify [path]` subcommand. Now just 2 scripts total.
- `healthy-backup.sh`: 384 → 259 lines

Credential Access

High
Category
Privilege Escalation
Confidence
71% confidence
Finding

The skill intentionally reads a secrets file and derives a manifest of environment variable names. Although values are not copied, secret names can still disclose integrations, internal systems, auth schemes, or high-value targets, so this is credential-adjacent data exposure rather than direct secret theft.

Content

Scanner excerpt · SKILL.md (reported line 50)May include surrounding context.

md
### Secrets manifest

At all tiers the script reads `openclaw-secrets.env` to extract variable *names* only — values are never written. The resulting `secrets-manifest.txt` lists what environment variables your rig expects, useful for rebuilding on a new machine.

### GPG passphrase

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The documented runtime behavior reads both the secrets env file and the backup key from disk. Accessing credentials is necessary for a backup tool, but it remains a sensitive capability: compromise of the script or its execution environment would expose encryption material and secret inventory.

Content

Scanner excerpt · SKILL.md (reported line 65)May include surrounding context.

md
| What | Why | Sensitive? |
|------|-----|-----------|
| `~/.openclaw/openclaw.json` | Load config + stage (scrubbed copy) | Sensitive fields redacted before staging |
| `~/.openclaw/shared/secrets/openclaw-secrets.env` | Extract variable *names* for manifest | Values never written; file never copied |
| `~/.openclaw/credentials/backup.key` | Load encryption password | Read into memory only; file excluded from rsync |
| `~/.openclaw/` (migratable+) | rsync to staging | Secrets paths hard-excluded |
| Workspace + skills dirs (full tier) | rsync to staging | Secrets paths hard-excluded |

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · SKILL.md (reported line 73)May include surrounding context.

md
l tier) | rsync to staging | Secrets paths hard-excluded |
| `command -v <bin>` | Check required binaries exist | No |
| `df -m $HOME` | Check available disk space | No |
| `ollama list` (audit + opt-in manifest) | Check models loaded / list for DEPENDENCIES.md | Model names only |
| `npm list -g` (opt-in, default off) | List global packages for DEPENDENCIES.md | Can reveal installed tooling |
| `crontab -l` (opt-in, default off) | List cron jobs for DEPENDENCIES.md | VAR=values redacted before writing |
| `rclone listremotes` (if uploadMode=rclone) | Verify configured remote exists | No |
| `rclone sync` (if uploadMode=rclone) | Upload encrypted archives | Transfers only `*.gpg` files |

No network calls are made by the script itself beyond `rclone` when explicitly configured.

---

| Tier | What's included |
|------|----------------|
| `minimal` | `openclaw.json` + secrets manifest (key names only) |
| `migratable` | Everything in minimal + `~/.openclaw` (secrets excluded) + `DEPENDE

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 45)May include surrounding context.

md
#
# Secrets policy:
#   openclaw.json staged with sensitive field values SCRUBBED (jq walk)
#   shared/secrets/ credentials/ *.key *.pem *.env *.secret never rsynced
#   secrets-manifest: key names only — values never written
#   GPG passphrase: chmod-600 temp file, never on CLI, deleted on EXIT
set -euo pipefail

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · healthy-backup.sh (reported line 10)May include surrounding context.

sh
#
# Secrets policy:
#   openclaw.json staged with sensitive field values SCRUBBED (jq walk)
#   shared/secrets/ credentials/ *.key *.pem *.env *.secret never rsynced
#   secrets-manifest: key names only — values never written
#   GPG passphrase: chmod-600 temp file, never on CLI, deleted on EXIT
set -euo pipefail

Chaining Abuse

High
Category
Tool Misuse
Confidence
81% confidence
Finding

The cleanup trap performs 'rm -rf' on variables that are initialized as empty strings and later populated dynamically. Quoting prevents word-splitting, but if either path variable is corrupted, points somewhere unintended, or is attacker-influenced through environment/config interactions or future code changes, the trap can recursively delete arbitrary directories on exit. In a backup utility handling filesystem paths and temp dirs, destructive cleanup logic deserves extra scrutiny.

Content

Scanner excerpt · healthy-backup.sh (reported line 31)May include surrounding context.

sh
# ── Cleanup ───────────────────────────────────────────────────────────────────
STAGING="" ARCHDIR="" PF=""
cleanup() { rm -rf "$STAGING" "$ARCHDIR"; [ -f "$PF" ] && rm -f "$PF"; }
trap cleanup EXIT

# ── Config ────────────────────────────────────────────────────────────────────

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 286)May include surrounding context.

md
C_NPM=$(cfg  collectNpm     COLLECT_NPM     "false")
C_CRON=$(cfg collectCrontab COLLECT_CRONTAB "false")
C_OLL=$(cfg  collectOllama  COLLECT_OLLAMA  "true")
SECRETS="$OC/shared/secrets/openclaw-secrets.env"

PW="${BACKUP_PASSWORD:-$(cfg password BACKUP_PASSWORD "")}"
KF="$OC/credentials/backup.key"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · healthy-backup.sh (reported line 52)May include surrounding context.

sh
C_NPM=$(cfg  collectNpm     COLLECT_NPM     "false")
C_CRON=$(cfg collectCrontab COLLECT_CRONTAB "false")
C_OLL=$(cfg  collectOllama  COLLECT_OLLAMA  "true")
SECRETS="$OC/shared/secrets/openclaw-secrets.env"

PW="${BACKUP_PASSWORD:-$(cfg password BACKUP_PASSWORD "")}"
KF="$OC/credentials/backup.key"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · healthy-backup.sh (reported line 59)May include surrounding context.

sh
[ -z "$PW" ] && [ -f "$KF" ] && PW=$(tr -d '\n' < "$KF")

EX=(--exclude=shared/secrets/ --exclude=credentials/
    --exclude='*.key' --exclude='*.pem' --exclude='*.env'
    --exclude='*.secret' --exclude='.env'
    --exclude='.git/' --exclude='node_modules/' --exclude='BACKUPS/')

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · healthy-backup.sh (reported line 60)May include surrounding context.

sh
[ -z "$PW" ] && [ -f "$KF" ] && PW=$(tr -d '\n' < "$KF")

EX=(--exclude=shared/secrets/ --exclude=credentials/
    --exclude='*.key' --exclude='*.pem' --exclude='*.env'
    --exclude='*.secret' --exclude='.env'
    --exclude='.git/' --exclude='node_modules/' --exclude='BACKUPS/')

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · CHANGELOG.md (reported line 18)May include surrounding context.

md
- Cron default changed from `y` to `n` — explicit opt-in required.

### Changed
- Setup flow restructured into 5 explicit phases: Questions → Write config → Install cron → Dry run → Summary.
- Cron recommended time updated to 03:15 (after Total Recall dream cycle at 03:00).
- Summary always shown regardless of dry-run outcome.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents shell execution and installation/cron operations, but it declares no explicit tool scope such as allowed shell usage. This creates a governance gap: an agent or platform cannot enforce least privilege or clearly warn users that the skill requires command execution and filesystem access.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · CHANGELOG.md (reported line 115)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 36)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 145)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 285)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 286)May include surrounding context.

md
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · healthy-backup.sh (reported line 96)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · healthy-backup.sh (reported line 127)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · healthy-backup.sh (reported line 177)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 96)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 100)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.sh (reported line 106)May include surrounding context.

sh
`openclaw.json` is **never copied verbatim**. Before staging, the script uses `jq walk()` to replace the *value* of any field whose name contains `password`, `token`, `secret`, or `key` with `"<redacted>"`. Config structure and all non-sensitive values are preserved. The live file on disk is never modified.

> **Recommendation:** store your backup password in `~/.openclaw/credentials/backup.key` (chmod 600) rather than inline in `openclaw.json`. The health audit will warn if an inline password is detected.

### rsync exclusions — always applied, no config override