Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,17 @@ on:
# https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api
permissions:
contents: read
# Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option
pull-requests: write

jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4
# Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options.
with:
comment-summary-in-pr: always
# No PR comment output to keep permissions read-only.
# fail-on-severity: moderate
# deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later
# retry-on-snapshot-warnings: true
46 changes: 41 additions & 5 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ on:
push:
branches:
- main
permissions: {}

jobs:
sonarcloud:
runs-on: ubuntu-latest
environment: org-prod
permissions:
id-token: write
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0

- uses: actions/setup-python@v6
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.12'

Expand All @@ -28,11 +31,43 @@ jobs:
- name: Run tests with coverage
run: make coverage-sonar

- name: Skip SonarCloud on untrusted fork PR
if: ${{ github.event_name == 'pull_request' && (github.event.pull_request.head.repo.fork || !contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
run: |
echo "Skipping SonarCloud token retrieval for untrusted PR context."
echo "Fork PRs and non-collaborator authors do not receive Vault-backed token access."

- name: Azure login (OIDC)
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.fork == false && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}

- name: Read SonarCloud token from Key Vault
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.fork == false && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
id: sonar_token
shell: bash
run: |
set -euo pipefail
SONAR_TOKEN="$(az keyvault secret show \
--vault-name "${{ vars.AZURE_KEYVAULT_NAME }}" \
--name "sonar-cloud-token" \
--query value -o tsv)"
if [ -z "${SONAR_TOKEN}" ]; then
echo "Key Vault secret sonar-cloud-token is empty."
exit 1
fi
echo "::add-mask::$SONAR_TOKEN"
echo "value=$SONAR_TOKEN" >> "$GITHUB_OUTPUT"
Comment on lines +48 to +63
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid direct expression interpolation in run: — use an env: mapping instead.

${{ vars.AZURE_KEYVAULT_NAME }} is interpolated directly into the shell script (line 53). Although vars.* are admin-controlled and the risk is low, this pattern is flagged by GitHub's security hardening guide as a script injection vector. If the variable value ever contained shell metacharacters, it could break or be exploited.

Pass it through env: and reference the environment variable in the script instead:

Proposed fix
       - name: Read SonarCloud token from Key Vault
         if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.fork == false && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
         id: sonar_token
         shell: bash
+        env:
+          VAULT_NAME: ${{ vars.AZURE_KEYVAULT_NAME }}
         run: |
           SONAR_TOKEN="$(az keyvault secret show \
-            --vault-name "${{ vars.AZURE_KEYVAULT_NAME }}" \
+            --vault-name "$VAULT_NAME" \
             --name "sonar-cloud-token" \
             --query value -o tsv)"
           if [ -z "${SONAR_TOKEN}" ]; then
🤖 Prompt for AI Agents
In @.github/workflows/sonarcloud.yml around lines 47 - 61, The run step "Read
SonarCloud token from Key Vault" (id: sonar_token) interpolates `${{
vars.AZURE_KEYVAULT_NAME }}` directly into the shell script; change this to pass
the value via an env mapping (e.g., env: AZURE_KEYVAULT_NAME: ${{
vars.AZURE_KEYVAULT_NAME }}) and then reference it inside the run script as
"$AZURE_KEYVAULT_NAME" when calling az keyvault secret show; ensure the env var
is quoted in the shell invocation and preserve masking/validation of SONAR_TOKEN
as currently done.


- name: SonarCloud scan
uses: SonarSource/sonarcloud-github-action@ffc3010689be73b8e5ae0c57ce35968afd7909e8
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.fork == false && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 # v7.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_TOKEN: ${{ steps.sonar_token.outputs.value }}
with:
args: >
-Dsonar.host.url=https://sonarcloud.io
Expand All @@ -43,10 +78,11 @@ jobs:
-Dsonar.enableIssueAnnotation=true

- name: SonarCloud quality gate
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.fork == false && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)) }}
uses: SonarSource/sonarqube-quality-gate-action@cf038b0e0cdecfa9e56c198bbb7d21d751d62c3b
with:
scanMetadataReportFile: dist/quality/sonar/scannerwork/report-task.txt
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_TOKEN: ${{ steps.sonar_token.outputs.value }}
SONAR_HOST_URL: https://sonarcloud.io
timeout-minutes: 5