diff --git a/.env.example b/.env.example index ece2a33..7d867b4 100644 --- a/.env.example +++ b/.env.example @@ -6,6 +6,7 @@ DATABASE_URL_SYNC=postgresql+psycopg://writer:writer@localhost:5432/writer APP_ENV=dev LOG_JSON=false # 凭据加密密钥(Fernet, urlsafe-base64 32B)— **必填**:API 启动即校验,缺失/非法则拒绝启动。 -# 下方为开发占位 key(可直接用于本地);生产请换新值: +# ⚠️ 下方为**不可用占位符**,必须替换:`cp .env.example .env` 后用下方命令生成真实 key 填入。 +# 切勿把真实 key 提交进版本库;任何曾经泄露过的 key 必须立即轮换(重新加密已存凭据)。 # uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" -CREDENTIAL_ENC_KEY=cnMpG6QQxJejuDLHTe_S-nq2snoKgXCqWFfsctEHB-4= +CREDENTIAL_ENC_KEY=replace-me-with-generated-fernet-key diff --git a/tests/test_env_example_no_secret.py b/tests/test_env_example_no_secret.py new file mode 100644 index 0000000..b8d92f0 --- /dev/null +++ b/tests/test_env_example_no_secret.py @@ -0,0 +1,38 @@ +"""回归守卫:`.env.example` 不得携带可用的真实密钥(CR-H8)。 + +`.env.example` 是入库模板;若其中的 `CREDENTIAL_ENC_KEY` 是一把真实可用的 +Fernet key,任何照抄 `.env.example` 的环境都会共用同一把泄露过的密钥。此测试 +确保模板里只放**不可用占位符**——照抄到 `.env` 会在启动校验(main._lifespan) +处快速失败,逼迫运维生成真实 key。 +""" + +from __future__ import annotations + +import re +from pathlib import Path + +import pytest +from cryptography.fernet import Fernet + +_ENV_EXAMPLE = Path(__file__).resolve().parent.parent / ".env.example" +_PLACEHOLDER = "replace-me-with-generated-fernet-key" + + +def _credential_enc_key() -> str: + text = _ENV_EXAMPLE.read_text(encoding="utf-8") + match = re.search(r"^CREDENTIAL_ENC_KEY=(.*)$", text, flags=re.MULTILINE) + assert match is not None, ".env.example 缺少 CREDENTIAL_ENC_KEY 行" + return match.group(1).strip() + + +def test_env_example_credential_key_is_non_functional_placeholder() -> None: + value = _credential_enc_key() + assert value, "CREDENTIAL_ENC_KEY 不能为空" + # 真实可用的 Fernet key 会构造成功——那正是要杜绝的泄露面。 + with pytest.raises(ValueError): + Fernet(value.encode()) + + +def test_env_example_credential_key_is_the_expected_placeholder() -> None: + # 更紧的锁:值必须恰是约定占位符,防止未来又塞进别的真实 key。 + assert _credential_enc_key() == _PLACEHOLDER