docs 📝: Add new rule to detect Sidekiq secret in README.md #23

Merged
Jose merged 19 commits from dev into main 2026-02-14 11:02:56 +01:00
4 changed files with 220 additions and 169 deletions

View File

@@ -1,164 +0,0 @@
---
# https://github.com/kekxv/pr-check
name: PR check
on:
pull_request:
types: [opened, synchronize]
jobs:
leak_test:
name: Gitleaks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
github-server-url: ${{ vars.GIT_SERVER_URL }}
- name: Install Gitleaks
run: |
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz \
| tar -xz
sudo mv gitleaks /usr/local/bin/
- name: Run Gitleaks
run: |
gitleaks dir . \
--redact=10 \
--verbose \
--exit-code 1
lint_test:
name: lint tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
github-server-url: ${{ vars.GIT_SERVER_URL }}
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Run markdownlint
run: npx markdownlint-cli2 "**/*.md" "#node_modules"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.14"
- name: Install ansible-lint and yamllint
run: |
python -m pip install --upgrade pip
pip install ansible ansible-lint yamllint
- name: Run yamllint
run: |
yamllint .
- name: Run ansible-lint
run: |
ansible-lint
handle_failures:
runs-on: ubuntu-latest
needs: [leak_test, lint_test]
if: needs.leak_test.result != 'success' || needs.lint_test.result != 'success'
steps:
- name: Comment, label, and close PR
run: |
API="${{ vars.GIT_SERVER_URL }}/api/v1/repos/${{ github.repository }}"
PR="${{ github.event.pull_request.number }}"
TOKEN="${{ secrets.GITEA_TOKEN }}"
COMMENT_BODY="❌ CI checks failed.\n\nLeak test: ${{ needs.leak_test.result }}\nLint: ${{ needs.lint_test.result }}"
# Find existing comment
EXISTING_COMMENT_ID=$(curl -s -H "Authorization: token $TOKEN" \
"$API/issues/$PR/comments" \
| jq -r '.[] | select(.body | test("<!--ci-failed-comment-->")) | .id')
# Update or create comment
if [ -n "$EXISTING_COMMENT_ID" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments/$EXISTING_COMMENT_ID"
else
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments"
fi
# Add label if missing
LABELS=$(curl -s -H "Authorization: token $TOKEN" "$API/issues/$PR/labels" | jq -r '.[] | .name')
if ! echo "$LABELS" | grep -q "^ci-failed$"; then
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '["ci-failed"]' \
"$API/issues/$PR/labels"
fi
# Close PR
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"closed"}' \
"$API/pulls/$PR"
handle_success:
runs-on: ubuntu-latest
needs: [leak_test, lint_test]
if: needs.leak_test.result == 'success' && needs.lint_test.result == 'success'
steps:
- name: Update comment, remove label, reopen PR
run: |
API="${{ vars.GIT_SERVER_URL }}/api/v1/repos/${{ github.repository }}"
PR="${{ github.event.pull_request.number }}"
TOKEN="${{ secrets.GITEA_TOKEN }}"
COMMENT_BODY="✅ All CI checks passed.\n\nLeak test: ${{ needs.leak_test.result }}\nLint: ${{ needs.lint_test.result }}"
# Find existing comment
EXISTING_COMMENT_ID=$(curl -s -H "Authorization: token $TOKEN" \
"$API/issues/$PR/comments" \
| jq -r '.[] | select(.body | test("<!--ci-failed-comment-->")) | .id')
# Update comment if exists
if [ -n "$EXISTING_COMMENT_ID" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments/$EXISTING_COMMENT_ID"
fi
# Remove label if exists
LABELS=$(curl -s -H "Authorization: token $TOKEN" "$API/issues/$PR/labels" | jq -r '.[] | .name')
if echo "$LABELS" | grep -q "^ci-failed$"; then
curl -s -X DELETE \
-H "Authorization: token $TOKEN" \
"$API/issues/$PR/labels/ci-failed"
fi
# Reopen PR if closed
PR_STATE=$(curl -s -H "Authorization: token $TOKEN" "$API/pulls/$PR" | jq -r '.state')
if [ "$PR_STATE" = "closed" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"open"}' \
"$API/pulls/$PR"
fi

View File

@@ -0,0 +1,168 @@
---
# https://github.com/kekxv/pr-check
name: PR check
on:
pull_request:
types: [opened, synchronize]
jobs:
leak_test:
name: Gitleaks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
github-server-url: ${{ vars.GIT_SERVER_URL }}
- name: Install Gitleaks
run: |
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz \
| tar -xz
sudo mv gitleaks /usr/local/bin/
- name: Run Gitleaks
run: |
gitleaks dir . \
--config .gitleaks.toml \
--redact=50 \
--verbose \
--exit-code 1
# --exclude-files "README.md"
lint_test:
Review

[Score: 2] Potential security risk if sensitive information is present in the README file and it's being excluded from Gitleaks checks. Consider removing the exclusion if not necessary.

[Score: 2] Potential security risk if sensitive information is present in the README file and it's being excluded from Gitleaks checks. Consider removing the exclusion if not necessary. ```
name: lint tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
github-server-url: ${{ vars.GIT_SERVER_URL }}
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Run markdownlint
run: npx markdownlint-cli2 "**/*.md" "#node_modules"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.14"
- name: Install ansible-lint and yamllint
run: |
python -m pip install --upgrade pip
pip install ansible ansible-lint yamllint
- name: Run yamllint
run: |
yamllint .
- name: Run ansible-lint
run: |
ansible-lint
handle_failures:
runs-on: ubuntu-latest
needs: [leak_test, lint_test]
if: "${{ always() && (
needs.leak_test.result != 'success' ||
needs.lint_test.result != 'success' ) }}"
steps:
- name: Comment, label, and close PR
run: |
API="${{ vars.GIT_SERVER_URL }}/api/v1/repos/${{ github.repository }}"
PR="${{ github.event.pull_request.number }}"
TOKEN="${{ secrets.GITEA_TOKEN }}"
COMMENT_BODY="❌ CI checks failed.\n\nLeak: ${{ needs.leak_test.result }}\nLint: ${{ needs.lint_test.result }}"
# Find existing comment
EXISTING_COMMENT_ID=$(curl -s -H "Authorization: token $TOKEN" \
"$API/issues/$PR/comments" \
| jq -r '.[] | select(.body | test("<!--ci-failed-comment-->")) | .id')
# Update or create comment
if [ -n "$EXISTING_COMMENT_ID" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments/$EXISTING_COMMENT_ID"
else
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments"
fi
# Add label if missing
LABELS=$(curl -s -H "Authorization: token $TOKEN" "$API/issues/$PR/labels" | jq -r '.[] | .name')
if ! echo "$LABELS" | grep -q "^ci-failed$"; then
curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '["ci-failed"]' \
"$API/issues/$PR/labels"
fi
# Close PR
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"closed"}' \
"$API/pulls/$PR"
handle_success:
runs-on: ubuntu-latest
needs: [leak_test, lint_test]
if: needs.leak_test.result == 'success' && needs.lint_test.result == 'success'
steps:
- name: Update comment, remove label, reopen PR
run: |
API="${{ vars.GIT_SERVER_URL }}/api/v1/repos/${{ github.repository }}"
PR="${{ github.event.pull_request.number }}"
TOKEN="${{ secrets.GITEA_TOKEN }}"
COMMENT_BODY="✅ CI checks pass.\n\nLeaks: ${{ needs.leak_test.result }}\nLint: ${{ needs.lint_test.result }}"
# Find existing comment
EXISTING_COMMENT_ID=$(curl -s -H "Authorization: token $TOKEN" \
"$API/issues/$PR/comments" \
| jq -r '.[] | select(.body | test("<!--ci-failed-comment-->")) | .id')
# Update comment if exists
if [ -n "$EXISTING_COMMENT_ID" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\":\"<!--ci-failed-comment-->\n$COMMENT_BODY\"}" \
"$API/issues/$PR/comments/$EXISTING_COMMENT_ID"
fi
# Remove label if exists
LABELS=$(curl -s -H "Authorization: token $TOKEN" "$API/issues/$PR/labels" | jq -r '.[] | .name')
if echo "$LABELS" | grep -q "^ci-failed$"; then
curl -s -X DELETE \
-H "Authorization: token $TOKEN" \
"$API/issues/$PR/labels/ci-failed"
fi
# Reopen PR if closed
PR_STATE=$(curl -s -H "Authorization: token $TOKEN" "$API/pulls/$PR" | jq -r '.state')
if [ "$PR_STATE" = "closed" ]; then
curl -s -X PATCH \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"open"}' \
"$API/pulls/$PR"
fi

