Skip to content

Commit cb450d6

Browse files
Merge pull request #42 from CodeMonkeyCybersecurity/claude/how-should-011CUtCozqouRDwKLnWA4nXV
Claude/how should 011 c ut cozqou r dw k ln wa4n xv
2 parents 1dea983 + 32d865e commit cb450d6

File tree

9 files changed

+1372
-6
lines changed

9 files changed

+1372
-6
lines changed

.github/workflows/comprehensive-testing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
- name: Lint code
6767
run: |
6868
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
69-
golangci-lint run --timeout=10m
69+
golangci-lint run --timeout=10m --config=.golangci.yml
7070
7171
- name: Quick unit tests
7272
run: |

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ jobs:
2525
run: go mod download
2626

2727
- name: Run golangci-lint
28-
uses: golangci/golangci-lint-action@v3
28+
uses: golangci/golangci-lint-action@v6
2929
with:
3030
version: latest
31-
args: --timeout=5m --out-format colored-line-number
31+
args: --timeout=5m --config=.golangci.yml
3232

3333
- name: Check code formatting
3434
run: |

.gitleaks.toml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# .gitleaks.toml - Secret scanning configuration for Eos
2+
# Last Updated: 2025-11-07
3+
# Documentation: https://github.com/gitleaks/gitleaks
4+
#
5+
# This configuration detects secrets specific to Eos infrastructure:
6+
# - Vault tokens, Consul tokens, Nomad tokens
7+
# - Database passwords, API keys
8+
# - TLS certificates and private keys
9+
# - Generic secrets (passwords, tokens, keys)
10+
#
11+
# Used by:
12+
# - Pre-commit hook (.git/hooks/pre-commit - gitleaks protect --staged)
13+
# - CI/CD (future GitHub Actions workflow)
14+
# - Manual scans (gitleaks detect)
15+
16+
title = "Eos Secret Scanning Configuration"
17+
18+
# Use gitleaks' default ruleset as baseline
19+
[extend]
20+
useDefault = true
21+
22+
# ============================================================================
23+
# Eos-Specific Secret Patterns
24+
# ============================================================================
25+
26+
[[rules]]
27+
id = "vault-token"
28+
description = "HashiCorp Vault Token (hvs.* or s.* format)"
29+
regex = '''(hvs\.[a-zA-Z0-9]{90,}|s\.[a-zA-Z0-9]{24})'''
30+
tags = ["vault", "token", "hashicorp"]
31+
[rules.allowlist]
32+
paths = [
33+
'''.*_test\.go$''', # Test files may have fake tokens
34+
'''testdata/.*''', # Test data
35+
'''docs/.*\.md$''', # Documentation examples
36+
]
37+
38+
[[rules]]
39+
id = "consul-acl-token"
40+
description = "HashiCorp Consul ACL Token (UUID format)"
41+
regex = '''[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'''
42+
tags = ["consul", "token", "hashicorp"]
43+
[rules.allowlist]
44+
paths = [
45+
'''.*_test\.go$''',
46+
'''testdata/.*''',
47+
'''docs/.*\.md$''',
48+
]
49+
# Allow UUIDs in comments (often examples)
50+
regexes = [
51+
'''// .*[0-9a-f]{8}-[0-9a-f]{4}''', # UUID in comment
52+
]
53+
54+
[[rules]]
55+
id = "nomad-token"
56+
description = "HashiCorp Nomad ACL Token"
57+
regex = '''(?i)(nomad[_-]?token|x-nomad-token)[\s:=]+["\']?([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})["\']?'''
58+
tags = ["nomad", "token", "hashicorp"]
59+
60+
[[rules]]
61+
id = "postgres-connection-string"
62+
description = "PostgreSQL Connection String with Password"
63+
regex = '''postgres(ql)?://[a-zA-Z0-9_-]+:[^@\s]+@[a-zA-Z0-9_.-]+(:[0-9]+)?/[a-zA-Z0-9_-]+'''
64+
tags = ["database", "postgresql", "connection-string"]
65+
[rules.allowlist]
66+
paths = [
67+
'''.*_test\.go$''',
68+
'''testdata/.*''',
69+
]
70+
# Allow placeholder passwords
71+
regexes = [
72+
'''postgres.*:password@''',
73+
'''postgres.*:REPLACE_ME@''',
74+
'''postgres.*:\$\{.*\}@''', # Environment variables
75+
]
76+
77+
[[rules]]
78+
id = "api-key-pattern"
79+
description = "Generic API Key Pattern"
80+
regex = '''(?i)(api[_-]?key|apikey|access[_-]?key)[\s:=]+["\']([a-zA-Z0-9_\-]{20,})["\']'''
81+
tags = ["api-key", "secret"]
82+
[rules.allowlist]
83+
paths = [
84+
'''.*_test\.go$''',
85+
'''testdata/.*''',
86+
'''docs/.*''',
87+
]
88+
89+
[[rules]]
90+
id = "private-key"
91+
description = "Private Key (RSA, EC, etc.)"
92+
regex = '''-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----'''
93+
tags = ["private-key", "tls", "certificate"]
94+
[rules.allowlist]
95+
paths = [
96+
'''.*_test\.go$''',
97+
'''testdata/.*''',
98+
]
99+
100+
[[rules]]
101+
id = "jwt-token"
102+
description = "JSON Web Token (JWT)"
103+
regex = '''eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}'''
104+
tags = ["jwt", "token"]
105+
[rules.allowlist]
106+
paths = [
107+
'''.*_test\.go$''',
108+
'''testdata/.*''',
109+
]
110+
111+
[[rules]]
112+
id = "litellm-master-key"
113+
description = "LiteLLM Master Key (for BionicGPT/Moni)"
114+
regex = '''(?i)(litellm[_-]?master[_-]?key|master[_-]?key)[\s:=]+["\']?(sk-[a-zA-Z0-9_-]{20,})["\']?'''
115+
tags = ["litellm", "api-key", "bionicgpt"]
116+
117+
[[rules]]
118+
id = "openai-api-key"
119+
description = "OpenAI API Key"
120+
regex = '''sk-[a-zA-Z0-9]{32,}'''
121+
tags = ["openai", "api-key"]
122+
[rules.allowlist]
123+
paths = [
124+
'''.*_test\.go$''',
125+
'''testdata/.*''',
126+
]
127+
128+
[[rules]]
129+
id = "generic-password"
130+
description = "Generic Password Assignment"
131+
regex = '''(?i)(password|passwd|pwd)[\s:=]+["\']([^"\']{8,})["\']'''
132+
tags = ["password", "secret"]
133+
[rules.allowlist]
134+
paths = [
135+
'''.*_test\.go$''',
136+
'''testdata/.*''',
137+
'''docs/.*''',
138+
]
139+
# Allow obvious placeholders
140+
regexes = [
141+
'''(?i)password.*["\'](password|changeme|example|test|demo|placeholder|REPLACE_ME)["\' ]''',
142+
]
143+
144+
# ============================================================================
145+
# Global Allowlist (applies to ALL rules)
146+
# ============================================================================
147+
148+
[allowlist]
149+
description = "Global allowlist for files that can contain secrets"
150+
151+
# File paths to ignore completely
152+
paths = [
153+
'''vendor/.*''', # Third-party dependencies
154+
'''\.git/.*''', # Git internals
155+
'''\.github/.*''', # GitHub workflows (may contain examples)
156+
'''testdata/.*''', # Test fixtures
157+
'''.*_test\.go$''', # Test files
158+
'''docs/.*\.md$''', # Documentation
159+
'''.*\.pb\.go$''', # Protobuf generated files
160+
'''.*_gen\.go$''', # Generated files
161+
'''^\.golangci\.yml$''', # Linter config
162+
'''^go\.sum$''', # Go dependencies checksum
163+
]
164+
165+
# Regex patterns to ignore (applies to file content)
166+
regexes = [
167+
# Ignore environment variable placeholders
168+
'''\$\{[A-Z_]+\}''',
169+
'''\$[A-Z_]+''',
170+
171+
# Ignore common placeholders
172+
'''(?i)(example|test|demo|placeholder|changeme|replace_me|your_.*_here)''',
173+
174+
# Ignore URLs with placeholders
175+
'''https?://localhost''',
176+
'''https?://127\.0\.0\.1''',
177+
'''https?://example\.(com|org|net)''',
178+
179+
# Ignore comments with "fake" or "example"
180+
'''//.*(?i)(fake|example|test|mock)''',
181+
]
182+
183+
# Files to ignore by content (hash-based)
184+
# Note: This is for intentionally committed secrets in test fixtures
185+
stopwords = [
186+
"test",
187+
"example",
188+
"fake",
189+
"mock",
190+
"placeholder",
191+
]
192+
193+
# ============================================================================
194+
# Additional Configuration
195+
# ============================================================================
196+
197+
# Maximum file size to scan (bytes) - skip very large files
198+
[max-file-size]
199+
value = 10485760 # 10 MB
200+
201+
# Performance tuning
202+
[parallelism]
203+
value = 4 # Number of parallel workers

0 commit comments

Comments
 (0)