Spaces:
Sleeping
Sleeping
Download backend/crypto_utils.py from Comfoa/Civilly-Simplified-Backend: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/spaces/Comfoa/Civilly-Simplified-Backend/resolve/main/backend/crypto_utils.py
- Command line
-
hf download hf://spaces/Comfoa/Civilly-Simplified-Backend/backend/crypto_utils.py
-
curl -L -o crypto_utils.py https://huggingface.co/spaces/Comfoa/Civilly-Simplified-Backend/resolve/main/backend/crypto_utils.py
3.9 kB
| """ | |
| API key encryption utilities for OpenCouncil. | |
| Provides Fernet-based symmetric encryption for the Groq API key | |
| so it can be stored encrypted in the database or config files. | |
| For Vercel/GitHub deployment: | |
| 1. Generate an encryption key once: python -c "from crypto_utils import generate_key; print(generate_key())" | |
| 2. Set ENCRYPTION_KEY as a Vercel environment variable | |
| 3. Set GROK_API_KEY (encrypted) as a Vercel environment variable | |
| 4. The app decrypts at runtime using the ENCRYPTION_KEY | |
| This means even if someone gets access to your DB or .env, | |
| the API key is still encrypted with a separate key. | |
| """ | |
| import base64 | |
| import os | |
| from typing import Optional | |
| try: | |
| from cryptography.fernet import Fernet | |
| from cryptography.hazmat.primitives import hashes | |
| from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC | |
| HAS_CRYPTO = True | |
| except ImportError: | |
| HAS_CRYPTO = False | |
| def generate_key() -> str: | |
| """Generate a new Fernet encryption key. | |
| Run this once and save the output as ENCRYPTION_KEY env var. | |
| Usage: | |
| python -c "from crypto_utils import generate_key; print(generate_key())" | |
| """ | |
| if not HAS_CRYPTO: | |
| raise ImportError("Install cryptography: pip install cryptography") | |
| return Fernet.generate_key().decode() | |
| def _get_fernet(encryption_key: Optional[str] = None) -> Fernet: | |
| """Get a Fernet instance using the provided key or ENCRYPTION_KEY env var.""" | |
| if not HAS_CRYPTO: | |
| raise ImportError( | |
| "cryptography package is required for API key encryption. " | |
| "Install it with: pip install cryptography" | |
| ) | |
| key = encryption_key or os.getenv("ENCRYPTION_KEY") | |
| if not key: | |
| raise ValueError( | |
| "ENCRYPTION_KEY is required. Generate one with: " | |
| "python -c \"from crypto_utils import generate_key; print(generate_key())\"" | |
| ) | |
| # Ensure key is bytes and properly formatted | |
| if isinstance(key, str): | |
| key = key.encode() | |
| return Fernet(key) | |
| def encrypt_api_key(api_key: str, encryption_key: Optional[str] = None) -> str: | |
| """Encrypt an API key (e.g., DeepSeek key) for safe storage. | |
| Args: | |
| api_key: The plaintext API key to encrypt | |
| encryption_key: Optional custom encryption key (defaults to ENCRYPTION_KEY env var) | |
| Returns: | |
| Base64-encoded encrypted string | |
| """ | |
| f = _get_fernet(encryption_key) | |
| encrypted = f.encrypt(api_key.encode()) | |
| return encrypted.decode() | |
| def decrypt_api_key(encrypted_key: str, encryption_key: Optional[str] = None) -> str: | |
| """Decrypt an API key that was encrypted with encrypt_api_key(). | |
| Args: | |
| encrypted_key: The encrypted API key string | |
| encryption_key: Optional custom encryption key (defaults to ENCRYPTION_KEY env var) | |
| Returns: | |
| Plaintext API key | |
| """ | |
| f = _get_fernet(encryption_key) | |
| decrypted = f.decrypt(encrypted_key.encode()) | |
| return decrypted.decode() | |
| def get_api_key_from_env() -> Optional[str]: | |
| """Get the Groq API key, supporting both plaintext and encrypted modes. | |
| Resolution order: | |
| 1. GROK_API_KEY (plaintext) — for local dev | |
| 2. ENCRYPTED_GROK_KEY + ENCRYPTION_KEY — for production/GitHub-safe deploy | |
| Returns: | |
| The decrypted API key, or None if not configured. | |
| """ | |
| # First try plaintext (local dev) | |
| plain_key = os.getenv("GROK_API_KEY") | |
| if plain_key: | |
| return plain_key | |
| # Then try encrypted (production/GitHub-safe) | |
| encrypted_key = os.getenv("ENCRYPTED_GROK_KEY") | |
| encryption_key = os.getenv("ENCRYPTION_KEY") | |
| if encrypted_key and encryption_key: | |
| try: | |
| return decrypt_api_key(encrypted_key, encryption_key) | |
| except Exception as e: | |
| print(f"[WARN] Failed to decrypt API key: {e}") | |
| return None | |
| return None | |