Skip to content

Azure Pipelines advanced patterns: API gate, UI publishing, central template#4

Closed
appsechq-brian wants to merge 14 commits into
mainfrom
feature/cycode-advanced-patterns
Closed

Azure Pipelines advanced patterns: API gate, UI publishing, central template#4
appsechq-brian wants to merge 14 commits into
mainfrom
feature/cycode-advanced-patterns

Conversation

@appsechq-brian
Copy link
Copy Markdown
Member

Summary

Staging branch for three Azure Pipelines integration patterns that extend the existing CLI gate in azure-pipelines.yml. Not meant to merge to main here — this is a reference copy for customer visibility. The customer-facing doc is in se-copilot/artifacts/azure-pipelines-cycode-advanced-patterns.md.

Patterns added

  • API gatescripts/cycode-gate.sh queries the Cycode RIG Graph API for Open violations in a named repo and exits non-zero on match. Tunable via SEVERITY_MIN, CATEGORY, RISK_SCORE_MIN.
  • Results in Azure UIscripts/cycode-json-to-junit.py + scripts/cycode-summary.py transform cycode -o json scan ... output for PublishTestResults@2 (Tests tab) and ##vso[task.uploadsummary] (custom tab). Raw JSON also published via PublishBuildArtifacts@1.
  • Centralized templatetemplates/cycode-scan.yml owns the scan + publish + gate logic. Consumers extends it and pass parameters. Cross-repo usage documented in the template header.

Example pipelines

File Purpose
azure-pipelines-api-gate.yml Standalone API gate
azure-pipelines-publish-results.yml All three UI surfaces populated from one scan
azure-pipelines-template-consumer.yml Minimal consumer of templates/cycode-scan.yml

Real deployment target

Customer will configure and test in a private Azure DevOps environment with a self-hosted runner. pool: name: Default matches the existing pipeline; swap to ubuntu-latest for Microsoft-hosted agents.

Secrets needed

Azure DevOps: CYCODE_CLIENT_ID, CYCODE_CLIENT_SECRET as secret pipeline variables (ideally via Variable Group backed by Key Vault).

Test plan

  • Run scripts/cycode-gate.sh locally with real env vars against levine-se-playground to confirm the RIG filter on detection_details.repository_name resolves
  • Deploy to customer's test Azure DevOps project with self-hosted agent; run each of the three pipelines and verify:
    • azure-pipelines-api-gate.yml passes / fails based on tenant state
    • azure-pipelines-publish-results.yml populates Tests tab, custom summary tab, and artifact
    • azure-pipelines-template-consumer.yml extends the template and runs end-to-end
  • Refactor template into a separate repo and validate cross-repo resources.repositories + extends pattern

levine-cycode and others added 14 commits April 6, 2026 23:31
…ning

- Add vulnerable_packages/ directory for SCA testing
- Add n8n-workflow example with vulnerable n8n v1.100.0
- Add Dockerfile.n8n-vulnerable with CVE-2026-21858
- Update README with new vulnerable_packages section
- gha-excessive-permissions: detects permissions: write-all and broad
  write scope grants at workflow and job level
- gha-dangerous-pr-target-checkout: detects pull_request_target trigger
  combined with checkout of incoming PR code (pwn request pattern)
Scans vulnerable_apps/ for SAST findings on push, PR, and manual trigger.
Blocks build on any finding (default CLI exit code 1).
Scans only the diff between PR base and head commits,
not the full codebase. Falls back to HEAD~1 on manual trigger.
Full scan runs on push to main only. PRs use the delta scan workflow.
…centralized template

Three new patterns complementing the existing CLI gate in azure-pipelines.yml:

- scripts/cycode-gate.sh — queries the Cycode RIG Graph API for Open
  violations in a named repo; fails the build if any match. Filters by
  severity, category, and risk score via env vars. Emits
  ##vso[task.logissue] for Azure Pipelines.

