Added GPG pvt key as a github secret and updated workflow accordingly#333
Added GPG pvt key as a github secret and updated workflow accordingly#333Mahesh-Binayak wants to merge 2 commits into
Conversation
Replace committed .github/keys GPG file imports and manual gpg2 CLI calls with the crazy-max/ghaction-import-gpg@v6 action driven by the GPG_PRIVATE_KEY repository secret in maven-build, maven-publish-to-nexus, and maven-publish-android workflows. Also removes the stale inline GPG_TTY: $(tty) env var from the maven-publish-to-nexus publish step. For maven-sonar-analysis and maven-sonar-analysis-new, which do not sign artifacts, remove the GPG import step and GPG_SECRET secret entirely rather than migrating to the action. Remove the leftover `echo "GPG_TTY=$(tty)"` lines from dev-check, docker-build, npm-sonar-analysis, and release-changes workflows, which never used GPG signing but had accumulated the env export. Signed-off-by: Mahesh.Binayak <Mahesh.Binayak@thoughtworks.com> Signed-off-by: Mahesh.Binayak <mahesh.binyak@technoforte.o>
ci: migrate GPG key handling to crazy-max/ghaction-import-gpg@v6
WalkthroughThis PR modernizes GitHub Actions GPG key handling across eight CI/CD workflows. Maven build and publish workflows transition from file-based GPG imports to a secrets-based approach using the ChangesGitHub Actions GPG Workflow Modernization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/maven-build.yml:
- Around line 52-56: Replace the mutable tag crazy-max/ghaction-import-gpg@v6
with the exact commit SHA (e.g.,
crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec) wherever
it is used (the Import GPG step in .github/workflows/maven-build.yml and the
same referenced entries in maven-publish-to-nexus.yml and
maven-publish-android.yml) so the action is immutable; update each workflow's
"uses:" value to the SHA-pinned ref and verify the CI runs succeed after the
change.
- Around line 21-22: Update the docs and callers to include the required secret
by adding GPG_PRIVATE_KEY to the example secrets block in
docs/maven-build-readme.md (the workflow expects
workflow_call.secrets.GPG_PRIVATE_KEY) and ensure any repository using this
workflow supplies secrets.GPG_PRIVATE_KEY (not just GPG_SECRET); additionally,
replace the floating crazy-max/ghaction-import-gpg@v6 reference in
.github/workflows/maven-build.yml with a pinned commit SHA (or explicitly
document the version) to avoid unexpected changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a59346ea-16e2-49a9-aec8-b8dfa82a938c
📒 Files selected for processing (9)
.github/workflows/dev-check.yml.github/workflows/docker-build.yml.github/workflows/maven-build.yml.github/workflows/maven-publish-android.yml.github/workflows/maven-publish-to-nexus.yml.github/workflows/maven-sonar-analysis-new.yml.github/workflows/maven-sonar-analysis.yml.github/workflows/npm-sonar-analysis.yml.github/workflows/release-changes.yml
💤 Files with no reviewable changes (6)
- .github/workflows/maven-sonar-analysis.yml
- .github/workflows/maven-sonar-analysis-new.yml
- .github/workflows/dev-check.yml
- .github/workflows/release-changes.yml
- .github/workflows/docker-build.yml
- .github/workflows/npm-sonar-analysis.yml
| GPG_PRIVATE_KEY: | ||
| required: true |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find downstream callers of this reusable workflow across the mosip org
gh search code --owner mosip "uses: mosip/kattu/.github/workflows/maven-build.yml" --limit 100Repository: mosip/kattu
Length of output: 37
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Inspect the reusable workflow contract and the GPG import step
echo "=== maven-build.yml: contract around lines 15-35 ==="
nl -ba .github/workflows/maven-build.yml | sed -n '1,120p'
echo "=== maven-build.yml: lines 40-90 (focus on GPG import) ==="
nl -ba .github/workflows/maven-build.yml | sed -n '35,100p'
# 2) Search within this repo for downstream callers of the reusable workflow
echo "=== Local callers (this repo) using the workflow ==="
rg -n --hidden --glob '!**/node_modules/**' "uses:\s*mosip/kattu/\.github/workflows/maven-build\.yml" -S . || true
echo "=== Local callers with a looser match (in case of different path/format) ==="
rg -n --hidden --glob '!**/node_modules/**' "maven-build\.yml" -S .github/workflows || true
# 3) Also list any workflow_call secrets definitions for reference
echo "=== workflow_call secrets block (if present) ==="
rg -n "workflow_call|secrets:|GPG_PRIVATE_KEY" .github/workflows/maven-build.yml -n || trueRepository: mosip/kattu
Length of output: 169
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== maven-build.yml (first 200 lines with numbers via cat -n) ==="
cat -n .github/workflows/maven-build.yml | sed -n '1,200p'
echo "=== Local callers in this repo (workflows) using mosip/kattu reusable workflow ==="
rg -n --hidden --glob '!**/node_modules/**' "uses:\s*mosip/kattu/\.github/workflows/maven-build\.yml" -S .github/workflows . || true
echo "=== Local callers using maven-build.yml (fallback match) ==="
rg -n --hidden --glob '!**/node_modules/**' "uses:\s*.*maven-build\.yml" -S .github/workflows . || true
echo "=== workflow_call secrets block (if present) ==="
rg -n "workflow_call|secrets:|GPG_PRIVATE_KEY" .github/workflows/maven-build.yml -n || trueRepository: mosip/kattu
Length of output: 11781
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== docs/maven-build-readme.md around the reusable workflow call ==="
sed -n '1,120p' docs/maven-build-readme.mdRepository: mosip/kattu
Length of output: 2286
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "GPG_PRIVATE_KEY" -S . || true
rg -n "uses:\s*mosip/kattu/\.github/workflows/maven-build\.yml" -S .github workflows docs || true
rg -n "secrets:\s*inherit" -S .github || trueRepository: mosip/kattu
Length of output: 216
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git diff --stat -- .github/workflows/maven-build.yml || true
git diff -- .github/workflows/maven-build.yml | sed -n '1,200p' || trueRepository: mosip/kattu
Length of output: 37
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Any occurrences of 'secrets: inherit' in .github workflows ==="
rg -n "secrets:\s*inherit" -S .github || true
echo "=== Any occurrences of 'GPG_PRIVATE_KEY' in .github ==="
rg -n "GPG_PRIVATE_KEY" -S .github || true
echo "=== Any other docs mentioning GPG_PRIVATE_KEY ==="
rg -n "GPG_PRIVATE_KEY" -S docs || trueRepository: mosip/kattu
Length of output: 731
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== .github/workflows/maven-publish-to-nexus.yml (first 120 lines) ==="
cat -n .github/workflows/maven-publish-to-nexus.yml | sed -n '1,140p'
echo "=== .github/workflows/maven-publish-android.yml (first 140 lines) ==="
cat -n .github/workflows/maven-publish-android.yml | sed -n '1,180p'Repository: mosip/kattu
Length of output: 12563
Require GPG_PRIVATE_KEY in all callers (and fix README example) — maven-build.yml consumes it
.github/workflows/maven-build.yml declares workflow_call.secrets.GPG_PRIVATE_KEY: required: true (lines 21-22) and passes it to crazy-max/ghaction-import-gpg@v6 as gpg_private_key (lines 52-56). Callers must supply secrets.GPG_PRIVATE_KEY. In this repo’s docs/maven-build-readme.md example, secrets: includes GPG_SECRET but omits GPG_PRIVATE_KEY, so the example would fail as written.
Also consider pinning crazy-max/ghaction-import-gpg to a commit SHA instead of a floating v6 tag.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/maven-build.yml around lines 21 - 22, Update the docs and
callers to include the required secret by adding GPG_PRIVATE_KEY to the example
secrets block in docs/maven-build-readme.md (the workflow expects
workflow_call.secrets.GPG_PRIVATE_KEY) and ensure any repository using this
workflow supplies secrets.GPG_PRIVATE_KEY (not just GPG_SECRET); additionally,
replace the floating crazy-max/ghaction-import-gpg@v6 reference in
.github/workflows/maven-build.yml with a pinned commit SHA (or explicitly
document the version) to avoid unexpected changes.
| - name: Import GPG key | ||
| uses: crazy-max/ghaction-import-gpg@v6 | ||
| with: | ||
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | ||
| passphrase: ${{ secrets.GPG_SECRET }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Dereference the v6 tag to a commit SHA
gh api repos/crazy-max/ghaction-import-gpg/git/refs/tags/v6 \
--jq '.object.type + " " + .object.sha'
# If type is "tag" (annotated), dereference once more:
# gh api repos/crazy-max/ghaction-import-gpg/git/tags/<sha-from-above> --jq '.object.sha'Repository: mosip/kattu
Length of output: 103
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/maven-build.yml"
# show lines 45-70 with numbers
nl -ba "$file" | sed -n '45,70p'Repository: mosip/kattu
Length of output: 98
🌐 Web query:
crazy-max gaction-import-gpg gpg_private_key passphrase pin to commit SHA security best practice
💡 Result:
To ensure security when using the ghaction-import-gpg action, you should implement the following best practices: 1. Use Immutable Commit SHAs: Never pin your workflow actions to mutable tags or branch names (e.g., @v7). Instead, use the specific 40-character commit SHA to pin the action version [1][2]. This protects your pipeline against supply chain attacks where a malicious actor overwrites a tag or branch with compromised code [1][2]. Example: uses: crazy-max/ghaction-import-gpg@a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 # v7 2. Use GitHub Secrets for Sensitive Data: Always store the GPG private key and the associated passphrase in GitHub Secrets [3][4]. GitHub automatically masks these values in job logs, preventing them from being printed in plain text [4][5]. Never hardcode these values directly in your workflow files [4][5]. 3. Implement Least Privilege: Restrict the permissions of your workflow to only what is necessary [1]. Use an explicit permissions block to avoid granting excessive access by default [1]. If the workflow only needs to read the repository to sign commits, set: permissions: contents: read 4. Adopt Secure Alternatives: Consider using maintained forks or security-hardened versions of the action if your organization requires higher levels of provenance or supply chain security [6][7]. For example, some maintained versions provide additional features like signed commits and reproducible builds [6]. 5. Audit and Rotate: Regularly audit your GitHub Actions workflows for security misconfigurations, such as using mutable refs or excessive permissions [1]. If you suspect a secret has been exposed, rotate the GPG key immediately and update the corresponding GitHub Secret [2]. By combining immutable version pinning with secure secret management, you significantly reduce the attack surface of your CI/CD pipeline [1][2].
Citations:
- 1: https://dev.to/unbearablelabs/if-you-use-trivy-or-kics-in-ci-read-this-4d91
- 2: https://securityboulevard.com/2026/05/laravel-lang-composer-tag-rewrite-supply-chain-attack/
- 3: https://github.com/crazy-max/ghaction-import-gpg
- 4: https://stackoverflow.com/questions/61096521/how-to-use-gpg-key-in-github-actions
- 5: https://docs.github.com/actions/security-guides/using-secrets-in-github-actions
- 6: https://app.stepsecurity.io/action-advisor/step-security/ghaction-import-gpg
- 7: https://github.com/step-security/ghaction-import-gpg
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/maven-build.yml"
nl -ba "$file" | sed -n '45,70p'Repository: mosip/kattu
Length of output: 98
🌐 Web query:
crazy-max/ghaction-import-gpg gpg_private_key passphrase security pin to commit SHA
💡 Result:
The crazy-max/ghaction-import-gpg GitHub Action facilitates GPG key usage in GitHub Actions by importing a private key into the runner's environment [1][2]. To use it securely: 1. Store your ASCII-armored private GPG key as a GitHub Secret (e.g., GPG_PRIVATE_KEY) [1][2]. 2. If your key is passphrase-protected, store the passphrase as a separate GitHub Secret (e.g., PASSPHRASE) [1][2]. 3. Pass these secrets into the action's with: block [1][2]. The action automatically seeds the gpg-agent with the provided passphrase, allowing subsequent Git operations to use the key without manual interaction [1][2]. Regarding security and best practices: - Commit SHA Pinning: To protect your CI/CD pipeline against supply chain attacks (such as tag-based mutable ref poisoning), you should pin the action to a specific commit SHA rather than a branch or tag version (e.g., uses: crazy-max/ghaction-import-gpg@<40-char-sha>) [3][4]. - Secret Masking: GitHub automatically masks secrets defined in your workflow [5][6]. When using this action, the passphrase and private key are handled as secrets and will be redacted in logs [5][6]. However, avoid logging these values manually [6]. - No PIN requirement: The action does not require a "PIN" in the traditional hardware-security-module (HSM) sense; it manages GPG-agent caching for you, which eliminates the need for interactive passphrase prompts [1][2]. - Scope: The action configures the runner's local environment. If your workflow involves building and running code in separate Docker containers (e.g., via other custom actions), ensure those environments are also configured to access the imported GPG key, as the configuration does not persist automatically across container boundaries [7].
Citations:
- 1: https://github.com/crazy-max/ghaction-import-gpg
- 2: https://github.com/crazy-max/ghaction-import-gpg/blob/master/README.md
- 3: https://dev.to/unbearablelabs/if-you-use-trivy-or-kics-in-ci-read-this-4d91
- 4: https://securityboulevard.com/2026/05/laravel-lang-composer-tag-rewrite-supply-chain-attack/
- 5: https://stackoverflow.com/questions/61096521/how-to-use-gpg-key-in-github-actions
- 6: https://dev.to/thisguymartin/load-secrets-from-proton-pass-in-github-actions-2glj
- 7: GPG Sign in GitHub Actions commitizen-tools/commitizen#616
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/workflows/maven-build.yml"
# Print the relevant section with line numbers without relying on `nl`
awk 'NR>=45 && NR<=70 {printf "%d\t%s\n", NR, $0}' "$file"Repository: mosip/kattu
Length of output: 2491
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find all occurrences of the action to ensure only the expected one exists
rg -n "crazy-max/ghaction-import-gpg@v6|crazy-max/ghaction-import-gpg@" .github/workflows || trueRepository: mosip/kattu
Length of output: 324
🏁 Script executed:
#!/bin/bash
# Dereference the v6 tag to a commit SHA
gh api repos/crazy-max/ghaction-import-gpg/git/refs/tags/v6 \
--jq '.object.type + " " + .object.sha'
# If type is "tag" (annotated), dereference once more:
# gh api repos/crazy-max/ghaction-import-gpg/git/tags/<sha-from-above> --jq '.object.sha'Repository: mosip/kattu
Length of output: 103
Pin crazy-max/ghaction-import-gpg@v6 to a commit SHA
crazy-max/ghaction-import-gpg@v6 is a mutable tag for a third-party action and receives your GPG private key (secrets.GPG_PRIVATE_KEY) + passphrase, so it should be SHA-pinned. v6 resolves to e89d40939c28e39f97cf32126055eeae86ba74ec.
🔒 Pin to a SHA
- name: Import GPG key
- uses: crazy-max/ghaction-import-gpg@v6
+ uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_SECRET }}(Also used as @v6 in .github/workflows/maven-publish-to-nexus.yml and .github/workflows/maven-publish-android.yml.)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Import GPG key | |
| uses: crazy-max/ghaction-import-gpg@v6 | |
| with: | |
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| passphrase: ${{ secrets.GPG_SECRET }} | |
| - name: Import GPG key | |
| uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6 | |
| with: | |
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| passphrase: ${{ secrets.GPG_SECRET }} |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 53-53: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/maven-build.yml around lines 52 - 56, Replace the mutable
tag crazy-max/ghaction-import-gpg@v6 with the exact commit SHA (e.g.,
crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec) wherever
it is used (the Import GPG step in .github/workflows/maven-build.yml and the
same referenced entries in maven-publish-to-nexus.yml and
maven-publish-android.yml) so the action is immutable; update each workflow's
"uses:" value to the SHA-pinned ref and verify the CI runs succeed after the
change.
Summary by CodeRabbit