Releases: kastelldev/kastell
Releases · kastelldev/kastell
v1.17.1
v1.17.1 — Security Hardening
28 defence-in-depth fixes from 5-skill security audit.
Security
- sshExec type narrowing — accepts SshCommand only, 33 callers wrapped with raw()
- SAFE_MODE typo-safe — accepts "yes"/"1"/"on", warns on unrecognized values
- sanitizedEnv() expanded — 10 secret patterns (up from 4)
- Rollback SHA256 integrity — checksum verified before restore script execution
- MCP error sanitization — all 12 tool handlers route through sanitizeStderr
- Path traversal guard — relPath allowlist regex in rollback
- backupPath Zod regex — format validation prevents injection via tampered history
- SHELL_METACHAR — added & to block && on fallback path
- sedReplace path quoting — POSIX single-quote escape
- DEBIAN_FRONTEND scope — both apt-get commands covered
Changed
- scheduleManager: execSync replaced with spawnSync + DRY helper
- encryption.ts: execSync replaced with spawnSync array args
- Production deps: all 11 pinned to exact versions
- isSafeMode() extracted to src/utils/safeMode.ts
- Platform fallback: "coolify" changed to "bare" (least privileged)
- cmd("") throws, timeoutMs=0 guard, ControlMaster 0o700
- debugLog redaction, getServers() hardened, warnIfPermissionError helper
Full Changelog: v1.17.0...v1.17.1
v1.17.0
v1.17.0 — Fix Advanced + Doctor Integration
Added
- Bulk rollback —
kastell fix --rollback-alland--rollback-to <fix-id>for batch fix reversal - Doctor auto-fix —
kastell doctor --auto-fixdiagnose-then-fix pipeline with--dry-runand--forceoptions - Fix scheduling —
kastell schedule fix|auditinstalls local cron for automated fix/audit runs - SSH ControlMaster — connection multiplexing prevents sshd MaxStartups exhaustion during bulk operations
- Interactive menu full CLI parity — all CLI flags now accessible from interactive menu (schedule, audit extras, fix extras, fleet/doctor/evidence/backup options)
- WAF bot detection checks — NGX-WAF-BOT-DETECT and NGX-WAF-CHALLENGE-MODE audit checks
- Custom fix profiles — user-defined profiles from
~/.kastell/profiles/ --no-interactiveflag for automated fix runs
Fixed
- SSH lockout prevention — NET-HOSTS-DENY moved to GUARDED tier
- Sysctl SSH breakage — all sysctl fixes promoted to GUARDED with SSH probe + rollback
- Session-terminating commands — restart/halt promoted to GUARDED tier
- MCP SAFE_MODE guards — serverLock/Guard/Secure enforce isSafeMode()
- SSH ControlMaster Windows — socket path, stale cleanup, fork detection
Changed
- TOCTOU elimination, KASTELL_DIR consolidation, severityChalk utility
- 9,871 tests across 219 suites (up from 9,611 / 215)
Security
- Tier promotion system — dangerous fixes auto-promoted SAFE to GUARDED
- MCP fail-closed SAFE_MODE default
Full Changelog: v1.16.0...v1.17.0
v1.16.0
Added
- AES-256-GCM token encryption — tokens.json and notify-secrets.json encrypted at rest when OS keychain is unavailable. Per-installation random salt, cross-platform machine key derivation (Linux/macOS/Windows), transparent plaintext auto-migration
- Fix rollback & history —
kastell fix --rollback <id>restores from backup,kastell fix --historyshows fix log - Fix prioritization —
kastell fix --top Napplies highest-impact fixes,kastell fix --target 80fixes until score reaches target - Programmatic fix handlers — 4 dedicated handlers (sysctl, file-append, package-install, chmod/chown) replace shell redirect/pipe for SAFE tier fixes
- Fix profiles —
kastell fix --profile web-server|database|mail-serverapplies server-type-specific fix sets - Fix diff preview —
kastell fix --diffshows per-fix before/after changes - Fix report —
kastell fix --reportgenerates markdown fix report with score change and compliance info - WAF audit deep checks — 5 new WAF pipeline checks (IP ACL, rate limiting, input sanitization, bot detection headers, data masking) expanding nginx category to 14 checks
- Dependabot config —
.github/dependabot.ymlfor automated GitHub Actions SHA updates - 10 project-specific security audit custom checks (SSH injection, SAFE_MODE bypass, token leak, MCP validation, subprocess env, SSH host key, API sanitization, error disclosure, npm lifecycle)
Fixed
- getServers() fail-closed — corrupt servers.json now throws instead of silently returning empty array
- fileAppend handler shell injection — single-quote escape via shellEscape() on forward path (rollback already escaped)
- Encryption key hardening — per-installation random salt replaces hardcoded "kastell-v1", persistent random UUID fallback replaces low-entropy hostname
Security
- All 13 GitHub Actions references SHA-pinned across 5 workflow files (zero floating tags)
- SECFIX-01 through SECFIX-09 addressed: token encryption, supply chain hardening, fail-closed config, 5 already-closed findings verified
- Security audit: 29 findings (down from 39), 0 critical, 1 high (deferred to v2.0 by design)
/reviewskill added to release security gate
Changed
- Test count: 5,522 → 9,611 (4,089 new tests including 3,623 mutation killers)
- Test suites: 207 → 215
- Test helpers: 4 → 5 factory files (encryption-factories.ts added)
- Mutation score: 44.65% → 59.06% nominal / 78.6% effective (Dalga 1-3 complete)
v1.15.1
Added
kastell changelogcommand — Parse and display CHANGELOG.md in terminal (kastell changelog,kastell changelog v1.14.0,kastell changelog --all)- "Why Kastell?" manifesto in README (EN + TR) — problem statement, approach, AI-native positioning
- Kastell vs Alternatives comparison table in README (EN + TR) — Kastell vs Lynis vs OpenSCAP across 12 dimensions
- Zero Telemetry badge in README (EN + TR) — trust signal, no data collection
- CI profile stats dispatch —
.githuborg profile auto-updates on every main push (test/check/category/MCP counts) - Interactive menu: "View changelog" entry in Configuration section
- CHANGELOG.md included in npm package files
Fixed
- sshExec SSH banner handling — servers with login banners caused non-zero exit codes on Windows, breaking health checks, audit scores (42→11 false drop), and doctor cache writes. Now checks stdout content when stderr is banner-only
- 3 incorrect fix commands —
grub2-mkpasswd-pbkdf2→grub-mkpasswd-pbkdf2(Ubuntu),dc3dd→sleuthkit(available in repos),vector→rsyslog(no 3rd party repo needed) - Backup fix command —
kastell backup create(local CLI, not available on server) → server-sidetarcommand - audit-watch test timeout — Windows CI fake timer slowness (jest.setTimeout 15s + extra microtick flushes)
- CI dispatch format — JSON body for repository_dispatch (was form-encoded)
Security
- 10 security audit remediation items applied: SHELL_METACHAR validation, bot middleware fail-closed, clearKnownHostKey IP validation, sendTelegram token validation, unhandled rejection handler, npm publish --provenance, staging token scope, debugLog→KASTELL_DEBUG
- Security audit report:
security-audit-report.md(39 findings, 0 critical)
Changed
- Test count: 5,506 → 5,522 (16 new tests: 4 SSH banner + 12 changelog)
- Test suites: 206 → 207
v1.15.0 — Web Security + Auto-Fix + Telegram
What's New
Added
- Edge & WAF Audit (P88): 9 Nginx config checks + WAF detection, 30th audit category
- TCP Stack DDoS Hardening (P89): 8 sysctl DDoS parameter checks, 31st audit category
- kastell fix --safe (P90): SAFE/GUARDED/FORBIDDEN tier classification, mandatory backup, dry-run
- MCP server_fix (P91): 14th MCP tool with dryRun:true default, SAFE_MODE guard
- Telegram Bot Notifications (P92): Guard audit score monitoring, two-tier alerts
- Telegram Bot Commands (P93): grammy bot with /status, /audit, /health, /doctor, /help
kastell bot startcommand for foreground Telegram bot- Interactive menu: Telegram bot entry
Changed
- Audit categories: 29 → 31 (WAF & Reverse Proxy, DDoS Hardening)
- Audit checks: 413 → 442
- Tests: 5,468 → 5,499 (31 new bot module tests)
Security
- Bot allowedChatIds middleware silently blocks unauthorized users
- server_fix FORBIDDEN rejection blocks SSH/Firewall/Docker category fixes via MCP
- Fix tier classification: SSH/Firewall changes always FORBIDDEN
Full Changelog: v1.14.0...v1.15.0
v1.14.0
Added
- Snapshot Restore —
kastell snapshot restoreCLI + MCPsnapshot-restoreaction with SAFE_MODE guard, double confirmation, and 4-provider support (Hetzner, DigitalOcean, Vultr, Linode) - Cloud ID Lookup —
findServerByIp()across all 4 providers;kastell addnow displays Cloud ID automatically - TLS Hardening Audit — 8 checks (min version, weak ciphers, HSTS with max-age validation, OCSP stapling, cert expiry, DH params, compression, cert chain) with PCI-DSS/CIS/HIPAA compliance mappings
- HTTP Security Headers Audit — 6 checks (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, CORS wildcard, CSP) with PCI-DSS v4.0 mappings
- Lock Score Boost — 4 new lock steps (SSH fine-tuning with 15 directives, login.defs hardening, pam_faillock, sudo logging/requiretty) + 2 extended steps (banners +/etc/motd, cronAccess +at.allow); 24-step orchestrator
- Interactive menu — Added snapshot restore, audit --explain/--diff/--fix, doctor --fix options
- Stryker Mutation Testing — Baseline 40.74% across 19,726 mutants
Fixed
- Lock-audit alignment — 5 misalignments fixed (AIDE cron path, auditd restart, logrotate install+timer, cronAccess step, Docker mkdir)
- snapshotId MCP validation — Added regex validation for defense-in-depth
- CERT_NOT_FOUND sentinel — Properly emits when certificate file is missing instead of false CERT_EXPIRING_SOON
- HTTPS-only audit gap — HTTP header audit now tries HTTPS before HTTP for HTTPS-only servers
- CLI snapshotCreate SAFE_MODE — Added guard for consistency with MCP handler
- Vultr/Linode snapshotId validation — Added
assertValidServerIdfor defense-in-depth - Hetzner findServerByIp pagination — Changed
per_pagefrom 50 to 100 for consistency - Faillock idempotency — Each directive independently checked/updated instead of batch
- fileLock ENOENT — Ensure parent directory exists before creating lock file
Changed
- Test suite — 4178→5087 tests (909 new), 197 suites, 11 snapshots; branch coverage: global 93.25%, audit 95.96%, providers 91.22%, MCP 90.25%
- Audit categories — 27→29 (TLS Hardening + HTTP Security Headers); 421+ total checks
- CI hardening — Codecov integration, 4 typed test factory helpers, zero
as anycasts (231→0) - CI release gate —
release.ymlnow depends on CI success viaworkflow_run(prevents releasing when CI fails) - CI tag support — CI workflow now runs on tag pushes for release/publish chain
- TLS weak cipher detection — Added SEED and IDEA to pattern
- HSTS validation — Now checks max-age >= 31536000
- Compliance mappings — Added HIPAA for TLS, updated PCI-DSS HDR-005 to v4.0 (6.2.4)
- Skill consolidation — 5 global security skills delegated to single
kastell-security-check.md
Removed
- Stryker from CI — Mutation testing removed from GitHub Actions (exceeds 6h limit); moved to dedicated infrastructure with scheduled nightly incremental runs
Security
- Comprehensive v1.14 review — 5-agent parallel audit (OWASP, token/secret, audit system, code quality, test coverage); 13 findings resolved (3 MEDIUM + 10 LOW)
- Release workflow injection fix — Prevented shell injection via
head_branchinterpolation; added strict semver validation before checkout - Zero token leakage — 5-layer sanitization verified across all new code paths
v1.13.0
Added
- Claude Code Plugin —
kastell-plugin/marketplace-ready package withplugin.jsonmanifest,.mcp.json, andhooks.json - 4 Skills —
kastell-ops(background server management),kastell-research(Explore agent + architecture map),kastell-careful(skill-scoped LLM prompt hook),kastell-scaffold(4 fork-friendly templates) - 2 Agents —
kastell-auditor(security review) andkastell-fixer(bug diagnosis) project-scope agents - 5 Hooks —
session-log,stop-quality-check,session-audit,pre-commit-audit-guard,destroy-blockwith ESM-compatible.cjsscripts - MCP Discoverability —
server.instructions, MCP Logging,llms.txt,SUBMISSIONS.md, 4 platform setup guides,mcp-serverkeyword - Dynamic Content Injection —
!commandsyntax in 4 skill files for live codebase context
Fixed
- CLI↔MCP parity — 3 bugs fixed: logs default service (Dokploy), health host-key-mismatch detection, maintain update validation
- DO Coolify SSH key loss — Re-inject SSH public key after platform installer in cloud-init
- Docker crash after lock — SSH host key resolution in MCP health checks
- Plugin hook ESM compatibility — Renamed
.js→.cjsfor ESM project compatibility
Changed
- Commands→Core extraction —
backup,status,updatebusiness logic moved from commands/ to core/ (thin command pattern) - Adapter bypass elimination — 9 commands now use adapter properties (
port,defaultLogService,platformPorts) instead of hardcoded values - Shared
createMockAdapter()— Test mock factory intests/helpers/mockAdapter.ts; deduplicated across all test files - Test coverage — 4156→4178 tests (adapter contract, core extraction, hook tests)
v1.12.0
v1.12.0 — Lock Advanced + Audit Explain
Deep lock hardening (19 steps, 413 audit checks) with audit --explain inline explanations.
Added
audit --explain— Inline "Why:" + fix explanation for each failing check in CLI and MCP- Lock: auditd CIS L2 rules — Deep audit rules (time-change, network-change, kernel-module) in
50-kastell-deep.rules - Lock: sysctl deep tuning — 21 kernel hardening settings (dmesg_restrict, kptr_restrict, bpf_jit_harden, rp_filter, ASLR)
- Lock: pwquality — CIS L1 password policy (minlen=14, complexity classes), non-fatal with graceful skip
- Lock: SSH cipher blacklist — Weak ciphers/MACs/KEX removed with
sshd -tvalidation and automatic rollback - Lock: Docker runtime hardening — daemon.json merge with platform-aware guards and reload-not-restart
- Lock 19-step hardening — Expanded from 16 to 19 steps
- Audit 413 checks — 4 new checks (BPF JIT, audit time/network/module rules)
Fixed
- jq injection prevention (stdin pipe instead of shell interpolation)
- SSH sed tab pattern for cipher/MAC/KEX directives
Install
npm install -g kastell@1.12.0
# or
npx kastell@1.12.0Full changelog: https://github.com/kastelldev/kastell/blob/main/CHANGELOG.md
v1.11.0
What's New in v1.11.0
Added
- MCP tool descriptions — Updated all 13 MCP tools with 27-category routing hints and accurate check counts
- Audit display filter —
audit --filterfor display-only category/severity filtering without re-running SSH - Audit fix score delta — Post-fix score re-audit shows before/after comparison
- Lock 16-step expansion —
server lockexpanded from 5 to 16 hardening steps with grouped CLI output and dry-run preview - Lock step helpers —
runLockStep+ 11 command builders for modular hardening (auditd, sysctl, pwquality, AIDE, etc.) - SSH host key remediation — Proactive
removeStaleHostKeybefore SSH polling + error output with remediation hints
Fixed
- Interactive menu audit filters — Audit sub-menu now correctly passes filter and fix options
- FW-05 passed field — Fixed incorrect variable in firewall IPv6 check
- MCP check count — Corrected inflated 488+ count back to accurate 409
- Audit filter+fix hardening — Shell metacharacter guard, severity validation, structured error logging
- SSH retry error handling — Added
.catch()to SSH retry preventing unhandled rejections
Changed
getErrorMessagereuse — Consolidated error message extraction across modules
Full Changelog: v1.10.1...v1.11.0
v1.10.1
[1.10.1] - 2026-03-17
Added
- sshStream stdin support — SSH batch commands piped via stdin for reliable cross-platform execution
- Audit batch error reporting — Structured error details when audit SSH batches fail
Fixed
- Windows SSH argument escaping — Batch commands now use stdin pipe instead of spawn arguments, fixing truncation on Windows
- Audit sentinel wrappers — Added sentinel markers for 4 categories (accounts, services, boot, scheduling — 24 checks) fixing parser mismatches
- Cloud-init SSH lockout — Fixed DigitalOcean + Coolify SSH lockout caused by ssh.socket/needrestart/UFW ordering
- Interactive menu back navigation — Back option now works correctly in nested sub-menus
- DEBIAN_FRONTEND=noninteractive — Added to Coolify and Dokploy cloud-init scripts preventing apt prompts
- Provision reliability — Orphan cleanup, Vultr boot timeout (135s), SSH hardening safety guards
- Snapshot Zod schema — Added 6 P52 optional fields (vpsIrrelevant, connectionError, vpsType, vpsAdjustedCount, skippedCategories, warnings) preventing silent strip on load
Full Changelog: v1.10.0...v1.10.1