diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml new file mode 100644 index 0000000..c642c44 --- /dev/null +++ b/.github/workflows/security.yaml @@ -0,0 +1,24 @@ +name: Security / Secrets Scan + +on: + pull_request: + +jobs: + gitleaks: + name: Security Leaks + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + steps: + - name: Checkout (full history para varredura correta) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run Gitleaks + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: --config .gitleaks.toml --redact --verbose diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..9936f55 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,56 @@ +title = "Local Gitleaks Config" + +[extend] + +[allowlist] +description = "False positives permitidos" +paths = [ + '''tests/.*''', + '''\.secret-allowlist''' +] +regexes = [ + '''EXEMPLO_TOKEN_FAKE_123''' +] + +[[rules]] +id = "generic-api-key" +description = "Generic API Key" +regex = '''(?i)(api[_-]?key|secret|token)['"\s:=]{0,10}[A-Za-z0-9_\-]{16,64}''' +tags = ["apikey", "generic"] + +[[rules]] +id = "github-pat" +description = "GitHub Personal Access Token" +regex = '''ghp_[0-9A-Za-z]{36}''' +tags = ["github", "token"] + +[[rules]] +id = "aws-access-key" +description = "AWS Access Key ID" +regex = '''AKIA[0-9A-Z]{16}''' +tags = ["aws", "key"] + +[[rules]] +id = "aws-secret-key" +description = "AWS Secret Key (heurística)" +regex = '''(?i)aws(.{0,20})?(secret|key)['"\s:=]{0,10}([A-Za-z0-9/+=]{40})''' +tags = ["aws", "key"] + +[[rules]] +id = "slack-token" +description = "Slack Token" +regex = '''xox[baprs]-[A-Za-z0-9-]{10,48}''' +tags = ["slack", "token"] + +[[rules]] +id = "private-key" +description = "Private Key Block" +regex = '''-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----''' +tags = ["key", "private"] + +[[rules]] +id = "jwt" +description = "Provável JWT" +regex = '''eyJ[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}''' +tags = ["jwt", "token"] + diff --git a/.husky/pre-commit b/.husky/pre-commit index d0a7784..31a3747 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1,8 @@ + +HUSKY=0 ./.scripts/gitleaks protect --staged --config .gitleaks.toml --redact || { + echo "❌ Segredos suspeitos." + echo "🔒 Use './.scripts/gitleaks protect --staged --config .gitleaks.toml --redact' para verificar localmente." + exit 1 +} + npx lint-staged \ No newline at end of file diff --git a/.scripts/gitleaks b/.scripts/gitleaks new file mode 100755 index 0000000..de6a28d Binary files /dev/null and b/.scripts/gitleaks differ diff --git a/package.json b/package.json index f0d9434..209f42f 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ "build": "next build", "migration:create": "node-pg-migrate -m infra/migrations create", "migration:up": "node-pg-migrate -m infra/migrations --envPath .env.development up", + "secrets:scan": "./.scripts/gitleaks detect --config .gitleaks.toml --no-git --redact --source .", + "secrets:scan:git": "./.scripts/gitleaks detect --config .gitleaks.toml --redact --source .", + "secrets:scan:staged": "git diff --cached --name-only | xargs -r ./.scripts/gitleaks protect --staged --config .gitleaks.toml --redact", "wait-for-postgres": "node infra/scripts/wait-for-postgres.js", "prepare": "husky", "commit": "cz"