diff --git a/.env.test.example b/.env.test.example index e1d35cdc1f..b3f7d6404e 100644 --- a/.env.test.example +++ b/.env.test.example @@ -13,16 +13,16 @@ # --- LLM Provider API Keys (for cassette recording) --- # OpenAI: https://platform.openai.com/api-keys -OPENAI_API_KEY=sk-replace-with-real-key +OPENAI_API_KEY=YOUR_OPENAI_KEY_HERE # Anthropic: https://console.anthropic.com/settings/keys -ANTHROPIC_API_KEY=sk-ant-replace-with-real-key +ANTHROPIC_API_KEY=YOUR_ANTHROPIC_KEY_HERE # Google AI Studio (Gemini): https://aistudio.google.com/apikey GOOGLE_API_KEY=replace-with-real-key # Groq: https://console.groq.com/keys -GROQ_API_KEY=gsk_replace-with-real-key +GROQ_API_KEY=YOUR_GROQ_KEY_HERE # Mistral: https://console.mistral.ai/api-keys/ MISTRAL_API_KEY=replace-with-real-key @@ -40,7 +40,7 @@ WRITER_API_KEY=replace-with-real-key REPLICATE_API_TOKEN=replace-with-real-key # OpenRouter (budget-friendly proxy): https://openrouter.ai/keys -OPENROUTER_API_KEY=sk-or-replace-with-real-key +OPENROUTER_API_KEY=YOUR_OPENROUTER_KEY_HERE # --- AWS (for Bedrock / SageMaker cassette recording) --- # AWS_ACCESS_KEY_ID=replace-with-real-key diff --git a/.github/workflows/fr-pr.yaml b/.github/workflows/fr-pr.yaml index 50e3de11d1..d92e1eea55 100644 --- a/.github/workflows/fr-pr.yaml +++ b/.github/workflows/fr-pr.yaml @@ -11,7 +11,29 @@ concurrency: cancel-in-progress: true jobs: + secret-scan: + name: Secret Policy Check + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Fail on hardcoded provider API keys + shell: bash + run: | + set -euo pipefail + + regex='(sk-(proj-)?[A-Za-z0-9_-]{20,}|sk-or-v1-[A-Za-z0-9]{20,}|sk-ant-[A-Za-z0-9_-]{20,}|gsk_[A-Za-z0-9_-]{20,})' + + if git grep -nI -E "$regex" -- . ':(exclude)*.lock' ':(exclude)*.env.example' ':(exclude)*.env.*.example'; then + echo "::error::Potential hardcoded provider key detected. Remove it and use placeholders or GitHub Secrets." + exit 1 + fi + + echo "No hardcoded provider key patterns detected." + fr-tests: + needs: secret-scan name: FR Tests (py${{ matrix.python-version }}) runs-on: ubuntu-latest timeout-minutes: 45 @@ -49,6 +71,7 @@ jobs: if-no-files-found: ignore non-fr-tests: + needs: secret-scan name: Non-FR Tests (py${{ matrix.python-version }}) runs-on: ubuntu-latest timeout-minutes: 60