Skip to content
Back to skills

Sovereign Audit

BSecurity

Produce a single consolidated hardening report for the DSH node. Runs audit.sh, dome-check.sh, and machine-probe.py, parses their outputs, and writes one markdown file listing every passing check, every failure with a specific remediation command, and a top-line verdict (ALL GREEN / N ISSUES). Non-destructive — reads only, no auto-fix.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
developmenttypescriptpythongobashsqlnodedockergitbackendsecurity

Security analysis

B84/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 12, 2026

npx -y skills add garochee33/DSH --skill sovereign-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sovereign Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sovereign Audit
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/garochee33-sovereign-audit/badge)](https://www.skillsdirectory.com/skills/garochee33-sovereign-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sovereign-audit
description: "Produce a single consolidated hardening report for the DSH node. Runs audit.sh, dome-check.sh, and machine-probe.py, parses their outputs, and writes one markdown file listing every passing check, every failure with a specific remediation command, and a top-line verdict (ALL GREEN / N ISSUES). Non-destructive — reads only, no auto-fix."
---

You are producing a single human- and AI-readable report on the DSH node's current hardening posture. The three subcomponent scripts (`audit.sh`, `dome-check.sh`, `machine-probe.py`) each surface their own findings; this skill's job is to merge them into one authoritative view with specific remediation for every gap.

## 1. Run the three probes in order

```bash
cd "$DOME_ROOT"
TS=$(date -u +%Y%m%dT%H%M%SZ)
OUT="logs/sovereign-audit-$TS.md"
mkdir -p logs

# Fresh machine probe first (dome-check depends on it)
.venv/bin/python scripts/machine-probe.py > /tmp/audit-probe.out 2>&1

# Security audit (read-only)
bash scripts/audit.sh > /tmp/audit-audit.out 2>&1

# Full protocol check (may auto-fix screen-lock + DNS; that's intended)
bash scripts/dome-check.sh > /tmp/audit-dome-check.out 2>&1 || true
```

Note: `dome-check.sh` exits non-zero if any protocol fails, which is fine — we want the report, not a hard exit.

## 2. Parse the machine profile

```python
import json, sys
sys.path.insert(0, "$DOME_ROOT")
from agents.core.machine import get_profile, summary_one_liner, security_posture

profile = get_profile()
line = summary_one_liner()
posture = security_posture()
```

Fields you'll quote in the report:

- `summary_one_liner()` → one-line machine identity
- `profile["tier"]` → sovereign/guardian/scout/seed
- `profile["storage"]["filevault"]`
- `profile["security"]` → all the posture flags
- `profile["runtime"]` → Python/Node/Ollama/Docker versions

## 3. Parse the audit output

`audit.sh` emits `✅` / `❌` / `⚠️` lines. Count them and bucket by category:

```python
from pathlib import Path
import re

audit_text = Path("/tmp/audit-audit.out").read_text()
passes = re.findall(r"^✅ (.+)$", audit_text, re.M)
fails  = re.findall(r"^❌ (.+)$", audit_text, re.M)
warns  = re.findall(r"^⚠️  ?(.+)$", audit_text, re.M)
```

## 4. Parse the dome-check output

Same pattern but dome-check also includes auto-fixes:

```python
dc_text = Path("/tmp/audit-dome-check.out").read_text()
dc_passes = re.findall(r"^✅ (.+)$", dc_text, re.M)
dc_fails  = re.findall(r"^❌ (.+)$", dc_text, re.M)
dc_fixed  = re.findall(r"^🔧 (.+)$", dc_text, re.M)
```

Extract the summary counts from the trailing block:

```python
m = re.search(r"Passed:\s+(\d+).*Fixed:\s+(\d+).*Failed:\s+(\d+)", dc_text, re.S)
```

## 5. Build the remediation table

For every failure, attach the exact fix command. The known mappings:

| Failed check | Remediation |
|---|---|
| `Firewall OFF` | `sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on` |
| `Stealth mode OFF` | `sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on` |
| `FileVault OFF` | Manual: System Settings → Privacy & Security → FileVault |
| `SIP disabled` | Manual: reboot into Recovery → `csrutil enable` |
| `Screen lock OFF` | `defaults write com.apple.screensaver askForPassword -int 1 && defaults write com.apple.screensaver askForPasswordDelay -int 0` |
| `No GPG key` | `bash scripts/sovereign-secrets.sh` |
| `pass store not initialized` | `bash scripts/sovereign-secrets.sh` |
| `Git commit signing OFF` | `git config --global commit.gpgsign true` |
| `DNS → <not 127.0.0.1>` | `sudo networksetup -setdnsservers Wi-Fi 127.0.0.1 && sudo brew services start dnscrypt-proxy` |
| `dnscrypt-proxy not running` | `sudo brew services start dnscrypt-proxy` |
| `Python import errors` | `source .venv/bin/activate && pip install -r compute/requirements.txt` |
| `TypeScript errors` | `pnpm install && pnpm typecheck` (review errors) |
| `SQLite DB missing` | `python3 scripts/register-claude.py` |
| `ChromaDB empty` | `python3 scripts/ingest.py` |
| `N uncommitted change(s)` | `git -C "$DOME_ROOT" status` then review & commit |
| `.env NOT in .gitignore` | `echo '.env' >> .gitignore && git add .gitignore && git commit -m 'chore: gitignore .env'` |

For any failure not in this table, return "Manual review — see logs/sovereign-audit-<timestamp>.md"

## 6. Write the report

Structure (emit to `$OUT` which is `logs/sovereign-audit-<timestamp>.md`):

```markdown
# DSH Sovereign Audit — <ISO-8601 timestamp>

## Verdict
<ALL GREEN> | <N ISSUES REQUIRE MANUAL ACTION>

## Node
`<summary_one_liner output>`

Tier: **<tier>**

## Security posture
| Control | State |
|---|---|
| FileVault | ✅ / ❌ |
| SIP | ✅ / ❌ |
| Gatekeeper | ✅ / ❌ |
| Firewall | ✅ / ❌ |
| Private DNS | ✅ / ❌ |
| Secrets backend | ✅ / ❌ |

## Passes
- <count> from audit.sh
- <count> from dome-check.sh

## Failures (if any)
| Check | Source | Fix |
|---|---|---|
| <failure> | audit.sh | <command> |
| <failure> | dome-check | <command> |

## Auto-fixed during this run
- <list from dome-check's 🔧 lines>

## Runtime
- Python: <version>
- Node: <version>
- Ollama: <running? yes/no>
- Docker: <present? yes/no>

## Source outputs
- `/tmp/audit-audit.out` — 100 lines, ended <exit code>
- `/tmp/audit-dome-check.out` — <X> lines, ended <exit code>
- `/tmp/audit-probe.out` — machine-probe summary

## Next action
<one sentence — what the user should do first>
```

Save, print the path, and emit a 2-line summary to stdout for the calling agent:

```
✅ Audit complete: logs/sovereign-audit-<timestamp>.md
<0/N issues>
```

## 7. When the report is used downstream

Other skills may call this skill and parse the first two lines of the markdown:

- Line 1: `# DSH Sovereign Audit — ...`
- Line 2: the verdict paragraph (`ALL GREEN` or `N ISSUES REQUIRE MANUAL ACTION`)

Keep those two lines machine-parseable. Everything else in the report is human prose.

## Non-negotiables

- **Never auto-fix.** This skill is read-only. The remediation column is suggestions; the user or a separate skill runs them.
- **Never exfiltrate the report to a remote address.** The audit contains the node's full security posture — it's sensitive to anyone but the owner.
- **Never skip failed parse cases.** If `dome-check.sh` produced output in an unexpected format, flag it in the report rather than pretending it succeeded.
- **Never commit `logs/sovereign-audit-*.md`.** `logs/*.md` is gitignored; reports accumulate locally and can be hand-archived if useful.
- **Never run this skill in parallel with `sovereign-lockdown`.** Lockdown is writing state; audit is reading state. Sequencing matters.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…