Zuke is a build-automation framework, so it runs inside other people's pipelines and publishes itself to a public registry. Supply-chain integrity is therefore the primary concern, and this document describes how the project is hardened and how to report problems.
Zuke is pre-1.0 and largely AI-written (see the README). Review before you rely on it, and prefer pinning to an exact version in your own builds.
Please report security issues privately — do not open a public issue.
- Use GitHub's "Report a vulnerability" button under the repository's Security tab (Private Vulnerability Reporting). This opens a private advisory visible only to you and the maintainers.
- Include affected version(s), reproduction steps, and impact. A minimal proof of concept helps us triage quickly.
We aim to acknowledge a report within a few days and to coordinate a fix and disclosure timeline with you. Fixes ship in a new release; the advisory is published once a patched version is available.
While the project is pre-1.0, only the latest published version of each
@zuke/* package receives security fixes.
What the project does to keep releases trustworthy:
- Zero runtime dependencies. The library is dependency-free; the only
third-party tooling (
cspell,release-please) is dev/release-time, pinned, and never shipped to consumers. - Injection-free command execution. All process execution goes through
Deno.Commandwith a discrete argv array — there is no shell string, so interpolated values can never be reinterpreted as shell syntax. - Trusted publishing via OIDC. Packages publish to JSR with a short-lived
OIDC token (
id-token: write); no long-lived registry tokens or secrets are stored. JSR records build provenance for each published version. - Least-privilege CI. The default workflow token is
contents: read. The release pipeline is split so therelease-pleasejob (contents/pull-requests: write) and the JSRpublishjob (id-token: write) never hold each other's privileges. - Pinned, monitored Actions. Every GitHub Action is pinned to a full commit
SHA (with a version comment, kept current by Dependabot), and every job runs
step-security/harden-runnerto audit outbound network egress. - Pinned toolchain. The
./zukelauncher bootstraps a pinned Deno version by default (override withDENO_VERSION), so CI and local builds install a known version rather than a movinglatest. Dependencies are resolved against a committeddeno.lock, enforced with--frozen, and the scanner CLIs are pinned to exact versions in the security workflow. - Scanning via Zuke. The supply-chain scanners run as a typed Zuke build
target —
./zuke securitydrives zizmor (Actions SAST), actionlint, and gitleaks (secrets) through@zuke/security, failing the build on findings. (The package also wraps osv-scanner, semgrep, and Trivy for consumers whose projects have lockfiles/manifests those tools support.) Code-level SARIF for the GitHub Security tab comes from CodeQL (TypeScript), enabled through GitHub's default code-scanning setup, and from OpenSSF Scorecard, which runs as a native action workflow.
- Bootstrap launchers.
./zukeand./zuke.ps1install Deno on first use via the officialhttps://deno.landinstall script (curl … | sh). The version is pinned by default (setDENO_VERSION=latestor a specific version to override), andstep-security/harden-runneraudits runner egress, but the install script itself is fetched at run time. To avoid it entirely, install Deno yourself so the launcher finds it onPATH. deno publish --allow-dirty. The publish step currently allows a dirty tree as a backstop. The merged release tree should already be clean; once a real release confirms this, drop the flag for the strongest "published == committed source" guarantee.
The same scanners are exposed as Zuke tasks via
@zuke/security, so any consumer can run them in their
own pipeline:
import { SecurityTasks } from "jsr:@zuke/security";
await SecurityTasks.zizmor((s) => s.paths(".github/workflows"));
await SecurityTasks.osvScanner((s) => s.lockfile("package-lock.json"));In this repository, deno task zuke security runs the bundled set (zizmor,
actionlint, gitleaks) once the tools are installed on PATH.
These cannot be set from files in the repo; configure them in GitHub settings:
- Branch protection on
master: require a pull request with at least one review, require CODEOWNER review, require status checks (CI, CodeQL) to pass, dismiss stale approvals on new commits, and disallow force-pushes. - Restrict release-PR merges to maintainers.
- Enable CodeQL code scanning (default setup) with code quality. This is the single source for CodeQL — do not also add an advanced CodeQL workflow file, or the analysis runs twice.
- Enable secret scanning and push protection (free for public repos).
- Require 2FA for all maintainers, on both GitHub and JSR.
- Scope the JSR ↔ repo OIDC link so publishing is allowed only from this repository's release workflow.