Skip to content

feat(workshop_auth): PoC C0 — cookie-path JWT auth backend + tenant i… - #731

Closed
xiejava1018 wants to merge 4 commits into
AgentFlocks:devfrom
xiejava1018:workshop/poc-c0
Closed

feat(workshop_auth): PoC C0 — cookie-path JWT auth backend + tenant i…#731
xiejava1018 wants to merge 4 commits into
AgentFlocks:devfrom
xiejava1018:workshop/poc-c0

Conversation

@xiejava1018

Copy link
Copy Markdown

…solation tests

  • flocks/workshop_auth/: TeamJWTAuthBackend (full AuthBackend Protocol, HS256 PoC) mounted via session-cookie branch of _apply_auth_for_request
  • tests/poc_workshop_auth.py: 9/9 — cookie JWT -> AuthUser(tenant_ids), negative cases
  • tests/poc_tenant_isolation.py: 10/10 — contracts/access driver-native tenant filtering
  • Zero core-file changes (design: route-b-enhanced-tenant-isolation.md v1.1)

xiejava1018 and others added 3 commits September 2, 2026 20:15
…solation tests

- flocks/workshop_auth/: TeamJWTAuthBackend (full AuthBackend Protocol, HS256 PoC)
  mounted via session-cookie branch of _apply_auth_for_request
- tests/poc_workshop_auth.py: 9/9 — cookie JWT -> AuthUser(tenant_ids), negative cases
- tests/poc_tenant_isolation.py: 10/10 — contracts/access driver-native tenant filtering
- Zero core-file changes (design: route-b-enhanced-tenant-isolation.md v1.1)
…S + env-gated mount

落地《route-b-enhanced-tenant-isolation.md》方案 §12 登记的对 Flocks 改动:

- 新增 flocks/workshop_auth/adapter.py — register_workshop_adapters() 注入
  Workshop permissions/tenant_ids 到 request.state.extension_context,
  严格遵循 AuthContextAdapter 签名 (HTTPConnection, AuthUser|None)
  → Awaitable[Mapping[str,Any]|None].
- 新增 flocks/workshop_auth/client.py — JWKS 拉取 + TTL 缓存
  (WORKSHOP_JWKS_TTL 默认 300s).
- backend.py 升级 — 支持 WORKSHOP_JWT_ALG=RS256/ES256 + WORKSHOP_JWKS_URL,
  默认 HS256 保持 PoC 可独立复现;_decode 改 async.
- __init__.py 新增 maybe_register_on_env() — 让生产侧零侵入挂载.
- 修改 flocks/server/__init__.py(方案 §12 AgentFlocks#5)— env-gated:
  FLOCKS_AUTH=workshop_jwt 时自动注册;失败 try/except 兜底,不阻塞原生部署.
- 新增 tests/test_workshop_auth_c1.py — 覆盖 mount/adapter/HS256/RS256/JWKS.

方案 §6.2 + §10-C2 pre-work 落地。FlocksAdapter HTTP/SSE 实现留 C2 主体。

Refs: docs/design/route-b-enhanced-tenant-isolation.md
在重建的 .venv-poc(py3.12 + 10 轻依赖)上真跑结果:
- test_workshop_auth_c1.py 11/11 PASS
- poc_workshop_auth.py 9/9 PASS (原 C0 认证链回归)
- poc_tenant_isolation.py 10/10 PASS (原 C0 隔离链回归)

修复:
1. isinstance(AuthService.get_backend(), TeamJWTAuthBackend) 恒 False —
   get_backend() 返回类对象本身(register_backend 存 class),
   isinstance(类, 类) 语义错误; 改为身份比较(2 处)。
   原 PoC 用 __name__ 比较正是规避此点。
2. test_backend_rs256_requires_jwks_url: _decode 已是 async(C2 pre-work),
   同步调用产生 coroutine never awaited 且不抛错; 改 asyncio.run 驱动。

验证覆盖: env-gated mount / adapter 注入 / HS256 正反例 /
RS256 缺 JWKS 守卫 / JWKS 缓存 miss。
@stephamie7
stephamie7 changed the base branch from main to dev September 3, 2026 01:20
uvicorn 全局异常处理器把 pyjwt 异常包成 500 '鉴权处理异常', 破坏客户端
重试语义。框架契约: get_user_by_session_id → None ⇒ 401 '登录已过期'。

真实服务联调验证(FLOCKS_AUTH=workshop_jwt, uvicorn flocks.server.app:app):
- 伪造 Cookie JWT → 401 登录已过期(修复前 500)
- 合法 team JWT → GET/POST /api/session 200(真实会话 ses_* 创建成功)
- Bearer-only → 401(设计事实: 不走 backend, 印证上游 PR AgentFlocks#732 动机)
- env-gated 挂载在真实启动链路生效(TeamJWTAuthBackend registered)

单测同步: forged/expired 两用例改断言 None; 30/30 全绿。
另修复测试 docstring 全角引号导致的语法错误。
@xiejava1018

Copy link
Copy Markdown
Author

关闭此 PR:误提到上游 AgentFlocks/flocks。已改在 fork 仓 xiejava1018/flocks 内部评审合并(workshop_auth 插件属于 Workshop 私有集成, 不适合直接进上游)。

@xiejava1018 xiejava1018 closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant