This guide explains how to securely manage API keys for WebSocket connections (particularly AIS stream) in CV Studio. The implementation follows security best practices by keeping sensitive credentials out of source code.
The original issue requested:
"inspire toi de ça pour le websocket préinscrit la clées, mais cache" (Use this as inspiration for the websocket, pre-configure the key but hide it)
This means:
- ✅ Pre-configure the API key (make it easy to set up)
- ✅ Hide the key (don't hardcode it in visible source files)
API keys are now loaded from environment variables instead of being hardcoded:
api_key = os.getenv('AIS_STREAM_API_KEY')Created .env.example template for easy setup:
# Copy .env.example to .env
cp .env.example .env
# Edit .env and add your API key
AIS_STREAM_API_KEY=your_actual_api_key_hereThe actual .env file is git-ignored for security.
Created src/utils/env_config.py module for managing environment variables:
from src.utils.env_config import get_ais_config, is_api_key_configured
# Check if API key is configured
if not is_api_key_configured():
print("Please set AIS_STREAM_API_KEY")
# Get configuration
config = get_ais_config()
api_key = config['api_key']
url = config['url']The examples/example_ais_stream.py now:
- ✅ Loads API key from environment variables
- ✅ Falls back to command line argument for convenience
- ✅ Shows clear error messages if API key is missing
- ✅ Doesn't expose API keys in code or logs
Best for development and local testing.
-
Copy the example file:
cp .env.example .env
-
Edit
.envand add your API key:AIS_STREAM_API_KEY=your_api_key_here AIS_STREAM_URL=wss://stream.aisstream.io/v0/stream AIS_STREAM_BOUNDING_BOX=[[[-5, 36], [36, 36], [36, 46], [-5, 46], [-5, 36]]]
-
Run the example:
python examples/example_ais_stream.py
Best for production and CI/CD pipelines.
# Set environment variable
export AIS_STREAM_API_KEY='your_api_key_here'
# Run the example
python examples/example_ais_stream.pyOn Windows:
set AIS_STREAM_API_KEY=your_api_key_here
python examples/example_ais_stream.pyOnly use for quick testing. API key will be visible in shell history.
python examples/example_ais_stream.py YOUR_API_KEY- API Keys Hidden: No real API keys in source code
- Git Ignored:
.envfiles are automatically ignored by git - Example Template:
.env.exampleshows structure without real credentials - Password Fields: Node UI uses password fields for API keys
- Secure Logs: API keys are not logged or displayed
.env.example: Template for environment variablesrequirements.txt: Addedpython-dotenv>=0.19.0examples/example_ais_stream.py: Updated to use environment variablessrc/utils/env_config.py: New utility module for env managementnode/InputNode/README_Websocket_AIS.md: Updated documentationtests/test_env_config.py: Comprehensive test suite
# Install dependencies
pip install python-dotenv
# Run environment config tests
python tests/test_env_config.py
# Run WebSocket abstraction tests
python tests/test_websocket_abstraction.pyAll tests pass:
- ✅ Environment variable loading
- ✅ API key configuration checks
- ✅ .env file parsing
- ✅ Security validation (no hardcoded keys)
- ✅ WebSocket abstraction layer
import os
from pathlib import Path
from dotenv import load_dotenv
from node.InputNode.node_websocket import AISStreamHandler
# Load environment variables
env_path = Path(__file__).parent / '.env'
load_dotenv(dotenv_path=env_path)
# Get API key from environment
api_key = os.getenv('AIS_STREAM_API_KEY')
if not api_key:
raise ValueError("Please set AIS_STREAM_API_KEY environment variable")
# Create handler
handler = AISStreamHandler(
url="wss://stream.aisstream.io/v0/stream",
api_key=api_key,
bounding_box=[[[-5, 36], [36, 36], [36, 46], [-5, 46], [-5, 36]]]
)The WebSocket node in the CV Studio editor automatically:
- Shows a password field for API key input
- Hides the API key with asterisks (*****)
- Doesn't log or display the API key
- Uses secure connection (wss://)
The problem statement provided this example code:
async def connect_ais_stream():
async with websockets.connect("wss://stream.aisstream.io/v0/stream") as websocket:
subscribe_message = {"APIKey": "58462ad27e7ad5bd8004d4948e46015ec75cc5df", # ❌ Hardcoded!
"BoundingBoxes": [[[-90, -180], [90, 180]]],
"FiltersShipMMSI": ["368207620", "367719770", "211476060"],
"FilterMessageTypes": ["PositionReport"]}
# ... rest of code- Hardcoded API Key: Key is visible in source code
- Security Risk: Key will be committed to git
- No Flexibility: Can't change key without editing code
- Double asyncio.run(): Bug in
asyncio.run(asyncio.run(...))
# Load from environment
api_key = os.getenv('AIS_STREAM_API_KEY') # ✅ Hidden
handler = AISStreamHandler(
url="wss://stream.aisstream.io/v0/stream",
api_key=api_key, # ✅ Secure
bounding_box=[[[-90, -180], [90, 180]]]
)
# Fixed: Single asyncio.run()
asyncio.run(main()) # ✅ Correct- Never commit
.envfiles: Already in.gitignore - Use
.env.examplefor documentation: Shows structure without secrets - Rotate keys regularly: Easy to update in
.envfile - Different keys for different environments: Use separate
.envfiles - Use environment variables in production: Don't rely on
.envfiles in prod
- Visit https://aisstream.io/
- Sign up for a free account
- Copy your API key
- Add it to your
.envfile
For issues or questions:
- Check the documentation in
node/InputNode/README_Websocket_AIS.md - Run the example:
python examples/example_ais_stream.py - Review tests:
python tests/test_env_config.py