47
.gitleaks.toml Normal file
View File

@@ -0,0 +1,47 @@
title = "Gitleaks Config"
# ==========================
Review

[Lines 1-3] [Score: 2] These lines are just a title and comments, they don't affect the logic or functionality of the code. However, it could be beneficial to include a brief description about what this configuration file does for someone who may not be familiar with Gitleaks.

[Lines 1-3] [Score: 2] These lines are just a title and comments, they don't affect the logic or functionality of the code. However, it could be beneficial to include a brief description about what this configuration file does for someone who may not be familiar with Gitleaks.
# Allowlist / False Positive Rules
# ==========================
# [[allowlist]]
# description = "Ignore placeholder secrets in README.md"
# filepath = "README.md"
Review

[Lines 6-8] [Score: 2] This rule allows the ignoring of placeholder secrets within the README.md file, which is a common practice to help avoid false positives during scans. It's good to have this allowlist rule in place to prevent unnecessary alerts.

[Lines 6-8] [Score: 2] This rule allows the ignoring of placeholder secrets within the README.md file, which is a common practice to help avoid false positives during scans. It's good to have this allowlist rule in place to prevent unnecessary alerts.
# # Add all placeholder-like patterns that trigger false positives
# regex = "cafebabe|deadbeef|DB_PASSWORD"
# [[allowlist]]
Review

