Files
git.stella-ops.org/docs/cicd/security-scanning.md
StellaOps Bot e6c47c8f50 save progress
2025-12-28 23:49:56 +02:00

15 KiB

Security Scanning

Complete guide to security scanning workflows in the StellaOps CI/CD pipeline.


Security Scanning Overview

StellaOps implements a defense-in-depth security scanning strategy:

┌─────────────────────────────────────────────────────────────────┐
│                    SECURITY SCANNING LAYERS                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Layer 1: PRE-COMMIT                                            │
│  └── Secrets scanning (pre-commit hook)                         │
│                                                                 │
│  Layer 2: PULL REQUEST                                          │
│  ├── SAST (Static Application Security Testing)                 │
│  ├── Secrets scanning                                           │
│  ├── Dependency vulnerability audit                             │
│  └── License compliance check                                   │
│                                                                 │
│  Layer 3: MAIN BRANCH                                           │
│  ├── All Layer 2 scans                                          │
│  ├── Container image scanning                                   │
│  └── Extended SAST analysis                                     │
│                                                                 │
│  Layer 4: SCHEDULED                                             │
│  ├── Weekly deep SAST scan (Monday)                             │
│  ├── Weekly dependency audit (Sunday)                           │
│  ├── Daily container scanning                                   │
│  └── Nightly regression security tests                          │
│                                                                 │
│  Layer 5: RELEASE                                               │
│  ├── Final vulnerability gate                                   │
│  ├── SBOM generation and signing                                │
│  ├── Provenance attestation                                     │
│  └── Container signing                                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Scanning Workflows

1. SAST Scanning (sast-scan.yml)

Purpose: Detect security vulnerabilities in source code through static analysis.

Triggers:

  • Pull requests (source code changes)
  • Push to main/develop
  • Weekly Monday 3:30 AM UTC
  • Manual dispatch

Scanned Languages:

  • C# / .NET
  • JavaScript / TypeScript
  • Python
  • YAML
  • Dockerfile

Checks Performed:

Check Tool Scope
Code vulnerabilities Semgrep/CodeQL (placeholder) All source
.NET security analyzers Built-in Roslyn C# code
Dependency vulnerabilities dotnet list --vulnerable NuGet packages
Dockerfile best practices Hadolint Dockerfiles

Configuration:

# sast-scan.yml inputs
workflow_dispatch:
  inputs:
    scan_level:
      type: choice
      options:
        - quick        # Fast scan, critical issues only
        - standard     # Default, balanced coverage
        - comprehensive # Full scan, all rules
    fail_on_findings:
      type: boolean
      default: true    # Block on findings

.NET Security Analyzer Rules:

The workflow enforces these security-critical CA rules as errors:

Category Rules Description
SQL Injection CA2100 Review SQL queries for vulnerabilities
Cryptography CA5350-5403 Weak crypto, insecure algorithms
Deserialization CA2300-2362 Unsafe deserialization
XML Security CA3001-3012 XXE, XPath injection
Web Security CA3061, CA5358-5398 XSS, CSRF, CORS

2. Secrets Scanning (secrets-scan.yml)

Purpose: Detect hardcoded credentials, API keys, and secrets in code.

Triggers:

  • Pull requests
  • Push to main/develop
  • Manual dispatch

Detection Patterns:

Secret Type Example Pattern
API Keys sk_live_[a-zA-Z0-9]+
AWS Keys AKIA[0-9A-Z]{16}
Private Keys -----BEGIN RSA PRIVATE KEY-----
Connection Strings Password=.*;User ID=.*
JWT Tokens eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+
GitHub Tokens gh[ps]_[A-Za-z0-9]{36}

Tool Options (Placeholder):

# Choose one by uncommenting in sast-scan.yml:

# Option 1: TruffleHog (recommended for open source)
# - name: TruffleHog Scan
#   uses: trufflesecurity/trufflehog@main
#   with:
#     extra_args: --only-verified

# Option 2: Gitleaks
# - name: Gitleaks Scan
#   uses: gitleaks/gitleaks-action@v2
#   env:
#     GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

