Skip to content

chant audit

chant audit [path] [flags]
chant audit <repo-url> [flags]

chant audit runs chant’s security, correctness, and best-practice rules against an existing repository’s config — CI/CD pipelines plus IaC and manifests (Kubernetes, Helm, Docker, CloudFormation, ARM, Config Connector) — including files chant didn’t generate. Point it at a local directory or a public repo URL and it produces a tiered report grouped by category, with findings worth a pull request split from lower-priority hygiene.

It is read-only and requires no chant project — it reads the repo’s CI files directly and runs the same post-synth security checks the build pipeline uses (GitHub Actions GHA*, GitLab CI WGL*; Forgejo workflows are GitHub-dialect, so the GitHub tier applies to them too).

What it scans:

  • .github/workflows/*.{yml,yaml} (GitHub Actions / Forgejo)
  • .forgejo/workflows/*.{yml,yaml} (Forgejo / Codeberg / Gitea)
  • .gitlab-ci.yml (GitLab CI)
  • Kubernetes manifests (any *.{yml,yaml} with apiVersion + kind), for a local path — runs the WK8*/ARGO* checks (privileged containers, host namespaces, hardcoded secrets, image pinning, …)
  • Docker — Dockerfile/*.Dockerfile and Compose files (*.{yml,yaml} with services:), for a local path — runs the DKRD* checks (root user, :latest images, exposed SSH, …)
  • AWS CloudFormation — .json/.yaml/.yml/.template with AWSTemplateFormatVersion or AWS::* resources, for a local path — runs the WAW*/COR*/EXT* checks (public S3, open security groups, IAM wildcards, unencrypted storage, …). Both JSON and YAML templates.
  • Azure ARM — .json deployment templates ($schema with deploymentTemplate + resources), for a local path — runs the AZR* checks (public blob access, missing encryption/TDE, HTTPS-only, TLS 1.2, …)
  • GCP Config Connector — *.{yml,yaml} with a cnrm.cloud.google.com apiVersion, for a local path — runs the WGC* checks (public IAM, open firewalls, public Cloud SQL, missing encryption, Workload Identity, …)
  • Helm charts — any directory with a Chart.yaml, for a local path — runs the WHM* checks (privileged/root containers, :latest images, inline Secrets, chart structure, …). The whole chart is audited as one unit.

Every rule a finding cites links to its entry in the audit rules reference.

The report groups findings into:

  • Quick wins (deterministic) — safe mechanical fixes shown as a ready-to-apply unified diff (add a least-privilege permissions: block, pin actions to a commit SHA, pin images to a digest).
  • Needs review (guidance) — findings that need a judgement call (script injection, pull_request_target hardening, secret scope), clustered by the security area they belong to.
  • Report-only (hygiene) — style/perf/deprecation, never something to open a PR over.

The minimized (markdown) report leads with ready-to-apply fix diffs; rule IDs link to the rules reference:

# chant audit
4 findings — 3 quick-win, 0 needs-review, 1 report-only (0 error, 3 warning, 1 info).
## Quick wins (deterministic)
### `.github/workflows/ci.yml`
Addresses [GHA033](/chant/lint-rules/audit-rules/#gha033) (Blanket write-all permissions):
```diff
-permissions: write-all
+permissions:
+ contents: read
```
Needs a value before it can be auto-patched:
- **[GHA021](/chant/lint-rules/audit-rules/#gha021)** (`build`) — Pin `actions/checkout` to a full 40-char commit SHA.
<details><summary>Report-only (hygiene) — 1</summary>
</details>

The expanded (HTML) report renders the same findings with badges, cards, and syntax-highlighted diffs — view a sample report →.

FlagDescription
-f, --format <fmt>Output format: stylish (default), json, sarif, markdown, html
--jsonShortcut for --format json
-o, --output <file>Write the report to a file instead of stdout
--tier <tier>all (default) or merge-worthy to show only PR-worthy findings
--fail-on <level>Exit non-zero on merge-worthy, warning, or none (default none)
--template <file>html only: a full HTML template override (see below)
--theme <file>html only: a JSON file of theme knobs (title, logo, accent, footer)
  • Minimized--format markdown (or stylish/json/sarif). Compact, pastes into a PR or issue; quick wins lead with ready-to-apply diffs, the rest collapses into <details>.
  • Expanded--format html. A self-contained, presentable HTML document (inline CSS, opens in a browser, shareable as one file): severity badges, tier counts, styled finding cards, syntax-highlighted fix diffs, and a provenance snapshot (host, repo, commit SHA, files scanned, timestamp, chant version) so every finding is anchored to an exact commit.
  • --theme theme.json fills knobs into the default template:

    { "title": "Acme CI Audit", "logo": "https://acme.example/logo.svg", "accent": "#0b7285", "footer": "Internal use only." }
  • --template my.html replaces the whole document. Available slots: {{title}}, {{accent}}, {{logo}}, {{styles}}, {{body}}, {{footer}}. The findings render into {{body}}.

For tooling, --format json emits a versioned envelope (stable contract). The same object is embedded in the HTML report inside <script type="application/json" id="chant-audit-report">, so the expanded report is both human- and machine-readable.

{
"schemaVersion": "1.0",
"tool": { "name": "chant-audit", "version": "0.7.0" },
"snapshot": { "target": "...", "host": "github.com", "repo": "owner/repo", "commit": "", "files": ["..."], "generatedAt": "", "toolVersion": "0.7.0" },
"summary": { "total": 0, "quickWin": 0, "needsReview": 0, "reportOnly": 0, "errors": 0, "warnings": 0, "infos": 0, "security": 0, "correctness": 0, "bestPractice": 0 },
"findings": [
{ "checkId": "GHA033", "severity": "warning", "message": "", "file": "", "entity": "", "lexicon": "github",
"tier": "merge-worthy", "fixKind": "deterministic", "category": "security", "title": "", "remediation": "",
"authority": [{ "name": "", "url": "" }], "docUrl": "https://intentius.io/chant/lint-rules/audit-rules/#gha033" }
]
}

Stability contract:

  • Additive changes (new fields) keep the same schemaVersion; renamed or removed fields bump it.
  • Consumers should check the major version and ignore unknown fields.
  • The snapshot anchors findings to an exact commit for reproducibility.
  • For maximum stability, integrate via --format sarif — an industry-standard, independently-versioned format.

Auditing a URL calls the host’s API. Set a host-specific token to lift rate limits (and, for GitHub, to resolve action SHAs and image digests for the inline fix diffs):

  • GITHUB_TOKEN — GitHub, plus action-SHA and image-digest resolution (always queries the GitHub/registry APIs)
  • GITLAB_TOKEN — GitLab
  • CODEBERG_TOKEN — Codeberg

Without a token, unauthenticated GitHub is limited to 60 requests/hour and pin fixes fall back to “needs a value” instead of an inline diff. Tokens are never sent across hosts.

chant audit runs each lexicon’s security checks, so it needs the lexicon packages for the file types you want audited installed alongside @intentius/chant:

Terminal window
# CI/CD pipelines
npm i @intentius/chant-lexicon-github # GitHub Actions (also Forgejo workflows)
npm i @intentius/chant-lexicon-gitlab # GitLab CI
npm i @intentius/chant-lexicon-forgejo # Forgejo dialect
# Infrastructure & manifests
npm i @intentius/chant-lexicon-k8s # Kubernetes manifests
npm i @intentius/chant-lexicon-helm # Helm charts
npm i @intentius/chant-lexicon-docker # Dockerfiles / Compose
npm i @intentius/chant-lexicon-aws # CloudFormation
npm i @intentius/chant-lexicon-azure # ARM templates
npm i @intentius/chant-lexicon-gcp # Config Connector

If a needed lexicon package is missing, the command tells you which package to install — either as a friendly error (CI files, detected by path) or, for content-detected file types, as a note when nothing was found.

Terminal window
# Audit the current repo
chant audit
# Audit a local checkout
chant audit ../some-repo
# Audit a public repo over the network
chant audit https://github.com/owner/repo
chant audit https://gitlab.com/group/project
chant audit https://codeberg.org/owner/repo
# Save a shareable markdown report
chant audit https://github.com/owner/repo -f markdown -o report.md
# Generate a presentable, branded HTML report
chant audit https://github.com/owner/repo -f html --theme theme.json -o report.html
# Only the PR-worthy findings, as JSON, failing CI if any exist
chant audit . --tier merge-worthy --json --fail-on merge-worthy
--fail-onExit 1 when…
none (default)never (read-only)
merge-worthyany merge-worthy finding exists
warningany error- or warning-severity finding exists