feat(credential): 支持从函数计算请求头静默刷新 STS 临时凭证#120
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a request-scoped STS credential “overlay” (via contextvars) intended for Function Compute (FC) deployments where rotated STS credentials are delivered on each request through x-fc-* headers, enabling silent refresh without breaking existing SDK APIs.
Changes:
- Added per-request STS overlay (
credential_context) and updatedConfigcredential getters to lazily resolve credentials with priority: explicit > request overlay (ambient only) > environment variables. - Switched Alibaba Cloud OpenAPI and TableStore client wiring to dynamic credential providers (avoiding “frozen” static credentials), and refactored httpx RAM signing auth to hold
Configand fetch live credentials per request. - Added
StsRefreshMiddlewareto inject/reset the overlay from request headers, plusAgentInvokercontext propagation for sync handlers/generators executed in threadpool.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unittests/utils/test_control_api.py | Updates expectations to validate OpenAPI clients receive a credential provider instead of static AK/SK/STS. |
| tests/unittests/utils/test_config.py | Adjusts tests for lazy credential resolution behavior in Config getters. |
| tests/unittests/test_sts_refresh.py | Adds comprehensive unit tests for overlay priority, middleware behavior, and live-signing behavior. |
| tests/unittests/conversation_service/test_session_store.py | Updates TableStore wiring tests to validate credentials_provider behavior. |
| AGENTS.md | Documents enforced conventions: provider-based credentials and request overlay refresh rules. |
| agentrun/utils/ram_signature/auth.py | Introduces shared httpx RAM auth that signs per request using live Config getters. |
| agentrun/utils/credential_providers.py | Adds an Alibaba Cloud OpenAPI credentials provider backed by Config. |
| agentrun/utils/credential_context.py | Adds contextvars-backed STS credential overlay utilities and data model. |
| agentrun/utils/control_api.py | Migrates control-plane OpenAPI client construction to provider-based credentials injection. |
| agentrun/utils/config.py | Implements lazy credential getters with request overlay support and “ambient” gating. |
| agentrun/toolset/api/mcp.py | Refactors MCP toolset RAM signing to use shared AgentrunRamAuth with live credentials. |
| agentrun/tool/api/openapi.py | Refactors OpenAPI tool RAM signing to use shared AgentrunRamAuth. |
| agentrun/tool/api/mcp.py | Refactors MCP tool RAM signing to use shared AgentrunRamAuth. |
| agentrun/server/sts_middleware.py | Adds middleware to extract FC STS headers and inject/reset request overlay. |
| agentrun/server/server.py | Installs STS refresh middleware into the server app. |
| agentrun/server/invoker.py | Propagates contextvars into executor threads for sync handlers and sync generators. |
| agentrun/memory_collection/memory_conversation.py | Updates TableStore async client creation to use dynamic credentials_provider. |
| agentrun/conversation_service/utils.py | Adds TableStore CredentialsProvider adapter + updates build_ots_clients to use it. |
| agentrun/conversation_service/session_store.py | Updates session store initialization to pass Config into OTS client builders (provider-based). |
| agentrun/conversation_service/__session_store_async_template.py | Mirrors session store changes in the codegen template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+31
to
+33
| from starlette.middleware.base import BaseHTTPMiddleware | ||
| from starlette.requests import Request | ||
| from starlette.responses import Response |
Comment on lines
+127
to
+130
| # 注入 STS 刷新中间件:从每次请求的 FC 头解析最新 STS 临时凭证,写入 | ||
| # 请求级 overlay,使本次请求内所有 Config/client 静默使用最新凭证。 | ||
| # 无条件启用:未携带相关头时(本地/非 FC)中间件不产生任何副作用。 | ||
| self.app.add_middleware(StsRefreshMiddleware) |
5e11488 to
ecf2278
Compare
部署在函数计算(FC)时,最新轮转的 STS 通过每次请求的 x-fc-* 头下发。新增 请求级凭证 overlay(contextvars),让所有 Config/client 在凭证过期后静默使用 最新 STS,对外 SDK API 零破坏。 - Config 凭证 getter 改为懒解析:显式 > 请求级 overlay(仅 ambient)> 环境变量 - 控制面 OpenAPI client 改用 credential provider、TableStore 改用 credentials_provider、MCP/OpenAPI httpx 签名器持有 Config 实时取证(去静态凭证) - 新增 StsRefreshMiddleware:解析 FC 头注入请求级 overlay;默认仅 FC 启用、 要求完整三元组,防止头注入与凭证混用 - AgentInvoker 同步 handler/生成器路径 copy_context 传播 overlay - AGENTS.md 增加"一律用 credential provider、禁止静态凭证"强制约定;新增单测 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
knowledgebase 分支覆盖率长期卡在 89.16% < 90%(main 既有问题,与本 STS 变更 无关),缺口集中在 BailianDataAPI._normalize_search_filters —— 该静态方法整段 未被任何测试覆盖。补 4 个单测覆盖 None / 空列表 / list+dict JSON 序列化 / 多 filter item 的全部分支,目录分支覆盖率 89.16% -> 91.96%,过线。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
原逻辑仅比较 HEAD^..HEAD(最近一次提交),多 commit 分支会漏检早先提交的 改动——例如分支最后一次提交只动 tests/ 时,会误判 agentrun 无变更而跳过 构建。改为 git merge-base(origin/main, HEAD) 取整个分支引入的全部改动; 直接 push 到 main 等与 base 无分叉的场景回退到 HEAD^..HEAD。 (仓库默认分支为 main,无 master 分支,故对齐 main。) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
…rver 场景手动注入 STS StsRefreshMiddleware 只在 agentrun server 内生效;用户用自有 Web 框架(FastAPI/ Flask/Django)或非 HTTP 任务时无法被拦截。新增两个公开上下文管理器(从 agentrun 顶层导出),让用户手动注入最新 STS: - use_sts_credentials(ak, sk, sts):显式传值 - use_sts_from_headers(headers):从任意请求头映射解析(同 x-fc-* 约定,大小写不敏感) 二者写入同一请求级 overlay,刷新逻辑与中间件完全一致(含三元组齐全校验、自动复位)。 中间件本身重构为直接复用 use_sts_from_headers —— 单一真相,server 内外同一套逻辑。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
之前默认仅在 FC 环境(FC_REGION 存在)才启用。按需求改为**默认启用**,不再 特殊判断 FC 环境;仅在环境变量 AGENTRUN_STS_REFRESH_ENABLED 设为假值 (0/false/no/off)或构造参数 enabled=False 时关闭。中间件在 x-fc-* 头不齐全 时本就透传、无副作用,故默认开是安全的。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
3a088f7 to
037b250
Compare
按 PR review 建议,将 StsRefreshMiddleware 从 BaseHTTPMiddleware 改为纯 ASGI 中间件(__call__ 包裹 await self.app(scope, receive, send),Headers(scope=scope) 取头,with use_sts_from_headers 在 app 整体结束后复位)。 收益:overlay 与请求同任务、同生命周期,对 endpoint / StreamingResponse body / run_in_threadpool 同步处理器 / **响应后的 background task** 全程可见;避免 BaseHTTPMiddleware 的额外 task/stream 包装及其流式/断连/异常传播的已知坑。 逻辑不变(复用 use_sts_from_headers)。新增 background-task 回归测试。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: OhYee <oyohyee@oyohyee.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
部署在函数计算(FC)时,最新轮转的 STS 通过每次请求的 x-fc-* 头下发。新增
请求级凭证 overlay(contextvars),让所有 Config/client 在凭证过期后静默使用 最新 STS,对外 SDK API 零破坏。
Fix bugs
Bug detail
Pull request tasks
Update docs
Reason for update
Pull request tasks
Add contributor
Contributed content
Content detail
Others
Reason for update