Security Best Practices for API Key Storage and Environment Handling in Claude-Video

Claude-Video implements a defense-in-depth strategy for API credentials by enforcing 0600 file permissions, validating access controls at runtime, and prioritizing environment variables over dot-env files to prevent accidental key exposure.

The bradautomates/claude-video repository demonstrates production-grade security patterns for managing sensitive credentials like Groq and OpenAI Whisper API keys. By combining restricted filesystem permissions with runtime validation and environment-first loading patterns, the codebase ensures that secrets remain protected throughout the application lifecycle.

Defense-in-Depth Architecture for Secret Storage

Claude-Video employs multiple layers of protection to ensure API keys never leak through filesystem access or version control.

Restricted File Permissions and Isolated Config Locations

The installer in skills/watch/scripts/setup.py creates a dedicated configuration directory at ~/.config/watch/ and immediately sets permissions to 0o700 (owner-only access). When scaffolding the .env file, it applies mode 0600 (read/write for owner only) through explicit os.chmod calls (lines 31-38). This prevents group members or other system users from reading the file, even if they possess filesystem access.

Empty Placeholder Pattern

Rather than prompting for and writing actual API keys to disk, the installer only creates empty placeholders (GROQ_API_KEY= and OPENAI_API_KEY=) in the scaffolded file (lines 52-54). This ensures that real credentials never touch the filesystem unless the user explicitly adds them manually, eliminating the risk of accidental commits or logs containing sensitive data.

Runtime Permission Validation

Before reading any configuration, the _check_file_permissions function in setup.py (lines 73-87) validates that the .env file is not world-readable or group-readable. If permissive permissions are detected, the system warns the user immediately, preventing scenarios where secrets might be exposed through misconfigured file sharing or backup processes.

Environment Variable Precedence

The load_api_key function in skills/watch/scripts/whisper.py (lines 65-73) implements a strict hierarchy: it first checks os.environ for GROQ_API_KEY or OPENAI_API_KEY, and only falls back to the dot-env locations (~/.config/watch/.env and a local .env) if environment variables are unset. This pattern supports CI/CD pipelines and containerized deployments where injecting secrets via environment variables is standard practice.

Safe Configuration Parsing

The read_env_file function in skills/watch/scripts/config.py (lines 36-44) safely strips inline comments while preserving # characters inside quoted values. This prevents accidental corruption of API keys that might contain hash symbols or base64-encoded strings, ensuring that the parsed configuration exactly matches the user's intent.

Idempotent Setup and Optional Key Handling

After successful installation, the setup script appends SETUP_COMPLETE=true to the .env file (lines 42-60) with the same restrictive permissions. This flag enables idempotent behavior, preventing the installer from re-prompting users on subsequent runs while maintaining the security boundary of the configuration file. As documented in the README, these keys remain optional—leaving them blank disables the Whisper integration entirely, allowing users to run the application without storing any third-party credentials.

Practical Implementation Examples

To load an API key with the environment-first fallback pattern used by the Whisper integration:

from whisper import load_api_key

backend, api_key = load_api_key()          # prefers Groq, falls back to OpenAI

if not api_key:
    raise RuntimeError("No Whisper API key found")

To safely read configuration values with proper comment handling:

from config import read_env_file

env = read_env_file()                      # reads ~/.config/watch/.env

detail = env.get("WATCH_DETAIL", "balanced")

To manually create a secure configuration file with proper permissions:

mkdir -p ~/.config/watch
cat > ~/.config/watch/.env <<EOF
GROQ_API_KEY=your-groq-key
OPENAI_API_KEY=your-openai-key
WATCH_DETAIL=balanced
EOF
chmod 600 ~/.config/watch/.env

Summary

  • Create files with mode 0600: The installer explicitly sets owner-only permissions on ~/.config/watch/.env during creation.
  • Validate permissions at runtime: The _check_file_permissions function warns if the file is accessible to group or other users.
  • Prefer environment variables: The load_api_key function checks os.environ before falling back to dot-env files.
  • Never auto-populate secrets: The installer only writes empty placeholders, requiring manual user intervention for real keys.
  • Parse comments safely: The read_env_file function handles inline comments without corrupting values containing hash symbols.

Frequently Asked Questions

Where does Claude-Video store API keys?

Claude-Video stores API keys in ~/.config/watch/.env with mode 0600 permissions, ensuring only the file owner can read or write the configuration. According to the source code in skills/watch/scripts/setup.py, this location is created with explicit os.chmod calls to prevent group or other access.

How does Claude-Video prevent accidental key exposure?

The repository prevents exposure through the empty placeholder pattern: the installer never writes user-provided keys to disk, only scaffolding empty variables like GROQ_API_KEY=. Combined with runtime permission checks in _check_file_permissions and strict file mode 0600, this ensures credentials cannot be leaked through filesystem access or version control.

Can I use environment variables instead of the .env file?

Yes. The load_api_key function in skills/watch/scripts/whisper.py explicitly checks os.environ for GROQ_API_KEY and OPENAI_API_KEY before reading from ~/.config/watch/.env. This environment-first approach allows secure deployment in containers and CI/CD pipelines without writing secrets to disk.

What happens if the .env file has insecure permissions?

If the .env file is group-readable or world-readable, the _check_file_permissions function in setup.py (lines 73-87) detects the permissive mode and emits a warning before proceeding. This runtime validation acts as a safety net against accidental permission changes or overly permissive umask settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →