Skip to content

SQSCANGHA-140 Add OpenPGP signature verification for scanner downloads#235

Merged
claire-villard-sonarsource merged 1 commit into
masterfrom
claire/SQSCANGHA-140/signature
Apr 28, 2026
Merged

SQSCANGHA-140 Add OpenPGP signature verification for scanner downloads#235
claire-villard-sonarsource merged 1 commit into
masterfrom
claire/SQSCANGHA-140/signature

Conversation

@claire-villard-sonarsource

@claire-villard-sonarsource claire-villard-sonarsource commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements OpenPGP signature verification for Sonar Scanner CLI downloads to ensure supply chain security. Downloaded binaries are now verified against SonarSource's public key before extraction.

Security Implementation

  • Default behavior: Verification enabled by default
  • SonarSource key fingerprint: 679F1EE92B19609DE816FDE81DB198F93525EC1A
  • Keyservers: hkps://keyserver.ubuntu.com and hkps://keys.openpgp.org

Tests

Installing Sonar Scanner CLI 8.0.1.6346 for linux-x64...
Downloading from: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-x64.zip
Downloading signature from: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-x64.zip.asc
Importing SonarSource public key from hkps://keyserver.ubuntu.com...
/usr/bin/gpg --homedir /home/runner/work/_temp/gpg-home-1777316065290-2325 --batch --keyserver hkps://keyserver.ubuntu.com --recv-keys 679F1EE92B19609DE816FDE81DB198F93525EC1A
gpg: keybox '/home/runner/work/_temp/gpg-home-1777316065290-2325/pubring.kbx' created
gpg: /home/runner/work/_temp/gpg-home-1777316065290-2325/trustdb.gpg: trustdb created
gpg: key 1DB198F93525EC1A: public key "SonarSource S.A. <infra@sonarsource.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
Successfully imported key from hkps://keyserver.ubuntu.com
✓ SonarSource public key imported successfully
Verifying GPG signature...
/usr/bin/gpg --homedir /home/runner/work/_temp/gpg-home-1777316065290-2325 --batch --verify /home/runner/work/_temp/b261552d-cbd0-4086-8aa0-db4f4f185021 /home/runner/work/_temp/d28e59a5-58c1-41e1-aeed-675edc5e36f4
gpg: Signature made Fri Dec  5 15:12:27 2025 UTC
gpg:                using RSA key D1436C0DBACEA48702AF97C363F1DD7753B8B315
gpg: Good signature from "SonarSource S.A. <infra@sonarsource.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 679F 1EE9 2B19 609D E816  FDE8 1DB1 98F9 3525 EC1A
     Subkey fingerprint: D143 6C0D BACE A487 02AF  97C3 63F1 DD77 53B8 B315
✓ GPG signature verification passed
/usr/bin/unzip -o -q /home/runner/work/_temp/d28e59a5-58c1-41e1-aeed-675edc5e36f4
Sonar Scanner CLI cached to: /opt/hostedtoolcache/sonar-scanner-cli/8.0.1.6346/linux-x64
/opt/hostedtoolcache/sonar-scanner-cli/8.0.1.6346/linux-x64/bin/sonar-scanner -Dsonar.projectBaseDir=.
18:54:28.049 INFO  Scanner configuration file: /opt/hostedtoolcache/sonar-scanner-cli/8.0.1.6346/linux-x64/conf/sonar-scanner.properties
18:54:28.052 INFO  Project root configuration file: /home/runner/work/sample-js-project/sample-js-project/sonar-project.properties
image

References

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Apr 27, 2026

Copy link
Copy Markdown

SQSCANGHA-140

@sonar-review-alpha

sonar-review-alpha Bot commented Apr 27, 2026

Copy link
Copy Markdown

Summary

This PR adds OpenPGP signature verification for downloaded Sonar Scanner CLI binaries, enabling supply chain security validation. When a binary is downloaded, the action now automatically fetches and validates its detached signature (.asc file) against SonarSource's public key before extraction.

Key behavior:

  • Verification is enabled by default
  • Downloads signature file alongside the ZIP binary
  • Imports SonarSource's key from primary keyserver (ubuntu) with automatic fallback to alternative keyserver (openpgp.org) if needed
  • New input skipSignatureVerification allows users to disable verification if needed (not recommended)

The implementation handles cross-platform specifics (Windows path conversion for GPG), creates isolated temporary GPG home directories, and cleans up properly. Tests cover both happy path and error scenarios with comprehensive mocking.

What reviewers should know

Start here: Review src/main/gpg-verification.js first—it's the core module containing all signature verification logic. The functions are small and well-documented.

Flow to follow:

  1. install-sonar-scanner.js — Shows where verification is triggered (after downloading the ZIP, before extraction)
  2. action.yml — New skipSignatureVerification input
  3. index.js — How the input is passed through the call chain
  4. Test files — Validation logic and error handling

