Skip to content

fix(security): set up SSH so classpath jobs can clone private git deps - #3

Merged
arootroatch merged 1 commit into
masterfrom
fix/private-git-ssh-classpath-jobs
Jul 20, 2026
Merged

fix(security): set up SSH so classpath jobs can clone private git deps#3
arootroatch merged 1 commit into
masterfrom
fix/private-git-ssh-classpath-jobs

Conversation

@arootroatch

Copy link
Copy Markdown
Collaborator

Draft for review — do not merge yet.

Problem

clj-kondo and clj-watson build the full classpath (clojure -Spath / clj-watson scan -p deps.edn), which forces resolution of private git dependencies. The reusable workflow has no SSH setup, so those two jobs only pass when a warm ~/.gitlibs cache already contains the dep. On a cold cache — which happens after any deps.edn change — they fail with:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

clj-holmes, gitleaks, shellcheck, and semgrep don't build the classpath and are unaffected.

Fix

  • Add an optional, scoped private-git-ssh-key workflow_call secret (not a return to blanket secrets: inherit).
  • Add a "Set up SSH for private git deps" step to only the two classpath-building jobs (clj-kondo, clj-watson). It mirrors the consumers' existing build workflows: write the deploy key to ~/.ssh/id_ed25519, chmod 600, ssh-keyscan github.com.
  • The step self-skips when the secret is unset (::notice::no private-git-ssh-key provided), so consumers without private git deps — and this repo's own self-test.yml (no deps.edn) — are unaffected.

Consumer usage

Consumer wrapper passes its existing SSH deploy-key secret through explicitly:

    uses: cleancoders/github-actions/.github/workflows/security.yml@v1
    with:
      clj-watson-blocking: true
      semgrep-blocking: true
    secrets:
      private-git-ssh-key: ${{ secrets.<YOUR_DEPLOY_KEY_SECRET> }}

Rollout / proof

Consumers pin @v1. To prove this end-to-end, a downstream consumer's wrapper is temporarily pointed at this fix branch and its security run goes fully green (all six jobs, including the now-enforcing clj-watson + semgrep). Final state re-pins consumers to @v1 once this merges and v1 is re-tagged to include it — the temporary branch pin is reverted before the downstream PR merges.

actionlint clean on security.yml and self-test.yml.

clj-kondo and clj-watson build the full classpath (`clojure -Spath` /
clj-watson scan), which must clone private git dependencies. The reusable
workflow had no SSH setup, so those jobs only succeeded when a warm
~/.gitlibs cache happened to already contain the dep; on a cold cache
(e.g. after any deps.edn change) they failed with a "Permission denied
(publickey)" clone error. clj-holmes, gitleaks, shellcheck and semgrep
don't build the classpath and are unaffected.

Add an optional, scoped `private-git-ssh-key` workflow_call secret and,
only in the two classpath-building jobs, a "Set up SSH" step that mirrors
the consumer build workflows (write the deploy key to ~/.ssh/id_ed25519,
ssh-keyscan github.com). The step self-skips when the secret is unset,
so consumers without private git deps (and the self-test) are unaffected.
Scoped on purpose — not a return to blanket `secrets: inherit`.
@arootroatch
arootroatch marked this pull request as ready for review July 20, 2026 19:02
@arootroatch
arootroatch merged commit cd2dbfb into master Jul 20, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant