chore: 删除退役的旧 JWT 密钥,同步过时引用并记录登录接口决策

1. 删除 config/jwt/jwt-private.pem 与 jwt-public.pem(旧密钥,配置已不再指向)。
   删除后复跑全量门禁以确认没有残留依赖:ruff 通过、unit+contract 447 passed、
   acceptance_check --production 7 PASS、demo_agent_e2e 9/9 PASS。
2. 修掉 4 处引用旧密钥路径的地方(它们会在删除密钥后直接失败或误导接入方):
   - tests/unit/core/test_security.py 的三处硬编码路径改为单一常量 DEV_KEY_DIR,
     否则删除旧密钥后该测试会因读不到文件而失败;
   - tools/demo_agent_e2e.py 的 docstring 前置条件;
   - docs/09 的配置示例;docs/19 的手工自签说明(改为指向配置项与
     tools/generate_jwt_keys.py)。
3. docs/21 记录旧密钥已删除,并注明删除后已复跑验证无残留引用。
4. docs/19 未解决项新增第 5 条:无登录接口属于**有意识的推迟**(等业务 Agent 开发阶段
   结束后再补),写明补的时候只需动签发侧、验签侧与身份解析侧都不需要改,
   并附上当前私钥边界的实测结论(无法伪造不存在的用户、无法使用已禁用账号)。
This commit is contained in:
2026-09-10 18:18:00 +08:00
parent c32d3dbd06
commit 2c5ef35d18
5 changed files with 22 additions and 8 deletions
+7 -3
View File
@@ -8,6 +8,10 @@ from app.core.config import Settings
from app.core.errors import UnauthorizedAgentError
from app.core.security import JwtAuthenticator
# 开发专用密钥目录(tools/generate_jwt_keys.py 生成)。本测试需要真实密钥完成签发与验签,
# 所以路径只在这里定义一次:换密钥目录时改这一处,避免多处硬编码各自漂移。
DEV_KEY_DIR = Path("config/jwt/dev")
def _settings() -> Settings:
return Settings(
@@ -18,13 +22,13 @@ def _settings() -> Settings:
redis_url="redis://localhost",
milvus_uri="http://localhost:19530",
neo4j_uri="bolt://localhost:7687",
jwt_public_key_path="config/jwt/jwt-public.pem",
jwt_public_key_path=str(DEV_KEY_DIR / "jwt-public.pem"),
)
def _token(subject: str = "1") -> str:
now = datetime.now(UTC)
private_key = Path("config/jwt/jwt-private.pem").read_text(encoding="utf-8")
private_key = (DEV_KEY_DIR / "jwt-private.pem").read_text(encoding="utf-8")
return jwt.encode(
{"sub": subject, "iss": "jr-auth", "aud": "jr-agent-platform", "iat": now,
"nbf": now, "exp": now + timedelta(minutes=5), "jti": "jti-1"},
@@ -65,7 +69,7 @@ def test_signed_invalid_subject_returns_401_before_identity_query(monkeypatch):
def test_authenticate_rejects_expired_token() -> None:
with pytest.raises(UnauthorizedAgentError):
now = datetime.now(UTC)
private_key = Path("config/jwt/jwt-private.pem").read_text(encoding="utf-8")
private_key = (DEV_KEY_DIR / "jwt-private.pem").read_text(encoding="utf-8")
token = jwt.encode(
{"sub": "user-1", "iss": "jr-auth", "aud": "jr-agent-platform",
"nbf": now - timedelta(minutes=2), "exp": now - timedelta(minutes=1), "jti": "jti-2"},