Portable security pre-flight kit. One command checks your tools, scans repos,
hardens against AI agents, audits remote repos, enforces missing settings, and
surfaces rotating reminders. Bash (seckit.sh) and PowerShell (seckit.ps1)
are equivalent.
The script installs the scanners for you. It lists the missing ones and asks
which to install (or pass --all / -y to take them all):
bash seckit.sh install # macOS / Linux: Homebrew + npm
pwsh ./seckit.ps1 install # Windows: winget/scoop + pipx + npmOr install them by hand:
brew install jq yq gh azure-cli osv-scanner gitleaks trufflehog semgrep checkov pre-commit
az extension add --name azure-devops --upgrade # for ADO audit / enforce
# Windows: winget install TruffleSecurity.Trufflehog --scope user ; pip install semgrep checkov pre-commit
npm i -g @socketsecurity/cli # only for socketRun with bash seckit.sh <command> (or pwsh ./seckit.ps1 <command>), or put it
on your PATH:
chmod +x seckit.sh banner.sh scan_repos.sh
ln -s "$PWD/seckit.sh" /usr/local/bin/seckit
seckit installuses Homebrew on macOS/Linux and winget/scoop/pipx on Windows. Missing scanners are skipped automatically — the scan runs with whatever is installed.
SecKit itself needs no installation and no admin rights — it is a plain shell script. The scanners install entirely to user space via the right package manager:
- pip / pipx — always user-space (
~/.local,%APPDATA%\Python), never touches system directories. - winget
--scope user— forces user-level installation; avoids MSI system installers. SecKit uses this flag by default on Windows. - scoop — installs to
%USERPROFILE%\scoop, no admin needed for scoop itself. Exception: packages whose upstream binary is an MSI (notably 7zip, which trufflehog depended on via scoop) can be blocked by corporate policy. SecKit now routes trufflehog through winget to avoid this. - npm -g — user-space when the npm prefix is under the user profile (the default on most installs).
If a scanner still cannot be installed in your environment, seckit doctor marks it missing and seckit scan skips it — the remaining scanners run normally.
Run with no arguments on a terminal to open the interactive menu; inside it, b
backs out of a submenu and q quits. In a pipe or CI (no TTY) the no-arg form
prints help, so it never hangs.
Every tool is optional: if missing it is skipped, never fatal. seckit doctor
shows what is present and how to install the rest.
| Tool | Catches | Needs |
|---|---|---|
jq |
JSON shaping for mcp, audit, enforce |
- |
yq |
YAML parsing for mcp and policy files |
- |
gh |
GitHub posture audit + enforce |
gh auth login |
az + azure-devops extension |
Azure DevOps audit + enforce |
AZURE_DEVOPS_EXT_PAT |
osv-scanner |
dependencies with known vulnerabilities (CVEs) | - |
gitleaks |
secrets in git history | - |
trufflehog |
secrets in working files | - |
semgrep |
code-level vulnerabilities (SQLi, XSS, CSRF, injection) | network (fetches rules); install via pip install semgrep or winget install Semgrep.Semgrep --scope user |
checkov |
infrastructure-as-code misconfig (Bicep, Terraform, Actions, Docker, K8s) | - |
socket (opt-in) |
malicious package behaviour, not just CVEs | npm |
pre-commit |
runs the gitleaks gate before every git commit |
activated by seckit harden |
seckit scan ~/Git # all installed scanners (except socket)
seckit scan ~/Git --socket # also run Socket (needs `socket login`)
seckit scan ~/Git --only=gitleaks,osv # just these scanners
seckit scan ~/Git --skip=semgrep # all except semgrep (the slow one)
# PowerShell: same switches as parameters
seckit scan ~/Git -Only gitleaks,osv
seckit scan ~/Git -Skip semgrep
seckit scan ~/Git --fail-on=high --strict # gate mode (pwsh: -FailOn high -Strict)Scanner names: osv, gitleaks, trufflehog, semgrep, checkov, socket.
In the interactive menu, the scan submenu lists the scanners and lets you pick
which to run.
A "repo" is any folder containing .git or package.json; node_modules is
skipped, and a package.json folder nested inside a repo (npm/pnpm workspaces,
monorepos) is scanned as part of that repo rather than again on its own - only
a nested .git makes it a separate repo. It runs per repo, so a big sweep
multiplies - semgrep is the bottleneck (it fetches rules and does full SAST),
so --skip=semgrep (or --only=...) keeps a quick pre-flight fast. Exits
non-zero if any repo has findings, so it works in CI. semgrep fetches the
p/default registry ruleset with metrics off (no source upload, no project
URL sent) and adds the p/mobsfscan mobile ruleset (Swift/Kotlin/Java, MASVS)
when a repo contains native mobile source; checkov runs offline; socket is
opt-in because it uploads each repo's manifest to socket.dev.
Exit codes: 0 clean, 1 findings at or above the --fail-on threshold,
2 usage error, 3 --strict with a selected scanner not installed.
--fail-on=high keeps a blocking gate quiet on low-severity noise: secrets
(gitleaks, trufflehog) always fail; osv fails only when Critical or High
vulnerabilities are present (a missing severity summary counts as fail);
semgrep runs with --severity ERROR; checkov and socket still report but
never fail the run. The default --fail-on=any fails on any finding, as
before. --strict is for gates that must not silently pass because a scanner
was missing on the machine.
| Surface | Scanner |
|---|---|
| npm / yarn / pnpm / bun lockfiles | osv |
Maven / Gradle (pom.xml, gradle.lockfile) |
osv |
| Python / Ruby / Go / Rust / PHP / Dart / .NET lockfiles | osv |
| Secrets in git history | gitleaks |
| Secrets in working files | trufflehog |
| JS/TS source (SAST) | semgrep p/default |
| Swift / Kotlin / Java mobile source | semgrep p/mobsfscan (auto, on native mobile source) |
| Bicep, Terraform, GitHub Actions, Docker, K8s | checkov |
| Malicious package behaviour | socket (opt-in) |
Not covered - know your blind spots: CocoaPods advisories (OSV has no
CocoaPods ecosystem, so Podfile.lock yields nothing), compiled IPA/APK/AAB
binaries, Expo app.json/eas.json and Info.plist/AndroidManifest
semantics, and a bare package.json with no lockfile. Expo-managed repos
with no ios//android/ dir are fine: their native layer is the npm
packages, which are covered. Each repo's report includes a Coverage: line
listing exactly which manifest files osv parsed (or "no package manifests
parsed", so silence never masquerades as coverage).
Accepted findings live in each tool's native file at the repo root - no
SecKit-specific format, so reasons and expiry are reviewed in the PR that
edits the file: .gitleaks.toml / .gitleaksignore, osv-scanner.toml
([[IgnoredVulns]] with reason and ignoreUntil), .semgrepignore /
# nosemgrep, .checkov.baseline (create with checkov -d . --create-baseline), .trufflehog-exclude (one path regex per line). The
checkov and trufflehog files are passed automatically when present;
gitleaks reads its ignore files from the scanned repo.
Two placement/scope caveats, both verified against the shipped tools:
osv-scanner.toml must sit beside each manifest it applies to (osv only
loads the config next to the lockfile being scanned - a root-level file does
nothing for a nested apps/*/package-lock.json). And checkov baselines match
on resource name + check id only, across files: a same-named resource in
a new file silently inherits the suppression, so review .checkov.baseline
diffs with care.
seckit harden stops Claude Code and GitHub Copilot pulling secrets into
their context. It asks whether to apply guardrails at repo level or
global level, shows the list of files it will add, and asks you to confirm
before writing. It never clobbers existing files (--force to overwrite,
--yes to skip the confirm).
seckit harden # ask scope, preview, confirm, then harden
seckit harden ~/Git/foo # repo scope, a specific repo
seckit harden --repo # repo scope, current dir
seckit harden --global # whole machine
seckit harden --yes # skip the confirm promptRepo level writes a .gitignore secret block, .claude/settings.json deny
rules, CLAUDE.md + .github/copilot-instructions.md,
.github/copilot-content-exclusion.yml (paste into GitHub > Settings > Copilot),
and a gitleaks pre-commit gate (.pre-commit-config.yaml + .gitleaks.toml). It
warns if a secret-like file is already tracked by git. Templates live in
../templates/.
Global level writes ~/.config/git/ignore, sets git config --global core.excludesfile (only if unset), and adds Claude deny rules to
~/.claude/settings.json (or ~/.claude/settings.seckit.json to merge).
seckit audit is the read-only posture check. It calls gh for GitHub and az repos for Azure DevOps, compares the live state to the policy files in
../templates/policy-github.yml and
../templates/policy-ado.yml, and writes a
markdown report under ~/.seckit/reports/audit-<timestamp>.md. Nothing is
written to the remote.
seckit audit github segraef # org-level
seckit audit github segraef/sec-kit # repo-level
seckit audit ado contoso/Platform # ADO project
seckit audit ado contoso/Platform/web-api # ADO repoThe report has the same shape as seckit scan: a summary line, a table of
findings tagged required or recommended, and an "AI agent prompt" section
that pastes straight into Claude or Copilot for a remediation plan. Exit code
is non-zero when any required setting fails. Safe to run anywhere because
every call is a GET.
seckit enforce writes the settings flagged by audit. It is dry-run by
default and prints every command it would run; pass --apply (Bash) or
-Apply (PowerShell) to actually write. It enables branch protection on the
default branch, turns on vulnerability alerts + secret scanning + push
protection + private vulnerability reporting, clamps workflow permissions to
read-only with no PR approval, and drops any missing SECURITY.md,
CODEOWNERS, dependabot, CodeQL or PR template files into the cwd.
seckit enforce github segraef/sec-kit # dry-run
seckit enforce github segraef/sec-kit --apply # write
seckit enforce ado contoso/Platform/web-api # dry-run ADOUse it as a follow-up to audit: review the report, then run enforce against
the same target to close the gaps.
seckit agent install writes the SecKit prompt as a Claude subagent, GitHub
Copilot chat mode, Cursor rule or AGENTS.md section, so any AI assistant can
run the same playbook without the shell scripts installed. The canonical body
lives in
../templates/seckit-agent.md; the per-target
frontmatter wrappers live in
../templates/agents/.
seckit agent show # print the canonical prompt
seckit agent install # auto-detect targets in cwd
seckit agent install --target claude # write only one target
seckit agent install --target all # write claude, copilot, cursor, agents-mdTargets:
claudewrites.claude/agents/seckit.md(subagent).copilotwrites.github/chatmodes/seckit.chatmode.md.cursorwrites.cursor/rules/seckit.mdc.agents-mdwrites or appendsAGENTS.md.
The agent prompt is portable: it lists the same six steps seckit scan runs,
references the same secret patterns, and emits the same report shape, so a
Claude session in a sandbox produces output a SecKit-trained eye recognises.
seckit mcp manages MCP (Model Context Protocol) servers from the registry in
../templates/mcp/registry.yml. It writes a
client config under .mcp.json (Claude), .vscode/mcp.json (Copilot) or
~/.cursor/mcp.json (Cursor), merging into any existing file. Two packs ship:
- security: Semgrep, Snyk, OSV, Trivy, OpenSSF Scorecard. Use these to give an assistant first-class access to your vulnerability tooling.
- enterprise: GitHub, Azure DevOps, Atlassian (Jira + Confluence), Microsoft Learn, Terraform registry, Microsoft Foundry. Use these for daily enterprise work.
seckit mcp list # everything, grouped by pack
seckit mcp install --pack security --client claude # 5 security servers
seckit mcp install github --client copilot # one server, one client
seckit mcp install --pack enterprise --client all # everything in every client
seckit mcp doctor # which clients + env vars are presentServers that need a token are listed with their required environment
variables. seckit mcp doctor shows which are set so you can fix them before
the assistant starts. Restart the client after writing the config.
Add one line to your shell rc for a banner, a rotating reminder, and scanner health on every new terminal (fast, no scanning):
# ~/.zshrc or ~/.bashrc
bash "$HOME/Git/GitHub/segraef/sec-kit/seckit.sh" startup# $PROFILE
& "$HOME/Git/GitHub/segraef/sec-kit/seckit.ps1" startupReminders live in ../reminders.txt, one per line as
reminder => how to tackle it. The part after => is actionable: a seckit
command where one helps (highlighted on screen), otherwise the manual step. Add
your own by appending a line.
seckit bug # prompts for a title, collects diagnostics, opens a GitHub issueseckit bug gathers SecKit version, OS, Node version, and seckit doctor output into a pre-filled issue body, then:
- If
ghis authenticated: creates the issue directly viagh issue create. - Otherwise: opens
github.com/segraef/sec-kit/issues/newin the browser with the body pre-filled.
Run any command with --debug (or set SECKIT_DEBUG=1) to capture a full trace log:
seckit --debug scan .
SECKIT_DEBUG=1 seckit scan .The log is written to ~/.seckit/logs/debug-<timestamp>.log and captures set -x output (every command and its arguments). When you run seckit bug after a debug session, the last 100 lines of the log are included in the issue body automatically.
| File | Purpose |
|---|---|
seckit.sh / seckit.ps1 |
the dispatcher |
scan_repos.sh / scan_repos.ps1 |
the repo scanner |
mcp.sh / mcp.ps1 |
the MCP server manager |
audit.sh / audit.ps1 |
the read-only GitHub / ADO posture audit |
enforce.sh / enforce.ps1 |
writes the settings flagged by audit |
banner.sh |
the animated startup banner |
reminders.txt |
the reminders |
templates/ |
files seckit harden drops into a repo |
templates/seckit-agent.md |
canonical AI-agent prompt |
templates/agents/ |
per-target frontmatter wrappers for agent install |
templates/mcp/registry.yml |
MCP server catalog (security + enterprise) |
templates/policy-github.yml |
GitHub posture policy used by audit and enforce |
templates/policy-ado.yml |
Azure DevOps posture policy used by audit and enforce |
templates/repo/ |
repo posture files dropped by harden and enforce |
The banner is single-byte ASCII rendered as solid blocks, so it works on stock
macOS bash 3.2. Edit the art and TAGLINE at the top of banner.sh.