- scripts/cycode-json-to-junit.py + scripts/cycode-summary.py —
  converters that take `cycode -o json scan ...` output and produce
  JUnit XML (for PublishTestResults@2 → Tests tab) and a Markdown
  report (for ##vso[task.uploadsummary] → custom tab on build summary).

- templates/cycode-scan.yml — centralized template consumed via
  `extends`. App pipelines pass parameters (scanPath, scanTypeFlags,
  severityThreshold, repoName, gateMode) and inherit the scan +
  publish + gate logic. Cross-repo usage documented in the header.

Example pipelines:
- azure-pipelines-api-gate.yml           — API gate standalone
- azure-pipelines-publish-results.yml    — Tests tab + summary + artifact
- azure-pipelines-template-consumer.yml  — minimal consumer of the template
Comment thread config/api_config.py
# Database credentials
DB_HOST = "prod-db.internal.example.com"
DB_USER = "app_service"
DB_PASSWORD = "Pr0d_S3cure!P@ssw0rd_2025_xK9m"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: Secret of type: 'Generic Password' was found.
Severity: Medium
Confidence Score: 99%
SHA: cf03e5240e

Description

A generic secret or password is an authentication token used to access a computer or application and is assigned to a password variable.

Cycode Remediation Guideline

❗ How to revoke


  • Change the password or secret in the system or application where it is used.
  • Update any services, applications, or scripts that use the old password or secret with the new one.
  • Invalidate any sessions or tokens that were authenticated using the old password or secret.

Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_secret_false_positive <reason> Applies to this secret value for all repos in your organization
#cycode_secret_ignore_here <reason> Applies to this request only
#cycode_secret_ignore_everywhere <reason> Applies to this secret value for all repos in your organization
#cycode_secret_revoked Applies to this secret value for all repos in your organization

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.

Comment thread config/api_config.py
import os

# Slack integration
SLACK_BOT_TOKEN = "xoxb-7391528460193-5827461039285-kR4mXpLn7QdWtYvBs9jH3gFe"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: Secret of type: 'Slack Token' was found.
Severity: Medium
SHA: 4ffb66c634

Description

In the scope of the Slack API, a token is an identifier that is used to authenticate Slack app app when making API requests

Cycode Remediation Guideline

❗ How to revoke


  • Navigate to the Slack API dashboard at https://api.slack.com/.
  • Log in with your Slack account credentials.
  • Go to the "Your Apps" section and select the app associated with the token.
  • Click on the "OAuth & Permissions" tab.
  • Scroll down to the "OAuth Tokens for Your Workspace" section.
  • Locate the token you need to revoke and click the "Revoke" button next to it.
  • Generate a new token if necessary and update your application with the new token.

Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_secret_false_positive <reason> Applies to this secret value for all repos in your organization
#cycode_secret_ignore_here <reason> Applies to this request only
#cycode_secret_ignore_everywhere <reason> Applies to this secret value for all repos in your organization
#cycode_secret_revoked Applies to this secret value for all repos in your organization

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.

# Vulnerable n8n Container
# This Dockerfile uses a vulnerable version of n8n affected by CVE-2026-21858

FROM n8nio/n8n:1.100.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: Infrastructure configuration issue: 'Specific user should be defined'.
Severity: High

Description

The image will run as root unless a lesser privileged user is defined

Cycode Remediation Guideline

Ensure that at least one USER instruction is defined before or in any none 'FROM scratch' build stage)

Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_ignore_violation_for_resource_everywhere <reason> Applies to this resource for this violation for all repos in your organization
#cycode_ai_remediation Request remediation guidance using Cycode AI
#cycode_ignore_violation_for_resource_here <reason> Applies to this resource for this violation in this request only
#cycode_ignore_resource_everywhere <reason> Applies to this resource for all repos in your organization
#cycode_iac_false_positive <reason> Applies to this resource for this violation for all repos in your organization

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.

Comment thread scripts/cycode-summary.py


def main(src: str) -> int:
with open(src) as f:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: SAST violation: 'Unsanitized user input in file path'.

Severity: High

Description

Unsanitized user input in file path resolution can lead to security vulnerabilities. This issue arises when an application directly uses input from the user to determine file paths or names without proper validation or sanitization. Attackers can exploit this to access unauthorized files or directories, leading to data breaches or other security compromises.