# Option 3: Semgrep
# - name: Semgrep Secrets
#   uses: returntocorp/semgrep-action@v1
#   with:
#     config: p/secrets

Allowlist Configuration:

Create .gitleaksignore or .secretsignore for false positives:

# Ignore test fixtures
src/__Tests/**/*
docs/examples/**/*

# Ignore specific files
path/to/test-credentials.json

# Ignore by rule ID
[allowlist]
regexes = ["test_api_key_[a-z]+"]

3. Container Scanning (container-scan.yml)

Purpose: Scan container images for OS and application vulnerabilities.

Triggers:

  • Dockerfile changes
  • Daily schedule (4 AM UTC)
  • Manual dispatch

Scan Targets:

Image Built From Scanned Components
stellaops/authority src/Authority/Dockerfile OS packages, .NET runtime
stellaops/scanner src/Scanner/Dockerfile OS packages, .NET runtime, analyzers
stellaops/concelier src/Concelier/Dockerfile OS packages, .NET runtime
(9 total images) ... ...

Vulnerability Severity Levels:

Severity Action Example
CRITICAL Block release Remote code execution
HIGH Block release (configurable) Privilege escalation
MEDIUM Warning Information disclosure
LOW Log only Minor issues
UNKNOWN Log only Unclassified

Tool Options (Placeholder):

# Choose one by uncommenting in container-scan.yml:

# Option 1: Trivy (recommended)
# - name: Trivy Scan
#   uses: aquasecurity/trivy-action@master
#   with:
#     image-ref: ${{ steps.build.outputs.image }}
#     format: sarif
#     output: trivy-results.sarif
#     severity: CRITICAL,HIGH

# Option 2: Grype
# - name: Grype Scan
#   uses: anchore/scan-action@v3
#   with:
#     image: ${{ steps.build.outputs.image }}
#     fail-build: true
#     severity-cutoff: high

# Option 3: Snyk Container
# - name: Snyk Container
#   uses: snyk/actions/docker@master
#   env:
#     SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

4. Dependency Security Scanning (dependency-security-scan.yml)

Purpose: Audit NuGet and npm packages for known vulnerabilities.

Triggers:

  • Weekly Sunday 2 AM UTC
  • Pull requests (dependency file changes)
  • Manual dispatch

Scanned Files:

Ecosystem Files
NuGet src/Directory.Packages.props, **/*.csproj
npm **/package.json, **/package-lock.json

Vulnerability Sources:

  • GitHub Advisory Database
  • NVD (National Vulnerability Database)
  • OSV (Open Source Vulnerabilities)
  • Vendor security advisories

Scan Process:

┌─────────────────────────────────────────────────────────────────┐
│                 DEPENDENCY SECURITY SCAN                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐                                               │
│  │  scan-nuget  │ dotnet list package --vulnerable              │
│  └──────┬───────┘                                               │
│         │                                                       │
│         ▼                                                       │
│  ┌──────────────┐                                               │
│  │   scan-npm   │ npm audit --json                              │
│  └──────┬───────┘                                               │
│         │                                                       │
│         ▼                                                       │
│  ┌──────────────┐                                               │
│  │   summary    │ Aggregate results, generate report            │
│  └──────────────┘                                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Example Output:

## Dependency Vulnerability Audit

### NuGet Packages
| Package | Installed | Vulnerable | Severity | Advisory |
|---------|-----------|------------|----------|----------|
| Newtonsoft.Json | 12.0.1 | < 13.0.1 | HIGH | GHSA-xxxx |

### npm Packages
| Package | Installed | Vulnerable | Severity | Advisory |
|---------|-----------|------------|----------|----------|
| lodash | 4.17.15 | < 4.17.21 | CRITICAL | npm:lodash:1 |

5. License Compliance (dependency-license-gate.yml)

Purpose: Ensure all dependencies use approved licenses.

Approved Licenses:

License SPDX ID Status
MIT MIT Approved
Apache 2.0 Apache-2.0 Approved
BSD 2-Clause BSD-2-Clause Approved
BSD 3-Clause BSD-3-Clause Approved
ISC ISC Approved
MPL 2.0 MPL-2.0 Review Required
LGPL 2.1+ LGPL-2.1-or-later Review Required
GPL 2.0+ GPL-2.0-or-later Blocked (copyleft)
AGPL 3.0 AGPL-3.0 Blocked (copyleft)

