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
141 changes: 141 additions & 0 deletions .github/workflows/.gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
title = "Gitleaks config for Omnia"

[allowlist]
description = "Ignore known false positives for infra repos"

paths = [
'''(^|/)\.git/'''
]

regexTarget = "match"
regexes = [
# Test/Example/Demo credentials
'''example[_-]?(password|secret|token|key)''',
'''dummy[_-]?(password|secret|token|key)''',
'''test[_-]?(password|secret|token|key)''',
'''demo[_-]?(password|secret|token|key)''',
'''CHANGEME''',
'''changeme''',
'''password:\s*dell\d+''',
'''PASSWORD\s*=\s*dell\d+''',
'''PASSWORD\s*=\s*"dell\d+''',
'''password:\s*slurmPassword''',
'''password:\s*"slurmPassword''',
'''VAULT_PASSWORD.*omnia_test''',
'''PASSWORD\s*=\s*"omnia_test''',
'''password\s*=\s*"correct_password"''',

# Ansible/Jinja2 variable references
'''password:\s*"?\{\{.*\}\}"?''',
'''ansible_.*password.*\{\{''',
'''password:\s*"hostvars''',
'''password:\s*hostvars''',
'''password:\s*\$\{''',
'''password:\s*\$[A-Z_]+''',

# Variable names (not values)
'''(token|secret|password)\s*=\s*[a-z_]+''',
'''password:\s*[a-z_]+(password|secret|key|token)''',
'''secret:\s*[a-z_]+(password|secret|key|token)''',
'''token:\s*[a-z_]+(password|secret|key|token)''',
'''password:\s*\{\s*password:''',
'''docker_password_cipher''',
'''load_docker_credentials''',
'''password:\s*s3_secret_key''',
'''password:\s*minio_s3_password''',
'''password:\s*switch_snmp3_password''',
'''password:\s*"mysql_.*_password''',
'''password:\s*"grafana_.*_password''',
'''password:\s*"switch_.*_password''',
'''password:\s*"kerberos_admin_password''',
'''password:\s*"directory_manager_password''',
'''secret:\s*"grafana_.*''',

# Validation/Success messages
'''success_msg.*password.*validated''',
'''fail_msg.*password''',
'''_password.*successfully.*validated''',
'''_password.*validated''',
'''msg.*password.*valid''',

# Database connection strings (localhost/templates)
'''postgresql://.*@localhost''',
'''postgresql://.*@127\.0\.0\.1''',
'''postgresql://user:pass@host''',
'''postgresql://.*%\([^)]+\)s''',
'''%\([^)]+\)s''',
'''timescaledb_password:\s*postgres''',
'''password:\s*postgres''',
'''PASSWORD:\s*postgres''',

# Shell commands and scripts
'''passwd:\s*\$''',
'''passwd:\$\(''',
'''passwd=\$\(openssl''',
'''hashed_passwd=\$\(openssl''',
'''openssl passwd''',
'''passwd:key=''',

# Configuration/Documentation fields
'''password:\s*Optional''',
'''password:\s*Password''',
'''password:\s*"Password''',
'''password:\s*password''',
'''password:\s*"password"''',
'''password:\s*"Openldap''',
'''password:\s*"Registration''',
'''password:\s*Registration''',
'''password\s*=\s*IntegrationTestConfig''',
'''password:.*description''',
'''password:.*request_args''',
'''password:.*database''',
'''password\s*=\s*AUTH_PASSWORD''',
'''password\s*=\s*\$MINIO_PASSWORD''',
'''password:\s*$''',
'''password:\s+description''',
'''password:\s+required''',
'''password:\s+type:''',
'''password=None''',
'''password:\n\s+request_args''',
'''password:\n\s*database''',
'''password:\ndatabase''',

# Documentation examples (xxx placeholders)
'''TOKEN=hf_x+''',
'''vault_password="x+''',
'''Password:\s*\d{8}''',
'''secret\s*=\s*"bld_s_[A-Za-z0-9_-]+"''',

# Known test/example tokens
'''1c8572f630701e8792bede122ec9c417''',
'''secretToken.*1c8572f6''',
'''cookieSecret.*1c8572f6''',

# Certificate references
'''secret:.*-cert''',
'''secret:.*-ca-cert'''
]

[[rules]]
id = "generic-password"
description = "Generic Password Detection"
regex = '''(?i)(password|passwd|pwd)\s*[:=]\s*["']?[A-Za-z0-9!@#$%^&*()_+=\-]{8,}["']?'''
tags = ["password"]

[[rules]]
id = "credentials-in-url"
description = "Credentials in URL"
regex = '''(?i)\b\w+:\/\/[^:\s]+:[^@\s]+@[^:\s]+'''
tags = ["credentials", "url"]

[[rules]]
id = "generic-token"
description = "Generic Token/Secret"
regex = '''(?i)(secret|token|api[_-]?key)\s*[:=]\s*["']?[A-Za-z0-9_\-]{16,}["']?'''
tags = ["token", "secret"]

[[rules]]
id = "ansible-secret"
description = "Ansible hardcoded secret"
regex = '''(?i)(ansible_.*password|vault_password)\s*[:=]\s*["'][^"']{6,}["']'''
tags = ["ansible", "secret"]
47 changes: 44 additions & 3 deletions .github/workflows/ansible-lint.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
name: Ansible Lint