[Lines 10-12] [Score: 2] This line includes specific patterns to ignore in the README.md file, such as cafebabe and deadbeef (common byte sequences), and DB_PASSWORD (likely a placeholder). These are common best practices when setting up Gitleaks allowlists.

[Lines 10-12] [Score: 2] This line includes specific patterns to ignore in the README.md file, such as cafebabe and deadbeef (common byte sequences), and DB_PASSWORD (likely a placeholder). These are common best practices when setting up Gitleaks allowlists.
# description = "Ignore badge URLs in README"
# filepath = "README.md"
# regex = "https://img.shields.io"
Review

[Lines 14-16] [Score: 2] This rule allows ignoring badge URLs within the README.md file, which is a common practice to help avoid false positives during scans. It's good to have this allowlist rule in place to prevent unnecessary alerts.

[Lines 14-16] [Score: 2] This rule allows ignoring badge URLs within the README.md file, which is a common practice to help avoid false positives during scans. It's good to have this allowlist rule in place to prevent unnecessary alerts.
# ==========================
# Rules
# ==========================
# [[rules]]
# id = "generic-api-key"
# description = "Generic API Key"
# regex = "(?i)(api[_-]?key|secret|token)=\\S+"

[Lines 20-23] [Score: 2] This rule is for detecting generic API keys (regex pattern provided) that may be hardcoded or leaked in the source code. It's a good practice to have rules like this in place to ensure sensitive data isn't accidentally exposed.

[Lines 20-23] [Score: 2] This rule is for detecting generic API keys (regex pattern provided) that may be hardcoded or leaked in the source code. It's a good practice to have rules like this in place to ensure sensitive data isn't accidentally exposed.
# entropy = 3.5
# [[rules]]
# id = "sidekiq-secret"
# description = "Sidekiq Secret"
# regex = "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=\\S+"
# entropy = 2.5

[Lines 26-30] [Score: 2] This rule is for detecting Sidekiq secrets (regex pattern provided) that may be hardcoded or leaked in the source code. It's a good practice to have rules like this in place to ensure sensitive data isn't accidentally exposed.

[Lines 26-30] [Score: 2] This rule is for detecting Sidekiq secrets (regex pattern provided) that may be hardcoded or leaked in the source code. It's a good practice to have rules like this in place to ensure sensitive data isn't accidentally exposed.
# ==========================
# File-specific entropy overrides
# ==========================
[[rules]]
id = "generic-api-key-docs"
description = "Ignore placeholder secrets in README.md"
regex = "(?i)(api[_-]?key|secret|token)=\\S+"
filepath = "README.md"
Review

[Lines 38-39] [Score: 4] The regular expression for generic API keys catches any string containing "api", "key", "secret", or "token" followed by one or more non-space characters. While this is a good starting point, it might catch too many false positives if the project uses these terms in non-sensitive contexts. Consider refining the regular expression to better match actual API keys.

