DocsGetting started

Installation

Install the shk CLI with npm, bun, the bundled installer script, Homebrew, or from source.

On this page

shk is distributed as a single CLI binary.

npm

Each tagged CLI release publishes the security-harness-kit package to npm. The installed command is shk:

npm install -g security-harness-kit
shk --version
bash

The npm package is generated by dist from the same release. On install it fetches the matching prebuilt release archive for your platform and exposes the shk command, so it supports the same platforms as the release archives.

For one-off runs without a global install:

npx security-harness-kit scan
bash

bun

The same package works with bun. The package's postinstall script downloads the binary at install time; when bun skips lifecycle scripts, which is its default for packages it does not trust, the shk launcher fetches the matching release archive on the first run instead, so the install still works:

bun add -g security-harness-kit
shk --version
bash

For one-off runs without a global install:

bunx security-harness-kit scan
bash

Install With Script

macOS and Linux releases can be installed with the bundled installer:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk-cli-installer.sh | sh
bash

Windows releases can be installed from PowerShell:

powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk-cli-installer.ps1 | iex"
powershell

-ExecutionPolicy Bypass is scoped to this one PowerShell process, so it avoids common script policy failures without changing the user's machine or profile policy. If you are already in PowerShell, this equivalent form also works:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force; irm https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk-cli-installer.ps1 | iex
powershell

If your organization enforces PowerShell through MachinePolicy or UserPolicy, the script installer may still be blocked. In that case, install with npm or bun instead, or download the .zip archive and verify its checksum by hand (see Download A Release Archive).

The installers are generated by dist and download the latest matching release archive. The shell installer verifies the selected archive against the SHA-256 checksum embedded at release time before installing shk. The generated PowerShell installer does not currently perform checksum verification; Windows users who require verification should verify the .zip archive manually. By default, script installers use the Cargo-style install path ($CARGO_HOME/bin, or ~/.cargo/bin when CARGO_HOME is unset).

Download A Release Archive

Tagged releases publish platform archives, per-archive checksums, installers, a Homebrew formula, maintainer WinGet manifests, and a CycloneDX SBOM:

shk-cli-aarch64-apple-darwin.tar.xz
shk-cli-aarch64-unknown-linux-gnu.tar.xz
shk-cli-x86_64-apple-darwin.tar.xz
shk-cli-x86_64-pc-windows-msvc.zip
shk-cli-x86_64-unknown-linux-gnu.tar.xz
shk-cli-installer.sh
shk-cli-installer.ps1
shk-winget-manifests.zip
shk.rb
shk-cli-npm-package.tar.gz
*-dist-manifest.json
*.sha256
shk-sbom.cdx.json
text

Verify the archive before unpacking:

shasum -a 256 -c shk-cli-x86_64-unknown-linux-gnu.tar.xz.sha256
bash

Each archive contains the shk binary. Tagged releases also generate GitHub artifact attestations for release assets. Verify a downloaded asset with the GitHub CLI:

gh attestation verify shk-cli-x86_64-unknown-linux-gnu.tar.xz \
  --repo Kazuki-tam/security-harness-kit
bash

On Windows, download shk-cli-x86_64-pc-windows-msvc.zip and its .sha256 file, compare Get-FileHash -Algorithm SHA256 against the checksum, unpack shk.exe, and place it in a directory on PATH (the installer default is %USERPROFILE%\.cargo\bin).

Verified Archive Install

For CI or security-sensitive environments, install from a pinned release tag and verify both the checksum and the GitHub artifact attestation before placing the binary on PATH:

version=v0.7.0
target=x86_64-unknown-linux-gnu
asset="shk-cli-${target}.tar.xz"
repo=Kazuki-tam/security-harness-kit

gh release download "$version" -R "$repo" -p "$asset" -p "${asset}.sha256"
shasum -a 256 -c "${asset}.sha256"
gh attestation verify "$asset" -R "$repo"

tmp="$(mktemp -d)"
tar -xJf "$asset" -C "$tmp"
install -m 755 "$tmp/shk-cli-${target}/shk" "$HOME/.cargo/bin/shk"
bash

Replace target with the archive that matches your platform. Avoid latest in CI so builds are reproducible and reviewable. shk ci init github generates a workflow that performs exactly this verified install.

Homebrew

Each tagged CLI release publishes the generated Homebrew formula to the public tap Kazuki-tam/homebrew-tap. Install with:

brew install Kazuki-tam/homebrew-tap/shk
bash

Homebrew drops the homebrew- prefix, so the short form also works:

brew install kazuki-tam/tap/shk
bash

The formula always tracks the latest release. To upgrade later, run brew upgrade shk.

Alternatively, the formula (shk.rb) is attached to each release as an asset and can be installed directly without the tap:

brew install --formula https://github.com/Kazuki-tam/security-harness-kit/releases/latest/download/shk.rb
bash

To install a pinned release this way, replace latest/download with download/<tag> (e.g. download/v0.7.0).

Intel macOS, Apple Silicon macOS, Linux x86_64/aarch64, and Windows x86_64 are supported. Scoop manifests are not published by the current release pipeline.

Desktop App

The desktop app is distributed separately from the CLI. Releases are published from desktop-vX.Y.Z (or combined shk-vX.Y.Z) tags as shk-desktop_* assets on GitHub Releases. Starting with desktop-v0.6.0, macOS builds are Developer ID signed, notarized, and stapled. Windows installers are currently not Authenticode-signed (see Windows SmartScreen below).

See desktop-release.md for maintainer release steps.

Choose an installer

Platform Asset pattern Notes
Linux x86_64 shk-desktop_*_x86_64-unknown-linux-gnu_*.AppImage or *.deb AppImage needs chmod +x
Linux aarch64 shk-desktop_*_aarch64-unknown-linux-gnu_*.AppImage or *.deb Same as above
macOS Intel shk-desktop_*_x86_64-apple-darwin_*.dmg Signed and notarized; drag shk.app to /Applications
macOS Apple Silicon shk-desktop_*_aarch64-apple-darwin_*.dmg Same as above
Windows x86_64 shk-desktop_*_x86_64-pc-windows-msvc_*setup.exe or *.msi Currently unsigned

The desktop-latest release always carries the installers from the newest signed desktop release under version-free names, so these URLs never change:

Platform Stable URL
macOS Apple Silicon https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-aarch64-apple-darwin.dmg
macOS Intel https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-x86_64-apple-darwin.dmg
Windows x86_64 (NSIS) https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-x86_64-pc-windows-msvc-setup.exe
Windows x86_64 (MSI) https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-x86_64-pc-windows-msvc.msi
Linux x86_64 https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-x86_64-unknown-linux-gnu.AppImage or https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-x86_64-unknown-linux-gnu.deb
Linux aarch64 https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-aarch64-unknown-linux-gnu.AppImage or https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-aarch64-unknown-linux-gnu.deb

desktop-latest also carries shk-desktop.sha256sum for the stable names and shk-desktop-latest.json, whose release_tag says which versioned release the stable files currently come from. The files are byte-identical to the shk-desktop_* assets of that release, so its provenance attestation verifies them too.

Verify a stable download:

curl -LO https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop-aarch64-apple-darwin.dmg
curl -LO https://github.com/Kazuki-tam/security-harness-kit/releases/download/desktop-latest/shk-desktop.sha256sum
awk '$2 == "shk-desktop-aarch64-apple-darwin.dmg"' shk-desktop.sha256sum \
  | shasum -a 256 -c -
bash

To pin a specific version instead, download the versioned shk-desktop_* assets and shk-desktop.sha256sum from that tag's release page, for example desktop-v0.7.0.

macOS

Installers from desktop-v0.6.0 onward are Developer ID signed and notarized; Gatekeeper opens them without workarounds. If you still run an older unsigned early access build, replace it with a signed .dmg install — the in-app updater also migrates existing installs because all releases share the same Tauri updater signing keys.

Windows SmartScreen

Windows installers are currently not Authenticode-signed, so SmartScreen may show Windows protected your PC. Choose More info → Run anyway if you trust the release checksum and attestation.

Blocked-activity notifications