Blocked on Violation:

  • GPL-licensed runtime dependencies
  • Unknown/proprietary licenses without explicit approval

Scan Results & Reporting

GitHub Step Summary

All security scans generate GitHub Step Summary reports:

## SAST Scan Summary

| Check | Status |
|-------|--------|
| SAST Analysis | ✅ Pass |
| .NET Security | ⚠️ 3 warnings |
| Dependency Check | ✅ Pass |
| Dockerfile Lint | ✅ Pass |

### .NET Security Warnings
- CA5350: Weak cryptographic algorithm (src/Crypto/Legacy.cs:42)
- CA2100: SQL injection risk (src/Data/Query.cs:78)

SARIF Integration

Scan results are uploaded in SARIF format for IDE integration:

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: scan-results.sarif

Artifact Retention

Artifact Retention
SARIF files 30 days
Vulnerability reports 90 days
License audit logs 1 year

Security Gates

PR Merge Requirements

Gate Threshold Block Merge?
SAST Critical 0 Yes
SAST High 0 Configurable
Secrets Found 0 Yes
Vulnerable Dependencies (Critical) 0 Yes
Vulnerable Dependencies (High) 5 Warning
License Violations 0 Yes

Release Requirements

Gate Threshold Block Release?
Container Scan (Critical) 0 Yes
Container Scan (High) 0 Yes
SBOM Generation Success Yes
Signature Verification Valid Yes

Remediation Workflows

Dependency Vulnerability Fix

  1. Renovate Auto-Fix:

    # renovate.json
    {
      "vulnerabilityAlerts": {
        "enabled": true,
        "labels": ["security"],
        "automerge": false
      }
    }
    
  2. Manual Override:

    # Update specific package
    dotnet add package Newtonsoft.Json --version 13.0.3
    
    # Audit and fix npm
    npm audit fix
    

False Positive Suppression

.NET Analyzer Suppression:

// Suppress specific instance
#pragma warning disable CA2100 // Review SQL queries for vulnerability
var query = $"SELECT * FROM {tableName}";
#pragma warning restore CA2100

// Or in .editorconfig
[*.cs]
dotnet_diagnostic.CA2100.severity = none  # NOT RECOMMENDED

Semgrep/SAST Suppression:

// nosemgrep: sql-injection
var query = $"SELECT * FROM {tableName}";

Container Scan Ignore:

# .trivyignore
CVE-2021-44228  # Log4j - not applicable (no Java)
CVE-2022-12345  # Accepted risk with mitigation

Configuration Files

Location

File Purpose Location
.gitleaksignore Secrets scan allowlist Repository root
.trivyignore Container scan ignore list Repository root
.semgrepignore SAST ignore patterns Repository root
renovate.json Dependency update config Repository root
.editorconfig Analyzer severity Repository root

Example .trivyignore

# Ignore by CVE ID
CVE-2021-44228

# Ignore by package
pkg:npm/lodash@4.17.15

# Ignore with expiration
CVE-2022-12345 exp:2025-06-01

Scheduled Scan Summary

Day Time (UTC) Workflow Focus
Daily 2:00 AM nightly-regression.yml Security tests
Daily 4:00 AM container-scan.yml Image vulnerabilities
Sunday 2:00 AM dependency-security-scan.yml Package audit
Monday 3:30 AM sast-scan.yml Deep code analysis

Monitoring & Alerts

Notification Channels

Configure notifications for security findings:

# In workflow
- name: Notify on Critical
  if: steps.scan.outputs.critical_count > 0
  run: |
    curl -X POST "${{ secrets.SLACK_WEBHOOK }}" \
      -d '{"text":"🚨 Critical security finding in '${{ github.repository }}'"}'

Dashboard Integration

Security scan results can be exported to:

  • Grafana dashboards (via OTLP metrics)
  • Security Information and Event Management (SIEM)
  • Vulnerability management platforms