Skip to content

Conversation

@tmikula-dev
Copy link
Collaborator

@tmikula-dev tmikula-dev commented Nov 27, 2025

Background

AquaSec scanning workflow to fetch, convert and fill the Security GitHub tab with corresponding GitHub PR comment.

Release Notes

  • AquaSec security scanning workflow

Closes #78

Summary by CodeRabbit

  • Chores
    • Replaced the previous repository security scan with a new full-repository AquaSec scanning integration that collects results, converts them to SARIF, uploads reports to code scanning, and generates a markdown summary for quick review; PRs receive summary links when applicable.
    • Updated ignore rules to exclude a new run script from source control.
  • Revert
    • Removed the prior Trivy-based repository scan workflow.

✏️ Tip: You can customize this high-level summary in your review settings.

@tmikula-dev tmikula-dev self-assigned this Nov 27, 2025
@tmikula-dev tmikula-dev added enhancement New feature or request work in progress Work on this item is not yet finished (mainly intended for PRs) labels Nov 27, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Walkthrough

Removes the Trivy repository scan workflow, adds an AquaSec full-repository scan workflow that HMAC-authenticates, paginates and aggregates scan results, converts findings to SARIF, uploads SARIF via CodeQL action, posts a PR comment when applicable, and adds run.sh to .gitignore. (50 words)

Changes

Cohort / File(s) Change Summary
Removed workflow
\.github/workflows/trivy_repository_scan.yml
Deleted existing Trivy full-repository scan workflow (checkout, Trivy filesystem scan, SARIF upload, PR summary/comment).
Added workflow
\.github/workflows/aquasec_repo_scan.yml
New AquaSec full-repository scan workflow: checkout (full history), HMAC-signed auth to AquaSec API, paginated retrieval of scan results into aquasec_scan_results.json, Python conversion to SARIF 2.1.0 (severity mapping, dedupe rules, sanitize), upload via github/codeql-action/upload-sarif@v4 (category: aquasec), generate Markdown summary to GITHUB_OUTPUT, and optional PR comment posting.
Repository ignore
\.gitignore
Added run.sh to ignored files.

Sequence Diagram(s)

sequenceDiagram
    actor GHA as GitHub Actions
    participant Repo as Repository
    participant Aqua as AquaSec API
    participant Converter as SARIF Converter (Python)
    participant Upload as CodeQL Upload Action
    participant GH as GitHub (PR / Security)

    GHA->>Repo: Checkout (full history)
    GHA->>Aqua: HMAC-authenticate (timestamp, signature)
    Aqua-->>GHA: Bearer token

    rect rgb(230,240,255)
    Note over GHA,Aqua: Paginate and aggregate scan results
    loop per page
        GHA->>Aqua: Fetch results page
        Aqua-->>GHA: Results page
        GHA->>GHA: Append to aquasec_scan_results.json
    end
    end

    rect rgb(240,230,255)
    Note over GHA,Converter: Convert aggregated results → SARIF
    GHA->>Converter: Run conversion (map severities, dedupe rules, sanitize)
    Converter-->>GHA: aquasec_scan.sarif
    end

    rect rgb(230,255,235)
    Note over GHA,Upload: Upload SARIF & publish summary
    GHA->>Upload: Upload SARIF (category: aquasec)
    Upload-->>GHA: Upload confirmation
    GHA->>GHA: Generate Markdown summary (GITHUB_OUTPUT)
    GHA->>GH: Post PR comment with summary (if PR)
    GH-->>GHA: Comment created
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Zejnilovic
  • ABMC831
  • petr-pokorny-absa
  • oto-macenauer-absa

Poem

🐰 I hopped through CI at break of dawn,

Trivy left the meadow, swift and gone,
AquaSec hummed a signed hello,
Pages gathered, findings in a row,
SARIF sprung, and I leapt on.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is largely incomplete and does not follow the required template structure with all expected sections. Add a comprehensive 'Overview' section explaining the problem and feature being implemented. Provide at least 2 complete release notes items instead of just a single generic entry. Keep the related issue reference as provided.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing an API caller for AquaSec full repository scanning, which is the core functionality added by the new workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
.github/workflows/aquasec_repository_scan.yml (2)

33-33: Consider parameterizing hardcoded API endpoints.

The AquaSec API endpoints are hardcoded with specific regions (eu-1 and eu-central-1). This limits flexibility if infrastructure changes or different regions are needed. Consider making these configurable via workflow inputs or environment variables, or document the region strategy.

Also applies to: 68-68


25-80: Add retry logic for network resilience.

The workflow makes multiple HTTP requests (AquaSec auth, GitHub API, AquaSec scan results) without retry logic. Transient network failures will cause the entire workflow to fail. Consider adding exponential backoff retry logic to improve resilience.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc490bf and 10807d7.

📒 Files selected for processing (2)
  • .github/workflows/aquasec_repository_scan.yml (1 hunks)
  • .github/workflows/trivy_repository_scan.yml (0 hunks)
💤 Files with no reviewable changes (1)
  • .github/workflows/trivy_repository_scan.yml
🔇 Additional comments (1)
.github/workflows/aquasec_repository_scan.yml (1)

8-12: Clarify unused security-events: write permission.

The workflow declares security-events: write permission but doesn't upload SARIF results or use GitHub security events API. Given the PR is marked as WIP, clarify whether:

  1. SARIF upload to GitHub Security tab is planned?
  2. GitHub security event integration is part of the roadmap?
  3. This permission should be removed if not needed?

Once the workflow is complete, align permissions with actual usage.

Comment on lines 59 to 64
REPO_ID=$(curl -s "https://api.github.com/repos/${{ github.repository }}" | jq -r '.id')

if [ -z "$REPO_ID" ] || [ "$REPO_ID" = "null" ]; then
echo "Failed to get repository ID from GitHub"
exit 1
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add explicit error handling for GitHub API call and configure timeout.

The curl request to GitHub API (line 59) lacks explicit error handling. If curl fails or hangs, the subsequent check for empty/null REPO_ID will catch the symptom, but the root cause (e.g., network timeout) is masked. Additionally, no timeout is configured, risking indefinite waits.

Apply this diff to add explicit error handling and timeout:

  echo "=== Getting Repository ID from GitHub ==="
  