While the app is open it tails .shk/audit.log for every project in the sidebar and raises an OS notification when a hook blocks AI activity, so an agent running in the background is visible without switching to the app. The bell menu in the top bar turns notifications off, or narrows them to one kind of block; both kinds are on by default.

Details worth knowing:

  • Only blocks recorded after a project appears in the sidebar are announced — existing history never produces a backlog of notifications.
  • Blocks arriving within a few seconds collapse into a single notification.
  • Notification text is limited to the block reason, the risky-action category, and the AI tool. File paths are deliberately left out, because notifications render on the lock screen and are persisted by the OS; use the Blocked AI activity panel to see them.
  • Turning notifications off stops the banners, not the tailing: the audit panel still updates while the app is open.
  • The first block prompts for OS notification permission (on macOS the installed app appears as shk; a tauri dev binary sends through the Terminal identity instead, so allow Terminal notifications when testing).
  • No banner but blocks listed in the panel almost always means macOS is suppressing display: check Focus mode, and the per-app notification style in System Settings → Notifications.

In-app updates

The desktop app checks desktop-latest/latest.json on GitHub for updater metadata. Updater packages are always signed with the project Tauri updater key, independent of OS code signing.

Build From Source

Building from source requires Rust 1.88 or newer.

git clone https://github.com/Kazuki-tam/security-harness-kit.git
cd security-harness-kit
cargo build --release
bash

The release binaries are written to:

target/release/shk
text

Uninstall

shk does not ship a dedicated shk uninstall command. Removal has two layers: the CLI binary, and any project or user-level files written by shk while it was in use.

1. Remove The Binary

Pick the method that matches how shk was installed.

Script installer (default ~/.cargo/bin):

rm -f "${CARGO_HOME:-$HOME/.cargo}/bin/shk"
bash

Windows (PowerShell installer; default %USERPROFILE%\.cargo\bin when CARGO_HOME is unset):

$BinDir = if ($env:CARGO_HOME) { Join-Path $env:CARGO_HOME "bin" } else { "$env:USERPROFILE\.cargo\bin" }
Remove-Item (Join-Path $BinDir "shk.exe") -ErrorAction SilentlyContinue
powershell

Homebrew formula:

brew uninstall shk
# If installed from a tap, you can also remove it:
# brew untap Kazuki-tam/homebrew-tap
bash

npm package:

npm uninstall -g security-harness-kit
bash

bun package:

bun remove -g security-harness-kit
bash

Source build: run cargo clean in the cloned repository to remove build output, or remove target/release/shk directly. If you copied that binary into a directory on PATH, remove the copied binary there as well.

2. Remove Project Artifacts

shk does not modify project files unless you explicitly run a command that writes to disk. The artifacts created by those commands are listed below. Remove any that you no longer need from each project.

Source Path Notes
shk init / shk policy init shk.toml Project policy file.
shk init with npm hardening .npmrc, pnpm-workspace.yaml, .yarnrc.yml, bunfig.toml as applicable Project package-manager hardening files. Remove only settings added for ignore-scripts or package age gates if the file also contains your own package-manager configuration.
shk scan --audit, audit-mode hooks .shk/audit.log and the .shk/ directory Metadata-only audit log.
shk hooks install .git/hooks/pre-commit Managed block delimited by # shk-managed-start / # shk-managed-end. Delete the file if shk is the only owner, or remove just the managed block to keep other pre-commit logic.
shk hooks install-ai (Claude Code) .claude/settings.json Remove entries tagged with "_shk_managed": true. Delete the file if it has no remaining entries. If you used --apply-deny or --apply-sandbox, also review the permissions.deny and sandbox settings that were merged into the same file.
shk hooks install-ai (Cursor) .cursor/hooks.json Remove entries tagged with "_shk_managed": true.
shk hooks install-ai (Codex) .codex/config.toml Remove the block delimited by # shk-managed-start / # shk-managed-end, and features.hooks = true if no longer needed. The managed block covers PreToolUse, PermissionRequest, UserPromptSubmit, and PostToolUse. If you used --apply-sandbox, also review the top-level sandbox_mode and approval_policy values.
shk hooks install-ai (Copilot) .github/hooks/shk-security.json Remove entries whose command contains shk scan --hook-mode copilot.
shk hooks install-ai (Antigravity) .agents/hooks.json Remove the top-level shk-security entry (its hook entries are tagged with "_shk_managed": true). Delete the file if it has no remaining entries.
shk hooks install-ai (Windsurf) .windsurf/hooks.json Remove entries whose command contains shk scan --hook-mode windsurf. Delete the file if it has no remaining entries.
shk skills install (Claude Code) .claude/skills/shk/SKILL.md Bundled skill file. Installs from 0.3.17 or earlier used .claude/skills/shk.md; remove that file too if present.
shk skills install (Copilot) .github/skills/shk/SKILL.md Bundled skill file.
shk skills install (Codex / Cursor / Antigravity) .agents/skills/shk/SKILL.md Bundled skill file.
shk skills install (Windsurf) .windsurf/skills/shk/SKILL.md Bundled skill file.
shk ci init github .github/workflows/shk.yml by default Generated GitHub Actions workflow. If you passed --output, remove that custom path instead.

