This document outlines security best practices for this repository to prevent accidental exposure of sensitive credentials and secrets.
- ✗ FORBIDDEN:
.envfiles with real credentials - ✗ FORBIDDEN: Hard-coded API keys, passwords, tokens
- ✗ FORBIDDEN: AWS/Azure/GCP credentials
- ✗ FORBIDDEN: Database passwords
- ✓ ALLOWED:
.env.templatewith placeholder values
Use one of these methods for credentials:
Mandatory runtime secret requirements:
MINIO_SSO_BRIDGE_SESSION_SECRETmust be set to a strong non-placeholder value (32+ chars).KEYCLOAK_GATEWAY_CLIENT_SECRETmust be set before enabling the kind shared SSO gateway.
VITE_DEMO_AUTO_ADMIN=trueis strictly for controlled demos and local showcase environments.- Never enable
VITE_DEMO_AUTO_ADMINin production. - Demo mode must still authenticate against Keycloak; use
VITE_DEMO_USERNAMEonly as a login hint and not as a secret store. KEYCLOAK_DEMO_AUTO_LOGINisfalseby default. Setting it totrueenables automatic credential submission in the Keycloak login theme and must remain disabled outside isolated demo environments.SUPERSET_OAUTH_DEFAULT_ROLEdefaults toGamma; using OAuth auto-registration withAdminnow requires explicit opt-in (SUPERSET_ALLOW_AUTO_ADMIN_ROLE=true).- Airflow metadata Postgres manifests use
POSTGRES_HOST_AUTH_METHOD=scram-sha-256; keep the Service cluster-internal and add explicitpg_hba/network policy controls for production. - Airflow OAuth role mapping is claim-driven (
admin/airflow_admin->Admin;airflow_op->Op;airflow_user->User;airflow_viewer->Viewer) with default fallback roleViewer; avoid broadeningAIRFLOW_OAUTH_DEFAULT_ROLEunless required. - DataHub runtime components authenticate with
DATAHUB_MYSQL_USER/DATAHUB_MYSQL_PASSWORD; avoid remote MySQL root access for app traffic. - AKS MinIO SSO defaults to Keycloak
odprealm; if this exceeds your trust boundary, setKEYCLOAK_REALM_K8SandMINIO_KEYCLOAK_OIDC_DISCOVERY_URL_K8Sto a dedicated realm and reconcile theminioclient there.
# 1. Copy the template
cp .env.template .env
# 2. Fill in REAL values in .env (local only)
# 3. .env is gitignored and never committed# Set directly in CI/CD platform (GitHub, GitLab, etc.)
export MINIO_SECRET_KEY="actual_secret_value"# Use Docker secrets, Kubernetes secrets, or managed services:
# - AWS Secrets Manager
# - Azure Key Vault
# - HashiCorp Vault
# - GitHub Secrets (for CI/CD)AKS default in this repository:
make k8s-aks-upsyncs.enventries into Azure Key Vault and projects them back into Kubernetes secretodp-envthrough Secrets Store CSI.- Set
AKS_USE_KEY_VAULT=falseonly for temporary fallback/testing.
.env # Local credentials file
.env.* # Environment-specific configs
secrets.json # Credential JSON files
airflow_secrets.json # Airflow-specific secrets
*_secrets.* # Any file with "_secrets" in name
credentials.json # Generic credentials
config.local.* # Local config overrides
__pycache__/ # Python cache
logs/ # Airflow execution logs
frontend/node_modules/ # NPM dependencies
.env.template # SAFE: Contains only placeholder values
A pre-commit hook prevents accidental commits of secrets:
- Detects common secret patterns (password=, secret=, api_key=, etc.)
- Blocks commits containing
.envfiles - Scans for private keys and certificates
git add sensitive_file.py
git commit -m "Add new feature" # ← Hook runs here
# ✗ BLOCKED: If file contains "password=realvalue"# 1. Remove the sensitive data from the file
# 2. Use .env or environment variables instead
# 3. Re-stage: git add <file>
# 4. Try commit again# WRONG - Never do this!
db_password = "admin123"
api_key = "sk_live_jd93jdj29dj"
# CORRECT - Use environment variables
import os
db_password = os.getenv("DB_PASSWORD")
api_key = os.getenv("API_KEY")# WRONG
git add .env # ← This will be blocked by pre-commit hook
# CORRECT
git add .env.template # ← Only this is allowed# WRONG - Hardcoded in docker-compose.yml
services:
postgres:
environment:
POSTGRES_PASSWORD: admin123 # ← Visible to all
# CORRECT - Use .env file
services:
postgres:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # ← Loaded from .env# 1. Clone the repository
git clone <repo>
cd ai_trial
# 2. Copy environment template
cp .env.template .env
# 3. Fill in YOUR local values in .env
# - Get credentials from team lead or secrets manager
# - NEVER check .env into git
nano .env
# 4. Verify pre-commit hook is active
ls -la .git/hooks/pre-commit # Should exist and be executable
# 5. Test the hook (should be blocked)
echo "test_password = 'secret123'" > test.py
git add test.py
git commit -m "Test" # ← Should be blocked by hook
rm test.py # Clean up# Option 1: Remove from git history (Recommended for small repos)
git filter-branch --tree-filter 'rm -f <file_with_secret>' HEAD
# Option 2: Use BFG Repo-Cleaner (faster for large repos)
bfg --delete-files <file_with_secret>
# Option 3: If on dev branch only (safest)
git reset --soft HEAD~1 # Undo last commit
rm .env # Remove secret file
git add -A
git commit -m "Remove sensitive data"- Rotate all exposed credentials (change passwords, regenerate API keys)
- Alert team members about the exposure
- Review git history for other exposed secrets
- Notify security team if production credentials were exposed
# Install git-secrets
brew install git-secrets
# Initialize for this repo
git secrets --install
# Check committed files
git secrets --scan- GitHub: Use "Secret Scanning" (org-level feature)
- GitLab: Use "Secret Detection" in CI pipeline
- General: Use
detect-secretsortruffleHog3
ops/portal-api/requirements.txtusesPyJWT[crypto]for token verification.- Avoid reintroducing
python-jose[cryptography]unless there is a documented exception and risk acceptance. - Verification:
- Build/scan target image after dependency changes.
- Confirm no open findings for
CVE-2024-23342/ecdsain the portal API artifact dependency graph.
- Code Review: All PRs reviewed before merge
- Secrets Manager: Use external service for production
- Rotation: Rotate credentials every 90 days
- Access Control: Limit who has access to credentials
- Auditing: Log who accessed what credentials and when
If you accidentally commit a secret:
- DO NOT PANIC - It's recoverable
- Alert the security team immediately
- Follow the "Emergency Action" steps above
- Document what happened to prevent future incidents
Last Updated: February 2026
Maintained By: Security Team
Policy Version: 1.0