Skip to content

Security: aboigues/gamma-cli

Security

SECURITY.md

Security Best Practices

This document outlines security best practices for developing and testing the Gamma CLI application.

Table of Contents

API Key Management

✅ DO

  1. Store API keys in environment variables

    export GAMMA_API_KEY="your-api-key-here"
  2. Use a .env file locally (which is gitignored)

    # .env file
    GAMMA_API_KEY=your-api-key-here
  3. Use GitHub Secrets for CI/CD

    • Go to Repository Settings → Secrets and variables → Actions
    • Add GAMMA_API_KEY as a secret
    • Reference it in workflows as ${{ secrets.GAMMA_API_KEY }}
  4. Use secure configuration storage

    • The CLI stores API keys in ~/.gamma/config.json
    • This file has restricted permissions (owner-only read/write)

❌ DON'T

  1. Never hardcode API keys in source code

    # BAD - Don't do this!
    api_key = "sk_live_abc123..."
  2. Never commit .env or config.json files

    • These files are in .gitignore - keep them there!
    • Use .env.example with placeholder values instead
  3. Never log or print API keys

    # BAD - Don't do this!
    print(f"Using API key: {api_key}")
    logger.debug(f"API Key: {api_key}")
  4. Never include API keys in error messages

    # BAD - Don't do this!
    raise Exception(f"API call with key {api_key} failed")

Environment Variables

Priority Order

The application checks for API keys in this order:

  1. Direct parameter (when initializing GammaClient)
  2. Environment variable GAMMA_API_KEY
  3. Configuration file ~/.gamma/config.json

Setting Environment Variables

Linux/macOS

# Temporarily (current session only)
export GAMMA_API_KEY="your-api-key"

# Permanently (add to ~/.bashrc or ~/.zshrc)
echo 'export GAMMA_API_KEY="your-api-key"' >> ~/.bashrc
source ~/.bashrc

Windows

# Temporarily (current session only)
$env:GAMMA_API_KEY="your-api-key"

# Permanently (system-wide)
setx GAMMA_API_KEY "your-api-key"

Using .env file

# Create .env file (gitignored by default)
echo "GAMMA_API_KEY=your-api-key" > .env

# The application will automatically load it

Testing Securely

Test Structure

We use three types of tests:

  1. Unit Tests - No real API calls, use mocked responses
  2. Integration Tests - Real API calls, require GAMMA_API_KEY
  3. Security Tests - Verify that credentials are never exposed

Running Tests

# Run unit tests only (no API key needed)
pytest -v -m "not integration"

# Run security tests
pytest -v -m security

# Run integration tests (requires GAMMA_API_KEY)
pytest -v -m integration

# Run all tests
pytest -v

Writing Secure Tests

Use fixtures for credentials

# Good - Use the provided fixtures
def test_api_call(integration_client):
    """Integration test using real API"""
    result = integration_client.list_themes()
    assert isinstance(result, list)

# Good - Use mock fixtures for unit tests
def test_api_call_mocked(secure_client, mock_requests_session):
    """Unit test with mocked API"""
    mock_requests_session.request.return_value.json.return_value = []
    result = secure_client.list_themes()
    assert isinstance(result, list)

Never log API keys in tests

# Bad - Don't do this!
def test_client(real_api_key):
    print(f"Testing with key: {real_api_key}")  # NEVER!

# Good - Keep credentials private
def test_client(integration_client):
    # Client is already configured, don't access the key
    result = integration_client.list_themes()

Available Test Fixtures

See tests/conftest.py for all available fixtures:

  • mock_api_key - Fake API key for unit tests
  • clean_environment - Clean test environment without any API keys
  • env_with_api_key - Test environment with mock API key set
  • real_api_key - Real API key from environment (integration tests only)
  • skip_if_no_api_key - Automatically skip tests if no API key available
  • secure_client - GammaClient with mocked requests (unit tests)
  • integration_client - GammaClient with real API (integration tests)

GitHub Actions & CI/CD

Setting Up Secrets

  1. Navigate to your repository on GitHub
  2. Go to SettingsSecrets and variablesActions
  3. Click New repository secret
  4. Name: GAMMA_API_KEY
  5. Value: Your actual Gamma API key
  6. Click Add secret

Workflow Structure

Our GitHub Actions workflow (./github/workflows/tests.yml) includes:

  1. Security Tests - Always run, even on forks
  2. Unit Tests - Always run, no secrets needed
  3. Integration Tests - Only run when secrets are available
  4. Code Quality - Linting, formatting, and secret scanning

Security Features

  • ✅ Secrets are never logged or printed
  • ✅ Integration tests are skipped for external PRs (where secrets aren't available)
  • ✅ Basic secret scanning to catch hardcoded credentials
  • ✅ Separate jobs for different test types
  • ✅ Matrix testing across multiple Python versions

Development Guidelines

Before Committing

  1. Check for hardcoded secrets

    # Use the security tests
    pytest -v -m security
  2. Verify .gitignore

    # Ensure sensitive files are ignored
    git status
    # Should NOT show .env or config.json
  3. Review changes for credential exposure

    git diff
    # Look for any API keys or secrets

Code Review Checklist

When reviewing code:

  • No hardcoded API keys or secrets
  • API keys come from environment variables
  • Error messages don't expose credentials
  • Logging doesn't include sensitive data
  • Tests use fixtures, not real credentials
  • .env and config.json are in .gitignore

File Permissions

Configuration files should have restricted permissions:

# Set proper permissions on config file
chmod 600 ~/.gamma/config.json

# Verify permissions
ls -la ~/.gamma/config.json
# Should show: -rw------- (owner read/write only)

Common Security Pitfalls

⚠️ Pitfall 1: Logging Request Headers

# BAD - Headers contain the API key!
print(f"Request headers: {headers}")

# GOOD - Log only non-sensitive information
print(f"Request to: {url}")

⚠️ Pitfall 2: Exception Messages

# BAD - Exception might contain API key
raise Exception(f"Failed with config: {config}")

# GOOD - Generic error message
raise Exception("API request failed")

⚠️ Pitfall 3: Verbose Debugging

# BAD - Verbose mode might expose credentials
client = GammaClient(verbose=True)  # Use carefully!

# GOOD - Verbose mode disabled in production
client = GammaClient(verbose=False)

⚠️ Pitfall 4: Test Data in VCS

# BAD - Committing test data with real API responses
test_data = {
    "api_key": "sk_live_real_key_here",  # NEVER!
    "response": {...}
}

# GOOD - Use mocked or sanitized data
test_data = {
    "response": {"id": "test_id", "title": "Test"}
}

Incident Response

If an API Key is Exposed

  1. Immediately revoke the key

  2. Remove from git history (if committed)

    # Use tools like git-filter-branch or BFG Repo-Cleaner
    # Contact GitHub support if needed
  3. Update all systems

    • Update local .env files
    • Update GitHub Secrets
    • Update any deployment configurations
  4. Audit for unauthorized usage

    • Check Gamma API usage logs
    • Look for suspicious activity

Reporting Security Issues

If you discover a security vulnerability:

  1. Do NOT open a public issue
  2. Do NOT discuss it in public channels
  3. DO email the maintainers privately
  4. DO provide details about the vulnerability

We will work with you to:

  • Verify the issue
  • Develop a fix
  • Credit you for responsible disclosure (if desired)

Additional Resources

Audit Log

Date Version Changes
2025-11-22 1.0 Initial security documentation

There aren’t any published security advisories