diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml
new file mode 100644
index 0000000..d41d323
--- /dev/null
+++ b/.github/workflows/gitleaks.yml
@@ -0,0 +1,37 @@
+---
+name: Gitleaks
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ branches: ["main"]
+ pull_request_target:
+ types: [opened, synchronize, reopened]
+ branches: ["main"]
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ gitleaks:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
+ (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository) ||
+ (github.event_name != 'pull_request' && github.event_name != 'pull_request_target')
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+ fetch-depth: 0
+
+ - name: Run Gitleaks
+ uses: gitleaks/gitleaks-action@v2
+ with:
+ args: --config .gitleaks.toml
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitleaks.toml b/.gitleaks.toml
new file mode 100644
index 0000000..972b0b5
--- /dev/null
+++ b/.gitleaks.toml
@@ -0,0 +1,70 @@
+# Gitleaks configuration for openshift_virtualization_migration
+# https://github.com/gitleaks/gitleaks
+
+title = "OpenShift Virtualization Migration Gitleaks Configuration"
+
+[extend]
+useDefault = true
+
+# Allowlist paths and patterns that contain placeholder credentials
+# (e.g., "changeme", example domains, template variables)
+[allowlist]
+description = "Global allowlist for placeholder values and template files"
+paths = [
+ '''\.gitleaks\.toml$''',
+ '''README\.md$''',
+]
+regexTarget = "line"
+regexes = [
+ # Placeholder values used in inventory and defaults
+ '''changeme''',
+ # Jinja2 template variables
+ '''\{\{.*\}\}''',
+ # Ansible Vault references
+ '''!vault''',
+ # Example/documentation values
+ '''example\.com''',
+ '''EXAMPLE''',
+ # YAML comments containing credential variable names
+ '''^\s*#.*''',
+ # HTML bold tags documenting variable names (docsible-generated)
+ '''.*''',
+ # Multi-line YAML block scalars where value is a Jinja2 template on the next line
+ '''[>|][+-]?\s*$''',
+]
+
+# Custom rules for Ansible-specific credential patterns
+[[rules]]
+id = "ansible-vault-password-file"
+description = "Ansible vault password file"
+regex = '''vault[_-]?pass(word)?[_-]?file\s*[:=]\s*['"]?([^\s'"]+)'''
+keywords = ["vault"]
+[rules.allowlist]
+regexes = ['''changeme''', '''\{\{.*\}\}''']
+
+[[rules]]
+id = "openshift-api-key"
+description = "OpenShift API key or token"
+regex = '''(?i)(openshift[_-]?(?:api[_-]?key|token|password))\s*[:=]\s*['"]?([^\s'"#}{]+)'''
+keywords = ["openshift"]
+[rules.allowlist]
+regexes = ['''changeme''', '''\{\{.*\}\}''', '''example''', '''.*''', '''[>|][+-]?\s*$''']
+paths = ['''defaults/main\.yml$''', '''inventory\.yml$''', '''README\.md$''', '''tasks/main\.yml$''']
+
+[[rules]]
+id = "automation-hub-token"
+description = "Automation Hub token"
+regex = '''(?i)(automation[_-]?hub[_-]?(?:token|password))\s*[:=]\s*['"]?([^\s'"#}{]+)'''
+keywords = ["automation_hub", "automation-hub"]
+[rules.allowlist]
+regexes = ['''changeme''', '''\{\{.*\}\}''']
+paths = ['''defaults/main\.yml$''', '''inventory\.yml$''']
+
+[[rules]]
+id = "container-registry-password"
+description = "Container registry password"
+regex = '''(?i)(container[_-]?password|registry[_-]?password)\s*[:=]\s*['"]?([^\s'"#}{]+)'''
+keywords = ["container_password", "registry_password"]
+[rules.allowlist]
+regexes = ['''changeme''', '''\{\{.*\}\}''', '''.*''']
+paths = ['''defaults/main\.yml$''', '''inventory\.yml$''', '''README\.md$''']