For commands that support it, re-running with --dry-run is a safe way to confirm the exact paths used in your project before deleting them. This applies to shk hooks install-ai, shk skills install, and shk ci init github; shk hooks install and shk init do not have a dry-run mode.

3. Remove User-Level Files

--global installs write to the user's home directory instead of the project. Remove these only if you want to disable shk for every project on this machine.

Source Path
shk hooks install-ai --global --tool claude-code ~/.claude/settings.json (managed entries, plus any permissions.deny or sandbox settings you explicitly enabled)
shk hooks install-ai --global --tool codex ~/.codex/config.toml (managed block, plus top-level sandbox settings if you used --apply-sandbox)
shk hooks install-ai --global --tool cursor ~/.cursor/hooks.json (managed entries)
shk hooks install-ai --global --tool copilot ~/.copilot/hooks/shk-security.json (managed entries)
shk hooks install-ai --global --tool antigravity ~/.gemini/config/hooks.json (managed shk-security entry)
shk hooks install-ai --global --tool windsurf ~/.codeium/windsurf/hooks.json (managed entries identified by --hook-mode windsurf)
shk skills install --global --tool claude-code ~/.claude/skills/shk/SKILL.md (or the legacy ~/.claude/skills/shk.md from 0.3.17 or earlier)
shk skills install --global --tool codex / --tool cursor ~/.agents/skills/shk/SKILL.md
shk skills install --global --tool copilot ~/.copilot/skills/shk/SKILL.md
shk skills install --global --tool antigravity ~/.gemini/config/skills/shk/SKILL.md
shk skills install --global --tool windsurf ~/.codeium/windsurf/skills/shk/SKILL.md

Managed entries use the same markers as project installs ("_shk_managed": true for JSON files, # shk-managed-start / # shk-managed-end for shell and TOML files). Copilot and Windsurf keep schema-clean JSON and are identified by their --hook-mode <tool> command strings. Settings merged by --apply-deny and --apply-sandbox are not individually tagged; review them before removing so you do not discard unrelated user configuration.

4. Remove Stored Env Keys

If you used shk env dotenvx import-keys or shk env key import / shk env encrypt, delete stored private keys before removing the binary so they are not orphaned. Stored keys are scoped to the canonical project root, so run this from each project where keys were stored:

shk env dotenvx delete --all
shk env key delete --all
bash

When [env].secret_store = "keyring" (the default), dotenvx keys live under the OS credential service security-harness-kit/dotenvx, and native keys live under security-harness-kit/env. If shk has already been removed, search for those service names in the platform credential store UI.

When [env].secret_store = "1password", keys are stored as tagged 1Password items (shk tag) in the vault configured by env.onepassword.vault. Item titles look like shk:{project_id}:env:DOTENV_PRIVATE_KEY or shk:{project_id}:dotenvx:DOTENV_PRIVATE_KEY_PRODUCTION. Delete them from the vault UI, or migrate back to the keyring first:

shk env key migrate --to keyring
bash

Verify the keyring copy, then remove the old tagged items explicitly from 1Password. Automatic source deletion is intentionally refused for a shared 1Password source.