certauth/api/config.py
Jarian Cottingham 279a28515f fix: generate JWT secret on first boot instead of hardcoded default (#19)
Generate random 256-bit secret stored in /var/lib/certauth/.jwt_secret (mode 0600)
ENV JWT_SECRET takes precedence. Remove CHANGE_ME_JWT_SECRET default.
Add tests for secret generation and env override
2026-07-04 04:48:30 +00:00

64 lines
1.9 KiB
Python

import os
import secrets
_YK_ROOT_SERIAL = "35450561"
_YK_INT_SERIAL = "33930436"
_ROOT_CA_PATH = "/etc/ssl/ca/root/root-ca.crt"
_INT_CA_PATH = "/etc/ssl/ca/intermediate/intermediate-ca.crt"
_CA_CHAIN_PATH = "/etc/ssl/ca/ca-chain.crt"
_ISSUED_DIR = "/etc/ssl/ca/issued"
_DB_PATH = "/var/lib/certauth/certauth.db"
_JWT_SECRET_FILE = "/var/lib/certauth/.jwt_secret"
_ALGORITHM = "HS256"
_ACCESS_TOKEN_EXPIRE_MINUTES = 60
_ADMIN_USERNAME = "certauth"
_PKCS11_MODULE = "/usr/lib/aarch64-linux-gnu/opensc-pkcs11.so"
_YK_PUB_ROOT = "/tmp/yk1-root-pub.pem"
_YK_PUB_INT = "/tmp/yk2-int-pub.pem"
_TMP_DIR = "/var/lib/certauth/tmp"
def _get_jwt_secret() -> str:
"""Return JWT secret from env, persisted file, or generate new one."""
env_secret = os.environ.get("JWT_SECRET")
if env_secret:
return env_secret
if os.path.exists(_JWT_SECRET_FILE):
with open(_JWT_SECRET_FILE) as f:
return f.read().strip()
secret = secrets.token_hex(32)
os.makedirs(os.path.dirname(_JWT_SECRET_FILE), exist_ok=True)
fd = os.open(_JWT_SECRET_FILE, os.O_WRONLY | os.O_CREAT, 0o600)
with os.fdopen(fd, "w") as f:
f.write(secret)
return secret
def _get_pin(env_var: str) -> str:
"""Require YubiKey PIN from environment — no default allowed."""
pin = os.environ.get(env_var)
if not pin:
raise RuntimeError(f"Missing required environment variable: {env_var}")
return pin
YK_ROOT_SERIAL = _YK_ROOT_SERIAL
YK_INT_SERIAL = _YK_INT_SERIAL
ROOT_CA_PATH = _ROOT_CA_PATH
INT_CA_PATH = _INT_CA_PATH
CA_CHAIN_PATH = _CA_CHAIN_PATH
ISSUED_DIR = _ISSUED_DIR
DB_PATH = _DB_PATH
SECRET_KEY = _get_jwt_secret()
ALGORITHM = _ALGORITHM
ACCESS_TOKEN_EXPIRE_MINUTES = _ACCESS_TOKEN_EXPIRE_MINUTES
ADMIN_USERNAME = _ADMIN_USERNAME
PKCS11_MODULE = _PKCS11_MODULE
YK_PUB_ROOT = _YK_PUB_ROOT
YK_PUB_INT = _YK_PUB_INT
TMP_DIR = _TMP_DIR
YK_ROOT_PIN = _get_pin("YK_ROOT_PIN")
YK_INT_PIN = _get_pin("YK_INT_PIN")