Cycode Remediation Guideline

✅ Do


  • Do use a safelist to define accessible paths or directories. Only allow user input to influence file paths within these predefined, safe boundaries.
  • Do sanitize user input used in file path resolution. For example, use absolute paths and check against the expected base directory
      BASE_DIRECTORY = '/path/to/safe/directory'
      my_path = os.path.abspath(os.path.join(BASE_DIRECTORY, user_input))
    
      if my_path.startswith(BASE_DIRECTORY):
        open(my_path)

❌ Don't


  • Do not directly use user input in file paths without sanitization. Failure to sanitize could allow attackers to manipulate file paths and to access or manipulate unauthorized files.

🎥 Learning materials (by Secure Code Warrior)


Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_sast_ignore_here <reason> Ignore this violation — applies to this violation only
#cycode_ai_remediation Request remediation guidance using Cycode AI
#cycode_sast_false_positive <reason> Mark as false positive — applies to this violation only

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.


out.append("</testsuite>")

with open(dst, "w") as f:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: SAST violation: 'Unsanitized user input in file path'.

Severity: High

Description

Unsanitized user input in file path resolution can lead to security vulnerabilities. This issue arises when an application directly uses input from the user to determine file paths or names without proper validation or sanitization. Attackers can exploit this to access unauthorized files or directories, leading to data breaches or other security compromises.

Cycode Remediation Guideline

✅ Do


  • Do use a safelist to define accessible paths or directories. Only allow user input to influence file paths within these predefined, safe boundaries.
  • Do sanitize user input used in file path resolution. For example, use absolute paths and check against the expected base directory
      BASE_DIRECTORY = '/path/to/safe/directory'
      my_path = os.path.abspath(os.path.join(BASE_DIRECTORY, user_input))
    
      if my_path.startswith(BASE_DIRECTORY):
        open(my_path)

❌ Don't


  • Do not directly use user input in file paths without sanitization. Failure to sanitize could allow attackers to manipulate file paths and to access or manipulate unauthorized files.

🎥 Learning materials (by Secure Code Warrior)


Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_sast_ignore_here <reason> Ignore this violation — applies to this violation only
#cycode_ai_remediation Request remediation guidance using Cycode AI
#cycode_sast_false_positive <reason> Mark as false positive — applies to this violation only

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.



def main(src: str, dst: str) -> int:
with open(src) as f:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cycode: SAST violation: 'Unsanitized user input in file path'.

Severity: High

Description

Unsanitized user input in file path resolution can lead to security vulnerabilities. This issue arises when an application directly uses input from the user to determine file paths or names without proper validation or sanitization. Attackers can exploit this to access unauthorized files or directories, leading to data breaches or other security compromises.

Cycode Remediation Guideline

✅ Do


  • Do use a safelist to define accessible paths or directories. Only allow user input to influence file paths within these predefined, safe boundaries.
  • Do sanitize user input used in file path resolution. For example, use absolute paths and check against the expected base directory
      BASE_DIRECTORY = '/path/to/safe/directory'
      my_path = os.path.abspath(os.path.join(BASE_DIRECTORY, user_input))
    
      if my_path.startswith(BASE_DIRECTORY):
        open(my_path)

❌ Don't


  • Do not directly use user input in file paths without sanitization. Failure to sanitize could allow attackers to manipulate file paths and to access or manipulate unauthorized files.

🎥 Learning materials (by Secure Code Warrior)


Tell us how you wish to proceed using one of the following commands:

Tag Short Description
#cycode_sast_ignore_here <reason> Ignore this violation — applies to this violation only
#cycode_ai_remediation Request remediation guidance using Cycode AI
#cycode_sast_false_positive <reason> Mark as false positive — applies to this violation only

⚠️ When commenting on Github, you may need to refresh the page to see the latest updates.

@appsechq-brian
Copy link
Copy Markdown
Member Author

Superseded by #5 — clean branch based on origin/main with only the Azure Pipelines advanced patterns commits.

@appsechq-brian appsechq-brian deleted the feature/cycode-advanced-patterns branch April 22, 2026 04:43
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.

2 participants