Important details:

  • SonarSource's key fingerprint is hardcoded: 679F1EE92B19609DE816FDE81DB198F93525EC1A
  • Path conversion: The convertToUnixPath function handles Windows path formatting for GPG (which expects Unix-style paths even on Windows)
  • Fallback: If the primary keyserver fails, the action automatically tries keys.openpgp.org
  • Cleanup: GPG home directories are created with 0o700 permissions and cleaned up in a finally block
  • Error messaging: Verification failures are explicit about supply chain compromise risk

Dependencies:

  • Added @actions/exec@2.0.0 to shell out GPG commands
  • Updated test command to use --experimental-test-module-mocks for test isolation

  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

sonar-review-alpha[bot]

This comment was marked as resolved.

sonar-review-alpha[bot]

This comment was marked as outdated.

sonar-review-alpha[bot]

This comment was marked as resolved.

sonar-review-alpha[bot]

This comment was marked as outdated.

@sonarqube-agent

sonarqube-agent AI commented Apr 28, 2026

Copy link
Copy Markdown

SonarQube Remediation Agent

SonarQube found 1 issue in this PR that the agent can fix for you. Est. time saved: ~5 min

1 issue found
  • 🟠 No magic number: 3.gpg-verification-mocked.test.js:222
  • Run Remediation Agent
    Select the checkbox above to enable this action.

View Project in SonarCloud

💡 Got issues in your backlog? Let the agent fix them for you.

sonar-review-alpha[bot]

This comment was marked as outdated.

@claire-villard-sonarsource claire-villard-sonarsource force-pushed the claire/SQSCANGHA-140/signature branch from cde6998 to 4964834 Compare April 28, 2026 11:46
sonar-review-alpha[bot]

This comment was marked as resolved.

@claire-villard-sonarsource claire-villard-sonarsource force-pushed the claire/SQSCANGHA-140/signature branch from 4964834 to 3ea526d Compare April 28, 2026 11:58
sonar-review-alpha[bot]

This comment was marked as outdated.

Comment thread src/main/gpg-verification.js Outdated
sonar-review-alpha[bot]

This comment was marked as outdated.

@antoine-vinot-sonarsource antoine-vinot-sonarsource left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - AMAJCLG*

*As Much As Javascript Can Look Good

Implemented OpenPGP signature verification to ensure the integrity and authenticity of downloaded SonarQube scanner packages. This security enhancement protects against supply chain attacks.

Key implementation decisions:
  - GPG verification runs by default for all scanner downloads, with an optional skipSignatureVerification flag for environments where GPG is unavailable
  - Dual keyserver strategy: attempts primary keyserver (keyserver.ubuntu.com) with automatic fallback to keys.openpgp.org if the primary fails, improving reliability across different network environments
  - Platform-specific path handling: converts Windows paths to Unix-style format for GPG compatibility, as GPG from Git for Windows expects Unix-style paths even on Windows systems
  - Isolated verification: uses temporary GPG home directories to avoid polluting user keyring, with guaranteed cleanup in finally blocks to prevent temp file leakage even on verification failures
  - Security-first error handling: throws clear errors when GPG is absent or signatures fail, preventing silent security bypasses

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
@claire-villard-sonarsource claire-villard-sonarsource force-pushed the claire/SQSCANGHA-140/signature branch from ed2a160 to e1c6b57 Compare April 28, 2026 13:44
@sonarqubecloud

Copy link
Copy Markdown

@sonar-review-alpha sonar-review-alpha Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean implementation overall. The security model — isolated ephemeral keyring, import by full 40-char fingerprint, then verify — is correct and well-suited for CI use. The cross-platform path handling, keyserver fallback, and cleanup-on-failure are all handled properly. One test maintenance issue worth fixing.

🗣️ Give feedback

Comment thread src/main/__tests__/gpg-verification-mocked.test.js
@claire-villard-sonarsource claire-villard-sonarsource merged commit 55e4480 into master Apr 28, 2026
71 checks passed
@claire-villard-sonarsource claire-villard-sonarsource deleted the claire/SQSCANGHA-140/signature branch April 28, 2026 13:49
@luroden

luroden commented Apr 28, 2026

Copy link
Copy Markdown

@claire-villard-sonarsource This is a breaking change if the runner does not have dirmngr installed.

@melloc01

Copy link
Copy Markdown

Yes, this is a breaking change. Please revert and consider to add on 8.0.0?

@gmmcal

gmmcal commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