[Lines 38-39] [Score: 4] The regular expression for generic API keys catches any string containing "api", "key", "secret", or "token" followed by one or more non-space characters. While this is a good starting point, it might catch too many false positives if the project uses these terms in non-sensitive contexts. Consider refining the regular expression to better match actual API keys.
entropy = 5.0 # high threshold, placeholders won't trigger

[Lines 35-40] [Score: 2] This rule is similar to the initial allowlist rule for ignoring placeholder secrets within the README.md file, but with a higher entropy threshold (10.0) to reduce false negatives. It's good to have this rule in place to prevent alerts on known placeholders and maintain proper scan results.

[Lines 35-40] [Score: 2] This rule is similar to the initial allowlist rule for ignoring placeholder secrets within the README.md file, but with a higher entropy threshold (10.0) to reduce false negatives. It's good to have this rule in place to prevent alerts on known placeholders and maintain proper scan results.
Review

[Score: 4] The high entropy value (5.0) set for the generic API keys in README.md might overlook actual secrets. Consider reducing the entropy threshold to ensure sensitive information is detected.

[Score: 4] The high entropy value (5.0) set for the generic API keys in README.md might overlook actual secrets. Consider reducing the entropy threshold to ensure sensitive information is detected.
[[rules]]
id = "sidekiq-secret"
description = "Sidekiq Secret in README.md"
regex = "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=\\S+"
filepath = "README.md"
Review

[Score: 4] The high entropy value (5.0) set for Sidekiq secrets in README.md might overlook actual secrets. Consider reducing the entropy threshold to ensure sensitive information is detected.

[Score: 4] The high entropy value (5.0) set for Sidekiq secrets in README.md might overlook actual secrets. Consider reducing the entropy threshold to ensure sensitive information is detected.
entropy = 5.0

[Lines 42-47] [Score: 2] This rule is similar to the initial detection rule for Sidekiq secrets, but it's specific to the README.md file and has a slightly lower entropy threshold (5.5) compared to the previous rule with higher entropy. It's good to have this rule in place to ensure sensitive data isn't accidentally exposed within the README.md file.

[Lines 42-47] [Score: 2] This rule is similar to the initial detection rule for Sidekiq secrets, but it's specific to the README.md file and has a slightly lower entropy threshold (5.5) compared to the previous rule with higher entropy. It's good to have this rule in place to ensure sensitive data isn't accidentally exposed within the README.md file.

View File

@@ -1,4 +1,4 @@
# ansible_role_proxmox_provision
# README ansible_role_proxmox_provision
> A reusable Ansible role template for for Proxmox VE
> with a focus on provisioning and managing.
@@ -7,7 +7,7 @@
[![Ansible Version](https://img.shields.io/badge/Ansible-2.12+-blue)](https://www.ansible.com/)
[![Proxmox](https://img.shields.io/badge/Proxmox-9-orange?logo=proxmox&logoColor=white)](https://www.proxmox.com/)
## 📌 Key Features
## 📌 Features
**Proxmox VE Optimized** - Specifically designed for Proxmox Virtual Environment
**Idempotent** - Safe to run multiple times
@@ -18,7 +18,7 @@
## 📊 Compatibility Matrix
| Feature | VE 7 | VE 8 | VE 9 |
| Feature \ Proxmox Version| 7 | 8 | 9 |
| ------------------------ | ---- | ---- | ---- |
| No-subscription repo | ✅ | ✅ | ✅ |
| Enterprise repo disabled | ✅ | ✅ | ✅ |
@@ -26,7 +26,7 @@
| Swap handling | ✅ | ✅ | ✅ |
| Logrotate protection | ✅ | ✅ | ✅ |
| Powertop auto-tune | ✅ | ✅ | ✅ |
| API utilities | ✅ | ✅ | ✅ |
| Utilities | ✅ | ✅ | ✅ |
## 📂 Directory Structure
@@ -46,7 +46,7 @@ ansible_role_proxmox_provision/
│ ├── repos.yml # Repository setup
│ ├── subscription.yml # Subscription nag removal
│ ├── swap.yml # Swap setup
│ └── utilities.yml # API utilities installation
│ └── utilities.yml # Utilities installation
├── templates/ # Jinja2 templates
└── vars/ # Non-overridable variables
└── main.yml