on:
Expand All @@ -18,22 +19,62 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get changed Ansible files (excluding deleted)
id: changed-files
run: |
git fetch origin ${{ github.base_ref }}
CHANGED=$(git diff --name-only --diff-filter=d \
origin/${{ github.base_ref }} HEAD -- \
'*.yml' '*.yaml' || true)

FILES=""
for f in $CHANGED; do
if [ -f "$f" ]; then
FILES="$FILES $f"
fi
done

FILES=$(echo "$FILES" | xargs)
echo "Filtered files: $FILES"
echo "files=$FILES" >> "$GITHUB_OUTPUT"

- name: Set up Python
if: steps.changed-files.outputs.files != ''
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Install Ansible and Ansible Lint
if: steps.changed-files.outputs.files != ''
run: |
python -m pip install --upgrade pip
pip install ansible-core

- name: Cache Ansible collections
if: steps.changed-files.outputs.files != ''
uses: actions/cache@v3
with:
path: ~/.ansible/collections
key: ${{ runner.os }}-ansible-collections-${{ hashFiles('.config/requirements.yml') }}
restore-keys: |
${{ runner.os }}-ansible-collections-

- name: Install Ansible Collections from requirements.yml
if: steps.changed-files.outputs.files != ''
run: |
ansible-galaxy collection install -r .config/requirements.yml --force --clear-response-cache
ansible-galaxy collection install -r .config/requirements.yml --force-with-deps

- name: Run ansible-lint
- name: Run ansible-lint on changed files
if: steps.changed-files.outputs.files != ''
uses: ansible/ansible-lint@main
with:
args: --config=.config/ansible-lint.yml
args: --config=.config/ansible-lint.yml ${{ steps.changed-files.outputs.files }}

- name: No Ansible files changed
if: steps.changed-files.outputs.files == ''
run: |
echo "No Ansible files changed in this PR."
echo "Skipping ansible-lint."
69 changes: 69 additions & 0 deletions .github/workflows/bandit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
name: Bandit Security Scan

'on':
pull_request:
branches:
- main
- staging
- release_1.7.1
- pub/build_stream
- pub/q2_dev
- pub/telemetry
- pub/q2_upgrade
- pub/q2_ansible
- q3_main

jobs:
bandit:
name: Bandit Python SAST
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get changed Python files (excluding deleted)
id: changed-files
run: |
git fetch origin ${{ github.base_ref }}
CHANGED=$(git diff --name-only --diff-filter=d \
origin/${{ github.base_ref }} HEAD -- '*.py' || true)

FILES=""
for f in $CHANGED; do
if [ -f "$f" ]; then
# Exclude test files — Bandit SAST is for product code
case "$f" in
*/tests/*|*/test_*|*_test.py) continue ;;
*) FILES="$FILES $f" ;;
esac
fi
done

FILES=$(echo "$FILES" | xargs)
echo "Filtered files: $FILES"
echo "files=$FILES" >> "$GITHUB_OUTPUT"

- name: Set up Python
if: steps.changed-files.outputs.files != ''
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install Bandit
if: steps.changed-files.outputs.files != ''
run: pip install bandit

- name: Run Bandit on changed files
if: steps.changed-files.outputs.files != ''
run: |
echo "Running Bandit on: ${{ steps.changed-files.outputs.files }}"
bandit ${{ steps.changed-files.outputs.files }} -ll -ii -f txt

- name: No Python product files changed
if: steps.changed-files.outputs.files == ''
run: |
echo "No Python product files changed in this PR."
echo "Skipping Bandit."
42 changes: 42 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Secret Leak Scan

'on':
pull_request:
branches:
- main
- staging
- release_1.7.1
- pub/build_stream
- pub/q2_dev
- pub/telemetry
- pub/q2_upgrade
- pub/q2_ansible
- q3_main

jobs:
gitleaks:
name: Scan for secrets
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run Gitleaks scan using Docker
run: |
docker run --rm \
-v ${{ github.workspace }}:/repo \
-w /repo \
ghcr.io/gitleaks/gitleaks:latest \
detect \
--source /repo \
--config /repo/.github/workflows/.gitleaks.toml \
--log-opts="origin/${{ github.base_ref }}..${{ github.sha }}" \
--verbose \
--no-git
57 changes: 57 additions & 0 deletions .github/workflows/pip-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
name: Dependency Vulnerability Scan

'on':
pull_request:
branches:
- main
- staging
- release_1.7.1
- pub/build_stream
- pub/q2_dev
- pub/telemetry
- pub/q2_upgrade
- pub/q2_ansible
- q3_main

jobs:
pip-audit:
name: pip-audit Dependency Scan
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check for changed requirements files
id: changed-files
run: |
git fetch origin ${{ github.base_ref }}
CHANGED=$(git diff --name-only --diff-filter=d \
origin/${{ github.base_ref }} HEAD -- \
'src/build_stream/requirements*.txt' || true)

FILES=$(echo "$CHANGED" | xargs)
echo "Changed requirements files: $FILES"
echo "files=$FILES" >> "$GITHUB_OUTPUT"

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install pip-audit
run: pip install pip-audit

- name: Audit build_stream dependencies
run: |
echo "Auditing src/build_stream/requirements.txt"
echo "for known vulnerabilities..."
pip-audit -r src/build_stream/requirements.txt \
--desc on || true
echo ""
echo "Auditing src/build_stream/requirements-dev.txt"
echo "for known vulnerabilities..."
pip-audit -r src/build_stream/requirements-dev.txt \
--desc on || true
Loading
Loading