suggestion: set default for skipSignatureVerification as true and make it default to false on v8 (see #239)

gmmcal added a commit to gmmcal/sonarqube-scan-action that referenced this pull request Apr 28, 2026
luketainton pushed a commit to luketainton/repos_epage-go that referenced this pull request Apr 28, 2026
…(#8)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [SonarSource/sonarqube-scan-action](https://github.com/SonarSource/sonarqube-scan-action) | action | minor | `v7.1.0` → `v7.2` |

---

### Release Notes

<details>
<summary>SonarSource/sonarqube-scan-action (SonarSource/sonarqube-scan-action)</summary>

### [`v7.2`](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

### [`v7.2.0`](https://github.com/SonarSource/sonarqube-scan-action/releases/tag/v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.1.0...v7.2.0)

#### What's Changed

- SQSCANGHA-133 Upgrade the Node version used in UTs + contribution guide by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;226](SonarSource/sonarqube-scan-action#226)
- SC-45750 Migrate to dateless license headers by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;229](SonarSource/sonarqube-scan-action#229)
- SQSCANGHA-134 Upgrade the libraries to latest version by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;227](SonarSource/sonarqube-scan-action#227)
- SQSCANGHA-138 Update dist and add ci test by [@&#8203;antoine-vinot-sonarsource](https://github.com/antoine-vinot-sonarsource) in [#&#8203;233](SonarSource/sonarqube-scan-action#233)
- SQSCANGHA-140 Add OpenPGP signature verification for scanner downloads by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;235](SonarSource/sonarqube-scan-action#235)

**Full Changelog**: <SonarSource/sonarqube-scan-action@v7...v7.2.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE1MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL2RlcGVuZGVuY2llcyJdfQ==-->

Reviewed-on: https://git.tainton.uk/repos/epage-go/pulls/8
Co-authored-by: renovate[bot] <renovate-bot@git.tainton.uk>
Co-committed-by: renovate[bot] <renovate-bot@git.tainton.uk>
luketainton pushed a commit to luketainton/repos_pypilot that referenced this pull request Apr 28, 2026
…(#440)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [SonarSource/sonarqube-scan-action](https://github.com/SonarSource/sonarqube-scan-action) | action | minor | `v7.1.0` → `v7.2` |

---

### Release Notes

<details>
<summary>SonarSource/sonarqube-scan-action (SonarSource/sonarqube-scan-action)</summary>

### [`v7.2`](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

### [`v7.2.0`](https://github.com/SonarSource/sonarqube-scan-action/releases/tag/v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.1.0...v7.2.0)

#### What's Changed

- SQSCANGHA-133 Upgrade the Node version used in UTs + contribution guide by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;226](SonarSource/sonarqube-scan-action#226)
- SC-45750 Migrate to dateless license headers by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;229](SonarSource/sonarqube-scan-action#229)
- SQSCANGHA-134 Upgrade the libraries to latest version by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;227](SonarSource/sonarqube-scan-action#227)
- SQSCANGHA-138 Update dist and add ci test by [@&#8203;antoine-vinot-sonarsource](https://github.com/antoine-vinot-sonarsource) in [#&#8203;233](SonarSource/sonarqube-scan-action#233)
- SQSCANGHA-140 Add OpenPGP signature verification for scanner downloads by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;235](SonarSource/sonarqube-scan-action#235)

**Full Changelog**: <SonarSource/sonarqube-scan-action@v7...v7.2.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE1MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL2RlcGVuZGVuY2llcyJdfQ==-->

Reviewed-on: https://git.tainton.uk/repos/pypilot/pulls/440
Co-authored-by: renovate[bot] <renovate-bot@git.tainton.uk>
Co-committed-by: renovate[bot] <renovate-bot@git.tainton.uk>
luketainton pushed a commit to luketainton/repos_roboluke that referenced this pull request Apr 28, 2026
…(#445)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [SonarSource/sonarqube-scan-action](https://github.com/SonarSource/sonarqube-scan-action) | action | minor | `v7.1.0` → `v7.2` |

---

### Release Notes

<details>
<summary>SonarSource/sonarqube-scan-action (SonarSource/sonarqube-scan-action)</summary>

### [`v7.2`](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.2.0...v7.2.0)

### [`v7.2.0`](https://github.com/SonarSource/sonarqube-scan-action/releases/tag/v7.2.0)

[Compare Source](SonarSource/sonarqube-scan-action@v7.1.0...v7.2.0)

#### What's Changed

- SQSCANGHA-133 Upgrade the Node version used in UTs + contribution guide by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;226](SonarSource/sonarqube-scan-action#226)
- SC-45750 Migrate to dateless license headers by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;229](SonarSource/sonarqube-scan-action#229)
- SQSCANGHA-134 Upgrade the libraries to latest version by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;227](SonarSource/sonarqube-scan-action#227)
- SQSCANGHA-138 Update dist and add ci test by [@&#8203;antoine-vinot-sonarsource](https://github.com/antoine-vinot-sonarsource) in [#&#8203;233](SonarSource/sonarqube-scan-action#233)
- SQSCANGHA-140 Add OpenPGP signature verification for scanner downloads by [@&#8203;claire-villard-sonarsource](https://github.com/claire-villard-sonarsource) in [#&#8203;235](SonarSource/sonarqube-scan-action#235)

**Full Changelog**: <SonarSource/sonarqube-scan-action@v7...v7.2.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE1MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL2RlcGVuZGVuY2llcyJdfQ==-->

Reviewed-on: https://git.tainton.uk/repos/roboluke/pulls/445
Co-authored-by: renovate[bot] <renovate-bot@git.tainton.uk>
Co-committed-by: renovate[bot] <renovate-bot@git.tainton.uk>
@claire-villard-sonarsource

Copy link
Copy Markdown
Contributor Author

Thanks you all for pointing this out, and all my apologies for the disruption! We will fix that on a patch version really soon.

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.

6 participants