Skip to content

Commit eaf9e08

Browse files
fix(security): remove leaked API key and add gitleaks secret scanning
Replace hardcoded production API key and URL with YOUR_* placeholders so the existing credential-detection guard falls back to dev mode. Add gitleaks GitHub Action to scan every push to main and every PR for secrets, with custom rules for RunAnywhere API keys, Railway URLs, and Supabase credentials. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a95be75 commit eaf9e08

3 files changed

Lines changed: 96 additions & 2 deletions

File tree

.github/workflows/secret-scan.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Secret Scanning
2+
3+
# =============================================================================
4+
# Gitleaks Secret Scanning Workflow
5+
#
6+
# Scans every push to main and every pull request for leaked secrets,
7+
# API keys, tokens, and internal URLs. Uses the project-level
8+
# .gitleaks.toml for RunAnywhere-specific patterns on top of gitleaks'
9+
# built-in detectors.
10+
# =============================================================================
11+
12+
on:
13+
push:
14+
branches: [main]
15+
pull_request:
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
secret-scan:
22+
name: Gitleaks Secret Scan
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
31+
- name: Run Gitleaks
32+
uses: gitleaks/gitleaks-action@v2
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
GITLEAKS_CONFIG: .gitleaks.toml

.gitleaks.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# =============================================================================
2+
# Gitleaks Configuration — RunAnywhere SDK Monorepo
3+
#
4+
# Custom rules supplement gitleaks' built-in detectors (AWS keys, JWTs, etc.).
5+
# These catch RunAnywhere-specific secrets and internal infrastructure URLs.
6+
# =============================================================================
7+
8+
title = "RunAnywhere Secret Scanning"
9+
10+
# -----------------------------------------------------------------------------
11+
# Custom Rules
12+
# -----------------------------------------------------------------------------
13+
14+
[[rules]]
15+
id = "runanywhere-api-key"
16+
description = "RunAnywhere API key (runa_prod_*, runa_dev_*, runa_staging_*)"
17+
regex = '''runa_(prod|dev|staging)_[A-Za-z0-9_\-]{10,}'''
18+
keywords = ["runa_prod", "runa_dev", "runa_staging"]
19+
20+
[[rules]]
21+
id = "railway-app-url"
22+
description = "Railway production/staging app URL"
23+
regex = '''https?://[a-zA-Z0-9\-]+\.up\.railway\.app'''
24+
keywords = ["railway.app"]
25+
26+
[[rules]]
27+
id = "supabase-url"
28+
description = "Supabase project URL (non-placeholder)"
29+
regex = '''https://[a-z0-9]+\.supabase\.co'''
30+
keywords = ["supabase.co"]
31+
32+
[[rules]]
33+
id = "supabase-anon-key"
34+
description = "Supabase anon/service key"
35+
regex = '''eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{20,}'''
36+
keywords = ["eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"]
37+
38+
# -----------------------------------------------------------------------------
39+
# Allowlists — paths and patterns that are safe to ignore
40+
# -----------------------------------------------------------------------------
41+
42+
[allowlist]
43+
description = "Global allowlist"
44+
45+
paths = [
46+
'''\.gitleaks\.toml$''',
47+
'''CLAUDE\.md$''',
48+
'''\.cursor/plans/.*\.plan\.md$''',
49+
'''thoughts/.*\.md$''',
50+
]
51+
52+
regexTarget = "line"
53+
regexes = [
54+
'''YOUR_PRODUCTION_API_KEY''',
55+
'''YOUR_PRODUCTION_BASE_URL''',
56+
'''YOUR_''',
57+
'''placeholder''',
58+
'''https://placeholder\.supabase\.co''',
59+
]

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/RunAnywhereApplication.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ class RunAnywhereApplication : Application() {
153153
} else {
154154
// PRODUCTION mode - requires API key and base URL
155155
// Configure these via Settings screen or set environment variables
156-
val apiKey = "REDACTED_API_KEY"
157-
val baseURL = "https://REDACTED_URL"
156+
val apiKey = "YOUR_PRODUCTION_API_KEY"
157+
val baseURL = "YOUR_PRODUCTION_BASE_URL"
158158

159159
// Detect placeholder credentials and abort production initialization
160160
if (apiKey.startsWith("YOUR_") || baseURL.startsWith("YOUR_")) {

0 commit comments

Comments
 (0)