Security Model for Storing Whisper API Keys in claude-video: External Config and Strict Permissions
claude-video stores Whisper API credentials outside version control in a user-specific configuration directory with 0600 permissions, loading them via environment variables or a protected ~/.config/watch/.env file.
The bradautomates/claude-video repository implements a defense-in-depth approach to protecting sensitive API tokens. By following a "no secrets in source control" principle and utilizing hierarchical configuration precedence, the project ensures that Whisper API keys remain accessible only to the invoking user while supporting multiple backend providers. This article examines the complete security model for storing Whisper API keys in claude-video based on the actual implementation in the Python source files.
Configuration Directory Architecture
All runtime configuration lives under the user's home directory to ensure portability and security across different development environments.
In skills/watch/scripts/config.py (lines 9–11), the repository defines the configuration path using constants named CONFIG_DIR and CONFIG_FILE:
# From skills/watch/scripts/config.py
CONFIG_DIR = Path.home() / ".config" / "watch"
CONFIG_FILE = CONFIG_DIR / ".env"
This externalizes sensitive data from the project repository, ensuring that .env files are never accidentally committed to version control.
Filesystem Permission Hardening
When the configuration file is first created, the setup.py script enforces strict access controls. The file is initialized with mode 0600, granting read and write permissions exclusively to the file owner.
This prevents other users on the same system from reading API credentials, even if they have access to the filesystem. The permission model follows Unix security best practices for sensitive credential storage.
Hierarchical API Key Loading
The load_api_key function in skills/watch/scripts/whisper.py (lines 65–102) implements a three-tier precedence system for discovering API credentials:
- Environment variables – Checks for
GROQ_API_KEYorOPENAI_API_KEYviaos.environ - User-specific config – Reads from
~/.config/watch/.env - Project-local
.env– Falls back to./.envfor reproducible development environments
# Example: Load the Whisper backend and key
from skills.watch.scripts.whisper import load_api_key
backend, api_key = load_api_key() # Prefers GROQ, falls back to OpenAI
if backend is None:
raise RuntimeError("No Whisper API key found")
print(f"Using {backend} backend")
You can manually scaffold the secure config file using standard Unix commands:
mkdir -p ~/.config/watch
printf "GROQ_API_KEY=your_groq_key_here\n" > ~/.config/watch/.env
chmod 600 ~/.config/watch/.env
Backend Selection Logic
If both API keys are present in the environment, claude-video prefers the Groq backend because it offers lower cost and faster inference. The load_api_key function checks for GROQ_API_KEY before falling back to OPENAI_API_KEY, ensuring optimal performance when both credentials are available.
Graceful Failure Handling
When no valid key is found, the transcribe_video function (lines 29–34 in skills/watch/scripts/whisper.py) aborts execution with a SystemExit and provides clear instructions directing the user to set environment variables or edit the user-config file. This prevents the application from running with missing credentials and failing downstream with cryptic API errors.
# The transcribe_video function validates key presence before processing
from skills.watch.scripts.whisper import transcribe_video
from pathlib import Path
segments, used_backend = transcribe_video(
video_path="example.mp4",
audio_out=Path("audio.mp3"),
)
print(f"Transcribed with {used_backend}")
Summary
- External storage: API keys live in
~/.config/watch/.env, outside the repository path - Strict permissions: Config files are created with
0600mode (owner read/write only) - No repository secrets:
.envfiles are excluded from version control via.gitignore - Precedence hierarchy: Environment variables take priority, followed by user config, then project-local files
- Backend preference: Groq is prioritized over OpenAI for cost and speed optimization
- Clear errors: Missing credentials trigger immediate
SystemExitwith actionable guidance
Frequently Asked Questions
Where does claude-video store Whisper API keys?
The application stores credentials in ~/.config/watch/.env within the user's home directory, or reads them from environment variables (GROQ_API_KEY or OPENAI_API_KEY). This location is defined in skills/watch/scripts/config.py and ensures secrets remain outside the git repository.
What file permissions protect the API key storage?
The setup script initializes the configuration file with Unix mode 0600, meaning only the file owner can read or write the credentials. Other users on the system cannot access the API keys even if they have filesystem access.
Which API provider takes precedence if both keys are configured?
Groq is preferred over OpenAI. The load_api_key function checks for GROQ_API_KEY first because the Groq backend is cheaper and faster for Whisper transcription tasks. If the Groq key is absent, the function falls back to OPENAI_API_KEY.
What happens if I run claude-video without configuring an API key?
The transcribe_video function raises a SystemExit with a descriptive error message (implemented at lines 29–34 of skills/watch/scripts/whisper.py). The message directs you to either set environment variables or edit the ~/.config/watch/.env file, preventing the script from attempting API calls with invalid credentials.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →