TFRS 跨语言共享凭证工具包(Python):PAT/client_credentials → 短 JWT 换发 + 缓存/刷新 + 纯 RS256 验签
Project description
tfrs-auth (Python)
TFRS AccessToken 客户端工具包:把「PAT / client_credentials → 短 RS256 JWT 换发
(RFC 8693)+ 缓存/刷新」与「Claims/scope 契约 + 纯验签」抽成可复用包,避免每个
MCP 工具 / SDK 重复实现 token 获取与生命周期管理。
SoT = TFRSManager Contract Registry。本包
contract.py为镜像,变更先改 Manager。 强制执行层(验签中间件/Socket.IO/ESO/默认拒绝 CI)不在本包,留 TFRobotServer。
安装
# 从 PyPI(推荐)
uv add tfrs-auth # 核心:契约 + 纯验签
uv add "tfrs-auth[httpx]" # 含客户端 token source / JWKS live 拉取
# 或:pip install "tfrs-auth[httpx]"
# 或从 git + tag(未发布版本)
uv add "tfrs-auth[httpx] @ git+https://cnb.cool/turingfocus/foundation/tfrs-foundation-py@<tag>#subdirectory=packages/tfrs-auth"
- 核心依赖:
pyjwt[crypto](契约 + 纯验签)。 - 可选 extra
httpx:客户端 token source / JWKS live 拉取。 - 许可证:MIT。
用法
客户端 token source(client_credentials,S5 A2A 主叫端)
from tfrs_auth import AsyncCachingTokenSource, ClientCredentials
cred = ClientCredentials.for_robot(
client_id=machine_client_id, # 机器人自身 Account.ID
client_secret=machine_client_secret, # tfp_ 明文(machineClientSecret)
callee_robot_id=callee_id, # → aud=robot:<calleeId>
scope=["a2a:invoke"],
)
async with AsyncCachingTokenSource(
cred, token_url="https://<user-host>/api/v1/oauth/token"
) as source:
token = await source.token() # 缓存 + 临期自动刷新 + 退避
headers = {"Authorization": f"Bearer {token.access_token}"}
同步场景用 CachingTokenSource(API 对称)。
纯验签(资源服务器侧,零网络)
from tfrs_auth import JwtVerifier
verifier = JwtVerifier.from_jwks(jwks_dict, issuer="https://<user-host>", audience="robot:42")
claims = verifier.verify(access_token) # 失败抛 TokenVerificationError
assert claims.has_scope("a2a:invoke")
live 拉取 JWKS:JwtVerifier.from_url("https://<user-host>/.well-known/jwks.json", ...)。
⚠️ 资源服务器务必传
issuer与audience:二者仅在提供时才校验。不传audience会放行签给任意机器人的 token,丧失aud=robot:<id>受众隔离(issuer之于颁发者 隔离同理)。from_url的未知-kid 刷新已内置限速(min_refresh_interval,默认 10s), 避免被构造的随机-kid token 放大成对 JWKS 端点的 DoS。异常约定:验签失败抛
TokenVerificationError;from_url模式下 JWKS 拉取的网络失败抛TransportError。消费方应except (TokenVerificationError, TransportError)同时兜住。
模块
| 模块 | 内容 |
|---|---|
contract |
Scope(8 active + 2 reserved) · Claims · GrantType/SubjectTokenType URN · OAuthErrorCode · JWKS/kid 形状 |
errors |
异常树(InvalidClientError(401) / InvalidTargetError / TemporarilyUnavailableError(503) …)+ from_oauth_error |
client |
Token · TokenSource/AsyncTokenSource · CachingTokenSource / AsyncCachingTokenSource(single-flight + 退避) |
credentials |
ClientCredentials(✅)· PatCredential / UserJwtCredential(骨架) |
verify |
JwtVerifier(RS256 + JWKS) |
transport |
BearerAuth(httpx auth,骨架) |
边界与状态
- 已实现:
contract/errors/client(sync+async caching) /credentials.ClientCredentials/verify。 - 骨架(首批 CNB Issue):
credentials.PatCredential/credentials.UserJwtCredential/transport.BearerAuth。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tfrs_auth-0.1.0.tar.gz.
File metadata
- Download URL: tfrs_auth-0.1.0.tar.gz
- Upload date:
- Size: 24.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d58880a81476aa4754e99892b8174bab77adb79d8d4b0077c3646e8b4a7af4d7
|
|
| MD5 |
31582dd7441a001846f8d5f62ccfc4f4
|
|
| BLAKE2b-256 |
961e45db3c204a931f00f7413ecd136e09c7c955f3805138e4662fbf1c563ce5
|
File details
Details for the file tfrs_auth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tfrs_auth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae5361d58d2c73ad597f40c813f18522e84f4e74d13669a6f59f9b1012ab8af1
|
|
| MD5 |
1538a7e1d91728c49de22eba74c54fa2
|
|
| BLAKE2b-256 |
4583bedb01c5a2c7f12e3a134e7eea0da0a3cd1c89f9fa219d2ab9f74a1d30e1
|