- REPO_ID=$(curl -s "https://api.github.com/repos/${{ github.repository }}" | jq -r '.id')
+ REPO_ID=$(curl -s --max-time 10 "https://api.github.com/repos/${{ github.repository }}" | jq -r '.id')
+ if [ $? -ne 0 ]; then
+   echo "Failed to query GitHub API"
+   exit 1
+ fi
  
  if [ -z "$REPO_ID" ] || [ "$REPO_ID" = "null" ]; then
    echo "Failed to get repository ID from GitHub"
    exit 1
  fi

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In .github/workflows/aquasec_repository_scan.yml around lines 59 to 64, the curl
call that fetches the GitHub repo ID lacks explicit error handling and a
timeout; update the workflow to call curl with --fail and a --max-time (timeout)
option, capture curl's exit status and stderr output, and if curl fails print a
descriptive error including the curl error/HTTP status and stderr before exiting
non-zero; then proceed to parse REPO_ID and keep the existing empty/null check
as a safety net.

Comment on lines 68 to 77
SCAN_RESULTS_ENDPOINT="https://eu-central-1.edge.cloud.aquasec.com/codesec/api/v1/scans/results"
SCAN_RESULTS=$(curl -s -X GET \
"$SCAN_RESULTS_ENDPOINT?repositoryIds=$REPO_ID" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")

if [ -z "$SCAN_RESULTS" ]; then
echo "Failed to retrieve scan results"
exit 1
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate HTTP response status and add timeout to scan results request.

The curl request (lines 69-72) lacks HTTP status validation. An error response from AquaSec (e.g., 4xx/5xx) could be treated as valid results, potentially masking failures. Additionally, no timeout is configured, risking indefinite waits.

Apply this diff to add status validation and timeout:

  echo "=== Receiving AquaSec Scan Results ==="
  
- SCAN_RESULTS=$(curl -s -X GET \
+ SCAN_RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
    "$SCAN_RESULTS_ENDPOINT?repositoryIds=$REPO_ID" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Accept: application/json")
  
- if [ -z "$SCAN_RESULTS" ]; then
+ SCAN_RESULTS=$(echo "$SCAN_RESPONSE" | head -n -1)
+ HTTP_STATUS=$(echo "$SCAN_RESPONSE" | tail -n 1)
+ 
+ if [ "$HTTP_STATUS" != "200" ]; then
+   echo "AquaSec API returned status $HTTP_STATUS"
    echo "Failed to retrieve scan results"
    exit 1
+ fi
+ 
+ if [ -z "$SCAN_RESULTS" ]; then
+   echo "Scan results are empty"
    exit 1
  fi
📝 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.

Suggested change
SCAN_RESULTS_ENDPOINT="https://eu-central-1.edge.cloud.aquasec.com/codesec/api/v1/scans/results"
SCAN_RESULTS=$(curl -s -X GET \
"$SCAN_RESULTS_ENDPOINT?repositoryIds=$REPO_ID" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")
if [ -z "$SCAN_RESULTS" ]; then
echo "Failed to retrieve scan results"
exit 1
fi
SCAN_RESULTS_ENDPOINT="https://eu-central-1.edge.cloud.aquasec.com/codesec/api/v1/scans/results"
SCAN_RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
"$SCAN_RESULTS_ENDPOINT?repositoryIds=$REPO_ID" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")
SCAN_RESULTS=$(echo "$SCAN_RESPONSE" | head -n -1)
HTTP_STATUS=$(echo "$SCAN_RESPONSE" | tail -n 1)
if [ "$HTTP_STATUS" != "200" ]; then
echo "AquaSec API returned status $HTTP_STATUS"
echo "Failed to retrieve scan results"
exit 1
fi
if [ -z "$SCAN_RESULTS" ]; then
echo "Scan results are empty"
exit 1
fi

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
.github/workflows/aquasec_repository_scan.yml (3)

66-77: Add HTTP status validation and timeout to AquaSec scan results request.

The curl request (lines 69–72) lacks HTTP status validation and a timeout. An error response from AquaSec (e.g., 4xx/5xx) could be parsed as valid results, silently masking failures. Add --max-time, capture HTTP status, and validate it before processing results.

Apply this diff:

  echo "=== Receiving AquaSec Scan Results ==="
  
  SCAN_RESULTS_ENDPOINT="https://eu-central-1.edge.cloud.aquasec.com/codesec/api/v1/scans/results"
- SCAN_RESULTS=$(curl -s -X GET \
+ SCAN_RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
    "$SCAN_RESULTS_ENDPOINT?repositoryIds=$REPO_ID" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Accept: application/json")
  
- if [ -z "$SCAN_RESULTS" ]; then
+ SCAN_RESULTS=$(echo "$SCAN_RESPONSE" | head -n -1)
+ HTTP_STATUS=$(echo "$SCAN_RESPONSE" | tail -n 1)
+ 
+ if [ "$HTTP_STATUS" != "200" ]; then
+   echo "AquaSec API returned HTTP status $HTTP_STATUS"
    echo "Failed to retrieve scan results"
    exit 1
+ fi
+ 
+ if [ -z "$SCAN_RESULTS" ]; then
+   echo "Scan results body is empty"
    exit 1
  fi

30-55: Mask AQUA_SECRET before using it in shell commands to prevent log exposure.

The AQUA_SECRET is used directly in the OpenSSL HMAC calculation (line 37) without masking. If the step fails, debug logging is enabled, or the openssl command outputs diagnostic information, the secret could be leaked into workflow logs. Although BEARER_TOKEN is correctly masked on line 51, AQUA_SECRET should also be masked immediately upon use.

Apply this diff to mask the secret:

  echo "=== Authenticating with AquaSec ==="
  
  TIMESTAMP=$(date -u +%s)
  AUTH_ENDPOINT="https://eu-1.api.cloudsploit.com"
  METHOD="POST"
  POST_BODY='{"validity":240,"allowed_endpoints":["GET","POST"]}'
  STRING_TO_SIGN="${TIMESTAMP}${METHOD}/v2/tokens${POST_BODY}"
+ echo "::add-mask::$AQUA_SECRET"
  SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$AQUA_SECRET" -hex | sed 's/.*= //g')

57-64: Add explicit error handling and timeout to GitHub API call.

The curl request on line 59 lacks error handling and a timeout. If the request hangs or fails, the subsequent check for empty/null REPO_ID masks the root cause. Additionally, silent curl failures are not detected. Add --max-time, explicit error handling, and curl exit code validation.

Apply this diff:

  echo "=== Getting Repository ID from GitHub ==="
  
- REPO_ID=$(curl -s "https://api.github.com/repos/${{ github.repository }}" | jq -r '.id')
+ REPO_ID=$(curl -s --max-time 10 "https://api.github.com/repos/${{ github.repository }}" 2>/dev/null | jq -r '.id' 2>/dev/null)
+ if [ $? -ne 0 ]; then
+   echo "Failed to retrieve repository ID from GitHub API"
+   exit 1
+ fi
  
  if [ -z "$REPO_ID" ] || [ "$REPO_ID" = "null" ]; then
    echo "Failed to get repository ID from GitHub"
    exit 1
  fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77f0e24 and 8d1b523.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repository_scan.yml (1 hunks)

@tmikula-dev tmikula-dev linked an issue Dec 10, 2025 that may be closed by this pull request
@tmikula-dev tmikula-dev requested a review from lsulak as a code owner December 10, 2025 10:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
.github/workflows/aquasec_repository_scan.yml (4)

44-45: Mask AQUA_SECRET before use in HMAC computation.

AQUA_SECRET is used directly in the openssl command without masking. If the step fails or debug logging is enabled, the secret could be exposed in logs.

Apply this diff to mask the secret immediately:

  STRING_TO_SIGN="${TIMESTAMP}${METHOD}/v2/tokens${POST_BODY}"
+ echo "::add-mask::$AQUA_SECRET"
  SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$AQUA_SECRET" -hex | sed 's/.*= //g')

55-64: Validate jq exit code after parsing auth response.

Line 55 assumes jq successfully parsed the response. If the response is malformed or jq fails, RESPONSE_STATUS may be empty or contain an error, and the subsequent check on line 57 will silently fail.

Apply this diff:

  RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status' 2>/dev/null)
+ if [ $? -ne 0 ]; then
+   echo "Failed to parse AquaSec authentication response"
+   exit 1
+ fi
  
  if [ "$RESPONSE_STATUS" = "200" ]; then

79-80: Export scan results to GITHUB_OUTPUT for downstream job consumption.

The workflow outputs results to stdout but does not emit them as a GitHub Actions workflow output. To allow downstream jobs to consume the scan results, append them to GITHUB_OUTPUT using a heredoc pattern to preserve newlines and special characters.

Apply this diff:

  echo "=== Scan Results ==="
  echo "$SCAN_RESULTS" | jq '.'
+ echo "scan_results<<EOF" >> $GITHUB_OUTPUT
+ echo "$SCAN_RESULTS" >> $GITHUB_OUTPUT
+ echo "EOF" >> $GITHUB_OUTPUT

69-72: Fix malformed curl URL syntax; close quote before line continuation.

Line 70 has a syntax error: the URL string is not properly terminated before the backslash continuation. The shell will fail to parse this command.

Additionally, no HTTP status code validation is performed, so 4xx/5xx error responses from AquaSec will be treated as valid results.

Apply this diff to fix the syntax and add HTTP status validation:

- SCAN_RESULTS=$(curl -s -X GET \
+ SCAN_RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
-   "$SCAN_RESULTS_ENDPOINT?repositoryIds=${{ github.repository_id }} \
+   "$SCAN_RESULTS_ENDPOINT?repositoryIds=${{ github.repository_id }}" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Accept: application/json")
+ 
+ SCAN_RESULTS=$(echo "$SCAN_RESPONSE" | head -n -1)
+ HTTP_STATUS=$(echo "$SCAN_RESPONSE" | tail -n 1)
+ 
+ if [ "$HTTP_STATUS" != "200" ]; then
+   echo "AquaSec API returned status $HTTP_STATUS"
+   echo "Failed to retrieve scan results"
+   exit 1
+ fi
🧹 Nitpick comments (1)
.github/workflows/aquasec_repository_scan.yml (1)

74-77: Add explicit check for empty scan results after HTTP validation.

Once HTTP status validation is added (see previous comment), add an explicit empty-content check as a secondary safety net.

Apply this diff after HTTP validation:

+ if [ -z "$SCAN_RESULTS" ]; then
+   echo "Scan results are empty"
+   exit 1
+ fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d1b523 and 371f052.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repository_scan.yml (1 hunks)

Comment on lines 48 to 53
AUTH_RESPONSE=$(curl -s -X "$METHOD" "$AUTH_ENDPOINT" \
-H "Content-Type: application/json" \
-H "X-API-Key: $AQUA_KEY" \
-H "X-Signature: $SIGNATURE" \
-H "X-Timestamp: $TIMESTAMP" \
-d "$POST_BODY")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add timeout to AquaSec authentication curl call.

The auth request to AquaSec (lines 48–53) lacks a timeout. If the network hangs or the endpoint is unreachable, the step will block indefinitely. Add --max-time 10 to curl.

Apply this diff:

- AUTH_RESPONSE=$(curl -s -X "$METHOD" "$AUTH_ENDPOINT" \
+ AUTH_RESPONSE=$(curl -s --max-time 10 -X "$METHOD" "$AUTH_ENDPOINT" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: $AQUA_KEY" \
    -H "X-Signature: $SIGNATURE" \
    -H "X-Timestamp: $TIMESTAMP" \
    -d "$POST_BODY")
📝 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.

Suggested change
AUTH_RESPONSE=$(curl -s -X "$METHOD" "$AUTH_ENDPOINT" \
-H "Content-Type: application/json" \
-H "X-API-Key: $AQUA_KEY" \
-H "X-Signature: $SIGNATURE" \
-H "X-Timestamp: $TIMESTAMP" \
-d "$POST_BODY")
AUTH_RESPONSE=$(curl -s --max-time 10 -X "$METHOD" "$AUTH_ENDPOINT" \
-H "Content-Type: application/json" \
-H "X-API-Key: $AQUA_KEY" \
-H "X-Signature: $SIGNATURE" \
-H "X-Timestamp: $TIMESTAMP" \
-d "$POST_BODY")
🤖 Prompt for AI Agents
.github/workflows/aquasec_repository_scan.yml around lines 48 to 53: the curl
call used for AquaSec authentication lacks a timeout which can cause the step to
hang indefinitely if the network or endpoint is unresponsive; add the curl
option --max-time 10 to the command so the request will fail after 10 seconds,
keeping other headers and payload intact.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
.github/workflows/aquasec_repository_scan.yml (4)

47-52: Add timeout to AquaSec authentication curl request.

The curl call lacks a timeout. If the AquaSec endpoint is unresponsive, the step will block indefinitely. Add --max-time 10 to ensure the request fails after 10 seconds.

Apply this diff:

- AUTH_RESPONSE=$(curl -s -X "$METHOD" "$AUTH_ENDPOINT" \
+ AUTH_RESPONSE=$(curl -s --max-time 10 -X "$METHOD" "$AUTH_ENDPOINT" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: $AQUA_KEY" \
    -H "X-Signature: $SIGNATURE" \
    -H "X-Timestamp: $TIMESTAMP" \
    -d "$POST_BODY")

78-79: Export scan results via GITHUB_OUTPUT for downstream job access.

The workflow outputs scan results to stdout but does not export them via GITHUB_OUTPUT. As described in the PR objectives, results should be emitted so downstream jobs can consume them. Add a multi-line output block.

Apply this diff:

  echo "=== Scan Results ==="
  echo "$SCAN_RESULTS" | jq '.'
+ echo "scan_results<<EOF" >> $GITHUB_OUTPUT
+ echo "$SCAN_RESULTS" >> $GITHUB_OUTPUT
+ echo "EOF" >> $GITHUB_OUTPUT

32-44: Mask AQUA_SECRET before use in HMAC calculation.

The AQUA_SECRET is used directly in the openssl command (line 44) without masking. If the step fails or debug logging is enabled, the secret could be exposed in workflow logs. Mask it immediately before the HMAC calculation.

Apply this diff to mask the secret:

  STRING_TO_SIGN="${TIMESTAMP}${METHOD}/v2/tokens${POST_BODY}"
+ echo "::add-mask::$AQUA_SECRET"
  SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$AQUA_SECRET" -hex | sed 's/.*= //g')

68-71: Fix syntax error in curl URL and add timeout and HTTP status validation.

Syntax Error: Line 69 is missing a closing quote after the URL parameter. The URL will be malformed, causing curl to fail.

Reliability Issues: The curl request lacks timeout and HTTP status validation. If AquaSec returns an error (4xx/5xx), it will be treated as valid results, potentially masking failures.

Apply this diff to fix the syntax error and add timeout/status validation:

  SCAN_RESULTS_ENDPOINT="https://eu-central-1.edge.cloud.aquasec.com/codesec/api/v1/scans/results"
- SCAN_RESULTS=$(curl -s -X GET \
-   "$SCAN_RESULTS_ENDPOINT?repositoryIds=${{ github.repository_id }} \
+ SCAN_RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
+   "$SCAN_RESULTS_ENDPOINT?repositoryIds=${{ github.repository_id }}" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Accept: application/json")
+ 
+ SCAN_RESULTS=$(echo "$SCAN_RESPONSE" | head -n -1)
+ HTTP_STATUS=$(echo "$SCAN_RESPONSE" | tail -n 1)
+ 
+ if [ "$HTTP_STATUS" != "200" ]; then
+   echo "AquaSec API returned HTTP status $HTTP_STATUS"
+   echo "Failed to retrieve scan results"
+   exit 1
+ fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 371f052 and 057d3f8.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repository_scan.yml (1 hunks)
🔇 Additional comments (3)
.github/workflows/aquasec_repository_scan.yml (3)

20-23: LGTM — checkout is properly configured.

The upgrade to actions/checkout@v6 addresses the prior review feedback, and disabling persist-credentials follows security best practices.


8-12: Permissions are appropriately scoped.

The permissions block correctly enables the actions needed (contents: read for checkout, write permissions for security events, PR comments, etc.) while maintaining least-privilege principles.


1-17: Workflow trigger and job configuration are appropriate.

The workflow correctly triggers on both manual dispatch and pull requests, with a clear job name and appropriate runner selection.

Comment on lines 54 to 63
RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status')

if [ "$RESPONSE_STATUS" = "200" ]; then
echo "Login successful."
BEARER_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data')
echo "::add-mask::$BEARER_TOKEN"
else
echo "Login failed"
exit 1
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for jq parsing of authentication response.

The jq call on line 54 assumes the response is valid JSON. If jq fails or the response is malformed, the error is silent. Additionally, if .status or .data fields are missing, the behavior is undefined. Add explicit error handling.

Apply this diff:

  RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status' 2>/dev/null)
+ if [ $? -ne 0 ] || [ -z "$RESPONSE_STATUS" ]; then
+   echo "Failed to parse AquaSec authentication response"
+   echo "Response: $AUTH_RESPONSE"
+   exit 1
+ fi
  
  if [ "$RESPONSE_STATUS" = "200" ]; then
    echo "Login successful."
    BEARER_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data' 2>/dev/null)
+   if [ $? -ne 0 ] || [ -z "$BEARER_TOKEN" ]; then
+     echo "Failed to extract bearer token from response"
+     exit 1
+   fi
    echo "::add-mask::$BEARER_TOKEN"
  else
    echo "Login failed"
    exit 1
  fi

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/aquasec_repository_scan.yml around lines 54 to 63: the script
assumes AUTH_RESPONSE is valid JSON and blindly extracts .status and .data with
jq; add robust error handling by first ensuring jq succeeds (check jq exit code
and/or use set -o pipefail before pipelines), validate that RESPONSE_STATUS is
non-empty and numeric (or exactly "200") and that BEARER_TOKEN is non-empty
before masking/using it, and on any jq parse failure or missing field print
AUTH_RESPONSE (or a truncated safe snippet), log a clear error message, and exit
with non-zero status; ensure any jq invocation uses -e or tests for null to
detect missing fields so malformed responses don't silently proceed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (5)
.github/workflows/aquasec_repository_scan.yml (5)

78-79: Export scan results via GITHUB_OUTPUT for downstream job access.

The workflow echoes scan results to stdout but does not emit them as a GitHub Actions output. Per the PR description, the workflow should "emit the scan JSON via GITHUB_OUTPUT" so downstream jobs can consume it.

Apply this diff to export the results:

  echo "=== Scan Results ==="
  echo "$SCAN_RESULTS" | jq '.'
+ 
+ # Export as multi-line output to preserve JSON formatting
+ {
+   echo "scan_results<<EOF"
+   echo "$SCAN_RESULTS"
+   echo "EOF"
+ } >> $GITHUB_OUTPUT

54-63: Add explicit error handling for jq parsing of authentication response.

The jq calls assume the response is valid JSON. If jq fails or fields are missing, errors are silent. Validate that jq parsing succeeds and that extracted values are non-empty before use.

Apply this diff:

  RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status')
+ if [ $? -ne 0 ] || [ -z "$RESPONSE_STATUS" ]; then
+   echo "Failed to parse AquaSec authentication response"
+   exit 1
+ fi
  
  if [ "$RESPONSE_STATUS" = "200" ]; then
    echo "Login successful."
    BEARER_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data')
+   if [ $? -ne 0 ] || [ -z "$BEARER_TOKEN" ]; then
+     echo "Failed to extract bearer token from response"
+     exit 1
+   fi
    echo "::add-mask::$BEARER_TOKEN"
  else
    echo "Login failed"
    exit 1
  fi

44-44: Mask AQUA_SECRET before use to prevent exposure in logs.

The AQUA_SECRET is used directly in the HMAC calculation without masking. If the step fails or debug logging is enabled, the secret could be exposed in workflow logs. Mask it immediately before the shell command that references it.

Apply this diff:

  STRING_TO_SIGN="${TIMESTAMP}${METHOD}/v2/tokens${POST_BODY}"
+ echo "::add-mask::$AQUA_SECRET"
  SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$AQUA_SECRET" -hex | sed 's/.*= //g')

47-52: Add timeout and error handling to AquaSec authentication curl call.

The curl request lacks both a timeout (risking indefinite hangs) and explicit error handling. If curl fails or the endpoint is unreachable, the failure is not caught until a downstream check on the token.

Apply this diff to add timeout and error handling:

- AUTH_RESPONSE=$(curl -s -X "$METHOD" "$AUTH_ENDPOINT" \
+ AUTH_RESPONSE=$(curl -s --max-time 10 -w "\n%{http_code}" -X "$METHOD" "$AUTH_ENDPOINT" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: $AQUA_KEY" \
    -H "X-Signature: $SIGNATURE" \
    -H "X-Timestamp: $TIMESTAMP" \
    -d "$POST_BODY")
+ 
+ HTTP_STATUS=$(echo "$AUTH_RESPONSE" | tail -n 1)
+ AUTH_RESPONSE=$(echo "$AUTH_RESPONSE" | head -n -1)
+ 
+ if [ "$HTTP_STATUS" != "200" ]; then
+   echo "AquaSec authentication failed with HTTP status $HTTP_STATUS"
+   exit 1
+ fi

68-76: Add timeout and HTTP status validation to scan results retrieval.

The curl request (after fixing the syntax error above) lacks a timeout and HTTP status validation. If AquaSec returns a 4xx/5xx error, it will be treated as valid results, masking the failure. Additionally, no timeout is configured, risking indefinite waits.

Apply this diff to add timeout and HTTP status validation:

  SCAN_RESULTS=$(curl -s -w "\n%{http_code}" --max-time 10 -X GET \
    "$SCAN_RESULTS_ENDPOINT?repositoryIds=${{ github.repository_id }}" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Accept: application/json")
  
+ SCAN_HTTP_STATUS=$(echo "$SCAN_RESULTS" | tail -n 1)
+ SCAN_RESULTS=$(echo "$SCAN_RESULTS" | head -n -1)
+ 
+ if [ "$SCAN_HTTP_STATUS" != "200" ]; then
+   echo "AquaSec API returned HTTP status $SCAN_HTTP_STATUS"
+   exit 1
+ fi
+ 
  if [ -z "$SCAN_RESULTS" ]; then
    echo "Failed to retrieve scan results"
    exit 1
  fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 057d3f8 and 0d3ff0e.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repository_scan.yml (1 hunks)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
.github/workflows/aquasec_repo_scan.yml (4)

43-43: Secret may be exposed in process listing.

Using ${AQUA_SECRET} directly in the openssl command line argument could expose the secret in process listings (ps aux). Consider using stdin or environment variable approach.

🔎 Proposed fix using stdin
-          SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "${AQUA_SECRET}" -hex | sed 's/.*= //g')
+          SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$(cat <<< "$AQUA_SECRET")" -hex | sed 's/.*= //g')

Alternatively, you could use a file descriptor or heredoc approach to avoid the secret appearing in command arguments.


134-135: Add error handling for file operations.

The file read operation lacks error handling. If aquasec_scan_results.json doesn't exist or is malformed, the script will fail with an unclear error message.

🔎 Proposed fix
+          import sys
+          
+          try:
-          with open("aquasec_scan_results.json", "r") as f:
-              data = json.load(f)
+              with open("aquasec_scan_results.json", "r") as f:
+                  data = json.load(f)
+          except FileNotFoundError:
+              print("Error: aquasec_scan_results.json not found", file=sys.stderr)
+              sys.exit(1)
+          except json.JSONDecodeError as e:
+              print(f"Error: Invalid JSON in aquasec_scan_results.json: {e}", file=sys.stderr)
+              sys.exit(1)

248-248: Consider externalizing the categories list.

The hardcoded CATEGORIES list must stay in sync with what AquaSec returns. If AquaSec adds new categories, they won't appear in the summary. Consider dynamically discovering categories from the SARIF data, or document this dependency.


54-60: Mask the bearer token to prevent log exposure.

The BEARER_TOKEN should be masked using ::add-mask:: to prevent it from appearing in workflow logs if any subsequent command inadvertently echoes it.

🔎 Proposed fix
           if [ "$RESPONSE_STATUS" = "200" ]; then
             echo "Login successful."
             BEARER_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data')
+            echo "::add-mask::$BEARER_TOKEN"
           else
             echo "Login failed with error message: $(echo "$AUTH_RESPONSE" | jq -r '.errors')"
             exit 1
           fi
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a661cb0 and 0ec7cec.

📒 Files selected for processing (2)
  • .github/workflows/aquasec_repo_scan.yml
  • .gitignore
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🔇 Additional comments (5)
.github/workflows/aquasec_repo_scan.yml (5)

1-16: LGTM!

Workflow triggers, permissions, and concurrency configuration are well-defined. The minimal required permissions follow the principle of least privilege.


142-207: LGTM!

The SARIF conversion logic is well-implemented:

  • Proper severity mapping with fallback
  • Rule deduplication using avd_id
  • Line number sanitization to meet SARIF schema requirements
  • Fingerprints for cross-scan deduplication

231-235: LGTM!

Standard usage of the CodeQL SARIF upload action with an appropriate category identifier.


251-264: Good error handling pattern.

The try-except block properly handles file I/O errors and JSON parsing issues with clear error messages to stderr.


23-27: [No action needed] — actions/checkout@v6 is the current latest version and is correctly specified in the workflow.

Likely an incorrect or invalid review comment.

Comment on lines 325 to 331
const summaryTable = `${{ steps.scan_summary_table.outputs.table }}`;
const body = `${sentence}\n\n${summaryTable}`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add await and consider escaping the summary table.

  1. The github.rest.issues.createComment() call should be awaited.
  2. The summaryTable is directly interpolated from step output, which could break the script if it contains backticks or ${...} patterns.
🔎 Proposed fix
           script: |
             const link = `https://github.com/${context.repo.owner}/${context.repo.repo}/security/code-scanning?query=pr%3A${context.issue.number}+is%3Aopen`;
             const sentence = `AquaSec has completed a full security repository scan ✅ You can find the analysis results for this PR branch on [this overview](${link}).\n Below is the summary of the findings:`;
-            const summaryTable = `${{ steps.scan_summary_table.outputs.table }}`;
-            const body = `${sentence}\n\n${summaryTable}`;
-            github.rest.issues.createComment({
+            const summaryTable = process.env.SUMMARY_TABLE;
+            const body = sentence + "\n\n" + summaryTable;
+            await github.rest.issues.createComment({
               issue_number: context.issue.number,
               owner: context.repo.owner,
               repo: context.repo.repo,
               body
             });
+        env:
+          SUMMARY_TABLE: ${{ steps.scan_summary_table.outputs.table }}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/aquasec_repo_scan.yml lines 325-331: the createComment() call
is not awaited and the summaryTable output is interpolated raw which can break
if it contains backticks or `${...}` patterns; fix by awaiting the
github.rest.issues.createComment(...) call and sanitize/escape the summaryTable
before interpolation (e.g., replace backticks with escaped backticks and replace
`${` with `$\{` or otherwise escape problematic sequences) so the body string
cannot terminate or re-evaluate templates.

@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

@github-actions
Copy link

AquaSec has completed a full security repository scan ✅ You can find the analysis results for this PR branch on this overview.
Below is the summary of the findings:

AQUASEC CRITICAL HIGH MEDIUM LOW TOTAL
sast 0 4 2 0 6
vulnerabilities 0 0 0 0 0
iacMisconfigurations 0 0 1 10 11
secrets 0 6 0 0 6
pipelineMisconfigurations 0 0 3 4 7
license 0 0 0 0 0
➡️ Total 0 10 6 14 30

@github-actions
Copy link

AquaSec has completed a full security repository scan ✅ You can find the analysis results for this PR branch on this overview.
Below is the summary of the findings:

AQUASEC CRITICAL HIGH MEDIUM LOW TOTAL
sast 0 4 2 0 6
vulnerabilities 0 0 0 0 0
iacMisconfigurations 0 0 1 10 11
secrets 0 0 0 0 0
pipelineMisconfigurations 0 0 3 4 7
license 0 0 0 0 0
➡️ Total 0 4 6 14 24

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
.github/workflows/aquasec_repo_scan.yml (4)

53-68: Consider adding --fail-with-body for better HTTP error handling.

The curl command with --max-time 30 doesn't fail on HTTP error responses (4xx/5xx). While the script checks .status from the JSON response, if AquaSec returns a non-JSON error page, jq may fail or return unexpected results.

🔎 Proposed fix
-          AUTH_RESPONSE=$(curl -s --max-time 30 -X $METHOD "$AUTH_ENDPOINT" \
+          AUTH_RESPONSE=$(curl -s --fail-with-body --max-time 30 -X $METHOD "$AUTH_ENDPOINT" \
             -H "Content-Type: application/json" \
             -H "X-API-Key: $AQUA_KEY" \
             -H "X-Timestamp: $TIMESTAMP" \
             -H "X-Signature: $SIGNATURE" \
-            -d "$POST_BODY")
+            -d "$POST_BODY") || {
+            echo "Error: Authentication request failed"
+            exit 1
+          }

83-90: Add error handling for scan results API call.

Similar to the authentication call, the pagination API call should handle HTTP errors and validate the response format before parsing.

🔎 Proposed fix
-            PAGE_RESPONSE=$(curl -s --max-time 30 -X GET "$REQUEST_URL" \
+            PAGE_RESPONSE=$(curl -s --fail-with-body --max-time 30 -X GET "$REQUEST_URL" \
               -H "Authorization: Bearer $BEARER_TOKEN" \
-              -H "Accept: application/json")
+              -H "Accept: application/json") || {
+              echo "Error: Failed to fetch page $PAGE_NUM"
+              exit 1
+            }
           
             if [ -z "$PAGE_RESPONSE" ]; then
               echo "Failed to retrieve scan results on page $PAGE_NUM"
               exit 1
             fi
+            
+            if ! echo "$PAGE_RESPONSE" | jq -e . >/dev/null 2>&1; then
+              echo "Error: Invalid JSON response on page $PAGE_NUM"
+              exit 1
+            fi

142-148: Add error handling for JSON file operations.

The file read operation lacks exception handling. If aquasec_scan_results.json is missing or contains invalid JSON, the script will fail with an unclear error message.

🔎 Proposed fix
+          import sys
+          
+          try:
-          with open("aquasec_scan_results.json", "r") as f:
-              data = json.load(f)
+              with open("aquasec_scan_results.json", "r", encoding="utf-8") as f:
+                  data = json.load(f)
+          except (IOError, json.JSONDecodeError) as e:
+              print(f"Error reading scan results: {e}", file=sys.stderr)
+              sys.exit(1)

256-256: Note: Categories list is hardcoded.

The CATEGORIES list is hardcoded. If AquaSec introduces new finding categories in the future, they won't appear in the summary table. Consider whether dynamically discovering categories from the SARIF data would be more maintainable.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02a236b and 9ebfc65.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repo_scan.yml
🔇 Additional comments (6)
.github/workflows/aquasec_repo_scan.yml (6)

1-17: LGTM!

The workflow configuration is well-structured with appropriate permissions scoped to what's needed (security-events for SARIF upload, issues/pull-requests for commenting). The concurrency configuration correctly prevents duplicate runs on the same branch.


217-237: LGTM!

The SARIF output structure is well-formed and compliant with the 2.1.0 schema. The tool driver includes all required fields, and findings are correctly mapped with rule indices and physical locations.


239-243: LGTM!

The SARIF upload step correctly uses the CodeQL action with appropriate parameters. The category: aquasec ensures these results are properly labeled in the Security tab.


260-324: LGTM!

The summary table generation is well-implemented with proper error handling for file operations, bounds checking on rule indices, and correct use of the GITHUB_OUTPUT heredoc pattern for multi-line values.


326-343: LGTM!

The PR comment step is well-implemented. The previous review concerns have been addressed:

  • await is now correctly used for the API call
  • The summary table is safely passed via environment variable, preventing template injection issues

23-27: No issues found — actions/checkout@v6 is a valid, released version.

@github-actions
Copy link

github-actions bot commented Dec 30, 2025

AquaSec has completed a full security repository scan ✅ You can find the analysis results for this PR branch on this overview.
Below is the summary of the findings:

AQUASEC CRITICAL HIGH MEDIUM LOW TOTAL
sast 0 4 2 0 6
vulnerabilities 0 0 0 0 0
iacMisconfigurations 0 0 1 10 11
secrets 0 0 0 0 0
pipelineMisconfigurations 0 0 3 4 7
license 0 0 0 0 0
➡️ Total 0 4 6 14 24

@tmikula-dev tmikula-dev removed the work in progress Work on this item is not yet finished (mainly intended for PRs) label Dec 30, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
.github/workflows/aquasec_repo_scan.yml (1)

27-27: Consider removing full history fetch.

The fetch-depth: 0 fetches the entire repository history, which can significantly slow down the workflow for large repositories. Security scans typically only need the current code state.

🔎 Proposed optimization
-          fetch-depth: 0
+          fetch-depth: 1
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ebfc65 and 0d9ddf0.

📒 Files selected for processing (1)
  • .github/workflows/aquasec_repo_scan.yml
🔇 Additional comments (5)
.github/workflows/aquasec_repo_scan.yml (5)

101-116: LGTM - Variable expansion issues resolved.

The shell variable references now correctly use the $ prefix and proper quoting. The pagination logic correctly aggregates findings and constructs the final JSON output.


190-195: LGTM - Good defensive line number sanitization.

The line number validation ensures SARIF schema compliance by enforcing start_line >= 1 and end_line >= start_line, preventing invalid region data.


234-238: LGTM - Standard SARIF upload configuration.

The upload-sarif action is correctly configured with the generated SARIF file and a category identifier for filtering in the GitHub Security tab.


240-319: LGTM - Well-structured summary generation with proper error handling.

The script correctly processes the SARIF file, aggregates findings by category and severity, and writes the markdown table to GITHUB_OUTPUT using the EOF delimiter for multiline content. Error handling for file I/O and JSON parsing is comprehensive.


321-359: LGTM - Previous review issues have been resolved.

The await keywords are now present on all GitHub API calls (lines 336, 346, 353), and the summary table is safely accessed via process.env.SUMMARY_TABLE rather than direct template interpolation, preventing any injection vulnerabilities. The marker-based logic correctly handles updating existing comments or creating new ones.

Comment on lines +53 to +68
AUTH_RESPONSE=$(curl -s --max-time 30 -X $METHOD "$AUTH_ENDPOINT" \
-H "Content-Type: application/json" \
-H "X-API-Key: $AQUA_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
-d "$POST_BODY")

RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status')

if [ "$RESPONSE_STATUS" = "200" ]; then
echo "Login successful."
BEARER_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data')
else
echo "Login failed with error message: $(echo "$AUTH_RESPONSE" | jq -r '.errors')"
exit 1
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add HTTP status code checking to curl request.

The curl command doesn't fail on HTTP errors by default. If the authentication endpoint returns a 4xx or 5xx status, the script may process an HTML error page as JSON, leading to confusing error messages or silent failures.

🔎 Proposed fix
-          AUTH_RESPONSE=$(curl -s --max-time 30 -X $METHOD "$AUTH_ENDPOINT" \
+          HTTP_CODE=$(curl -s --max-time 30 -w "%{http_code}" -o auth_response.tmp -X $METHOD "$AUTH_ENDPOINT" \
             -H "Content-Type: application/json" \
             -H "X-API-Key: $AQUA_KEY" \
             -H "X-Timestamp: $TIMESTAMP" \
             -H "X-Signature: $SIGNATURE" \
             -d "$POST_BODY")
           
+          if [ "$HTTP_CODE" -ne 200 ]; then
+            echo "HTTP request failed with status code: $HTTP_CODE"
+            cat auth_response.tmp
+            exit 1
+          fi
+          
+          AUTH_RESPONSE=$(cat auth_response.tmp)
           RESPONSE_STATUS=$(echo "$AUTH_RESPONSE" | jq -r '.status')
🤖 Prompt for AI Agents
.github/workflows/aquasec_repo_scan.yml around lines 53 to 68: the curl call
does not fail on HTTP errors so an HTML error page can be treated as JSON;
update the curl invocation to fail on HTTP errors and expose the HTTP status
code (for example use curl --fail --show-error -s -D - or use -w '%{http_code}'
to capture status into a variable), then check curl's exit status and the
returned HTTP status before attempting to parse JSON with jq; on non-2xx
responses print the raw body and status and exit with a non-zero code.

Comment on lines +83 to +90
PAGE_RESPONSE=$(curl -s --max-time 30 -X GET "$REQUEST_URL" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")

if [ -z "$PAGE_RESPONSE" ]; then
echo "Failed to retrieve scan results on page $PAGE_NUM"
exit 1
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add HTTP status code checking to curl request.

Similar to the authentication request, this curl command should verify the HTTP status code to distinguish between network/HTTP errors and successful responses with error data.

🔎 Proposed fix
-            PAGE_RESPONSE=$(curl -s --max-time 30 -X GET "$REQUEST_URL" \
+            HTTP_CODE=$(curl -s --max-time 30 -w "%{http_code}" -o page_response.tmp -X GET "$REQUEST_URL" \
               -H "Authorization: Bearer $BEARER_TOKEN" \
               -H "Accept: application/json")
           
-            if [ -z "$PAGE_RESPONSE" ]; then
-              echo "Failed to retrieve scan results on page $PAGE_NUM"
+            if [ "$HTTP_CODE" -ne 200 ]; then
+              echo "HTTP request failed with status code: $HTTP_CODE on page $PAGE_NUM"
+              cat page_response.tmp
               exit 1
             fi
+            
+            PAGE_RESPONSE=$(cat page_response.tmp)
📝 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.

Suggested change
PAGE_RESPONSE=$(curl -s --max-time 30 -X GET "$REQUEST_URL" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")
if [ -z "$PAGE_RESPONSE" ]; then
echo "Failed to retrieve scan results on page $PAGE_NUM"
exit 1
fi
HTTP_CODE=$(curl -s --max-time 30 -w "%{http_code}" -o page_response.tmp -X GET "$REQUEST_URL" \
-H "Authorization: Bearer $BEARER_TOKEN" \
-H "Accept: application/json")
if [ "$HTTP_CODE" -ne 200 ]; then
echo "HTTP request failed with status code: $HTTP_CODE on page $PAGE_NUM"
cat page_response.tmp
exit 1
fi
PAGE_RESPONSE=$(cat page_response.tmp)
🤖 Prompt for AI Agents
.github/workflows/aquasec_repo_scan.yml around lines 83 to 90: the curl call
only checks for empty response body and not the HTTP status code; change the
curl invocation to capture both response body and HTTP status code (e.g., write
body to a temp file and use curl -w to emit the status), then check the status
code is 2xx before proceeding; if the status is non-2xx, print an error with the
status and response body and exit with failure so network/HTTP errors are
distinguished from successful responses containing error payloads.

Comment on lines +172 to +175
"help": {
"text": truncate(remediation),
"markdown": f"**{category} {avd_id}**\n| Severity | Check | Message |\n| --- | --- | --- |\n|{sev_tag}|{truncate(title, 100)}|{truncate(message, 200)}|"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Sanitize markdown special characters in help field.

The markdown table directly embeds title and message without escaping special characters like |, *, [, ], etc. Pipe characters will break the table structure, and other markdown syntax could affect rendering in the GitHub Security tab.

🔎 Proposed fix
+          # Escape markdown special characters
+          def escape_markdown(text, max_len):
+              text = truncate(text, max_len)
+              # Escape pipe and other markdown special chars
+              return text.replace('|', '\\|').replace('*', '\\*').replace('[', '\\[').replace(']', '\\]')
+          
                      "help": {
                          "text": truncate(remediation),
-                          "markdown": f"**{category} {avd_id}**\n| Severity | Check | Message |\n| --- | --- | --- |\n|{sev_tag}|{truncate(title, 100)}|{truncate(message, 200)}|"
+                          "markdown": f"**{category} {avd_id}**\n| Severity | Check | Message |\n| --- | --- | --- |\n|{sev_tag}|{escape_markdown(title, 100)}|{escape_markdown(message, 200)}|"
                      },
📝 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.

Suggested change
"help": {
"text": truncate(remediation),
"markdown": f"**{category} {avd_id}**\n| Severity | Check | Message |\n| --- | --- | --- |\n|{sev_tag}|{truncate(title, 100)}|{truncate(message, 200)}|"
},
# Escape markdown special characters
def escape_markdown(text, max_len):
text = truncate(text, max_len)
# Escape pipe and other markdown special chars
return text.replace('|', '\\|').replace('*', '\\*').replace('[', '\\[').replace(']', '\\]')
"help": {
"text": truncate(remediation),
"markdown": f"**{category} {avd_id}**\n| Severity | Check | Message |\n| --- | --- | --- |\n|{sev_tag}|{escape_markdown(title, 100)}|{escape_markdown(message, 200)}|"
},
🤖 Prompt for AI Agents
In .github/workflows/aquasec_repo_scan.yml around lines 172-175, the markdown
table inserts raw title and message which can contain characters (|, *, _, `[`,
`]`, backticks, <, >, &) that break table formatting or alter rendering; add and
call a small escape helper (e.g., escapeMarkdown) to sanitize title and message
before embedding in the markdown string — at minimum replace '|' with '\|' and
escape backslashes and the common markdown/control characters (\, *, _, `, [, ],
<, >, &) by prefixing with backslash or converting to safe entities; use the
escaped values in the truncate/markdown assembly so the table remains intact and
safe for the GitHub Security tab.

Copy link
Contributor

@miroslavpojer miroslavpojer left a comment

Choose a reason for hiding this comment

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

I like this solution.

I preffer to create a GH action to host it and deliver short workflow using it in this repository.

runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
Copy link
Contributor

Choose a reason for hiding this comment

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

You should use GH sha instead of tags to avoid error report - AVD-PIPELINE-0008.

persist-credentials: false
fetch-depth: 0

- name: Retrieve AquaSec Scan Results
Copy link
Contributor

Choose a reason for hiding this comment

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

I propose to create a GH action from this long piece of code.
We need to spread this across all of our repos - it would be more sexy.

Let's talk about steps from this pipeline should be implemented by this new GH action.

@miroslavpojer
Copy link
Contributor

  1. After migration to new action - do re-review of AI reviewer comments.
  2. I can confirm the for this report the Overview table show all 24 known alerts visible in Aquasec - same groups, priorities, ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API caller for AquaSec full repository scan report

3 participants