Aikido acquires Allseek & Haicker to lead race in autonomous AI pentesting →
Aikido

Prevent Hardcoded Secrets in Python

Prevent Hardcoded Secrets in Python: Catch Security Vulnerabilities Before Production

Every Python developer has been there—you're pushing to meet a deadline, and you hardcode an API key "just temporarily." Then that temporary fix makes it to production, gets committed to Git history, and suddenly your credentials are exposed forever.

According to GitGuardian's 2024 State of Secrets Sprawl report, over 12.8 million secrets were detected in public GitHub repositories, with API keys and database credentials being the most frequently exposed. The average cost of a data breach involving exposed credentials is $4.45 million, according to IBM's 2024 Cost of a Data Breach Report.

This AI code review rule automatically catches hardcoded secrets in your Python code during pull requests, preventing costly security incidents before they happen.

What This Rule Detects

This rule scans for the most common types of hardcoded secrets that cause real-world security incidents:

  • API keys: OpenAI, Stripe, AWS, Google Cloud, third-party services
  • Database credentials: Connection strings with embedded passwords
  • Authentication tokens: JWT secrets, session keys, OAuth tokens
  • Encryption keys: Symmetric keys, salts, certificates
  • Service credentials: Docker registry tokens, CI/CD secrets

The rule uses intelligent pattern matching to catch both obvious cases (API_KEY = "sk-12345") and subtle ones (inline credentials in connection strings).

Real-World Examples

❌ Code That Causes Security Incidents

1`*#This leaked OpenAI key cost a startup $2,000 in unauthorized usage*`
2
3`OPENAI_API_KEY = "sk-proj-Ab3dEf7GhI9jKlMnOpQrStUvWxYz123456789"`
4
5`*# Database breach from exposed connection string*`
6
7`DATABASE_URL = "postgresql://admin:prod_password_2024@db-cluster.company.com:5432/users"`
8
9`*# JWT secret in code = anyone can forge authentication tokens*`
10
11`JWT_SECRET_KEY = "super-secret-key-that-never-changes"`
12
13`*# This pattern shows up in 40% of credential leaks*`
14
15`class APIClient:
16    def __init__(self):
17        self.session = requests.Session()
18        self.session.headers.update({
19            "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
20        })`

✅ Code That Passes Security Review

1import os
2
3# Environment variables keep secrets out of code
4OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
5if not OPENAI_API_KEY:
6    raise ValueError("OPENAI_API_KEY environment variable required")
7
8# Clean separation of config and code
9DATABASE_URL = os.getenv("DATABASE_URL")
10
11# Secrets loaded at runtime, not build time
12JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY")
13
14class APIClient:
15    def __init__(self):
16        token = os.getenv("API_TOKEN")
17        if not token:
18            raise ValueError("API_TOKEN environment variable required")
19        
20        self.session = requests.Session()
21        self.session.headers.update({"Authorization": f"Bearer {token}"})
22
23# Pro tip: Validate all required secrets at startup
24def validate_required_secrets():
25    required = ["OPENAI_API_KEY", "DATABASE_URL", "JWT_SECRET_KEY"]
26    missing = [key for key in required if not os.getenv(key)]
27    
28    if missing:
29        raise EnvironmentError(f"Missing required environment variables: {missing}")
30
31validate_required_secrets()  # Fail fast if misconfigured
`*# pip install python-dotenv*
from dotenv import load_dotenv
import os

*# Load secrets from .env file (never commit this file!)*
load_dotenv()

*# Now your secrets work locally without hardcoding*
DATABASE_URL = os.getenv("DATABASE_URL")  *# from .env file*
API_KEY = os.getenv("API_KEY")           *# from .env file*`

**`.env` file** (add to `.gitignore`):

`DATABASE_URL=postgresql://localhost:5432/myapp_dev
API_KEY=your_development_api_key
STRIPE_KEY=sk_test_your_test_key`
1# For production: Use your cloud provider's secret manager
2import boto3
3import json
4
5def get_secret(secret_name):
6    client = boto3.client('secretsmanager', region_name='us-west-2')
7    response = client.get_secret_value(SecretId=secret_name)
8    return json.loads(response['SecretString'])
9
10# Load secrets at runtime
11secrets = get_secret('prod/app/secrets')
12DATABASE_URL = secrets['database_url']
13API_KEY = secrets['api_key']
def load_docker_secret(secret_name):
    """Load secret from Docker swarm secret or fall back to env var"""
    try:
        with open(f'/run/secrets/{secret_name}', 'r') as f:
            return f.read().strip()
    except FileNotFoundError:
        return os.getenv(secret_name.upper())

DATABASE_PASSWORD = load_docker_secret('db_password')
1class Config:
2    """Centralized configuration with validation"""
3    def __init__(self):
4        # Fail fast on missing secrets
5        self.database_url = self._require_env('DATABASE_URL')
6        self.api_key = self._require_env('API_KEY')
7        self.debug = os.getenv('DEBUG', 'False').lower() == 'true'
8    
9    def _require_env(self, key):
10        value = os.getenv(key)
11        if not value:
12            raise ValueError(f'Required environment variable {key} is not set')
13        return value
14
15config = Config()  # Will raise error if secrets are missing

Why This Rule Saves You Time and Money

Prevents Expensive Mistakes: A single leaked API key can result in thousands of dollars in unauthorized usage. According to Verizon's 2024 Data Breach Investigations Report, 74% of data breaches involve the human element, including accidentally exposed credentials.

Saves Code Review Time: Instead of manually checking every PR for hardcoded secrets, the AI does it automatically and consistently. Security teams spend an average of 23% of their time on manual code reviews, according to GitLab's 2024 DevSecOps Report.

Reduces Security Incidents: GitHub's 2024 State of the Octoverse report shows that 95% of credential leaks happen through source code commits. Automated detection prevents most of these incidents.

Improves Team Productivity: Developers get immediate feedback instead of finding out about security issues days later during security reviews.

Compliance Made Easy: Automatically enforces security best practices required by SOC 2, ISO 27001, and other compliance frameworks.

Experience This Rule in Action with Aikido Security

Ready to stop worrying about accidentally committing secrets? Aikido Security's AI code review catches these issues the moment you open a pull request.

What you get:

  • Instant feedback on every PR
  • Zero false positives for real development work
  • Seamless integration with your existing workflow
  • Custom rules for your specific secret patterns
  • Team-wide enforcement of security best practices

The best part? It takes 2 minutes to set up and starts protecting your code immediately. No complex configuration, no security expertise required.

Get secure for free

Secure your code, cloud, and runtime in one central system.
Find and fix vulnerabilities fast automatically.

No credit card required | Scan results in 32secs.