资讯详情

资讯详情

Ray 安全开发规范实战:gRPC 令牌认证与 runtime_env 敏感信息脱敏

Ray 安全开发规范实战gRPC 令牌认证与 runtime_env 敏感信息脱敏【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray导读本文基于 Ray 开源仓库的security开发规则系统讲解维护 Ray 安全模型必须遵守的三条核心纪律为所有新增 gRPC 端点与 RPC handler 接入 token 认证、在 C 与 Python 两侧一致地传播认证令牌、以及让回显runtime_env的 Dashboard HTTP 端点对浏览器请求执行脱敏。读完本文你将掌握 Ray 基于Authorization: Bearer token的端到端认证机制的加载、注入与校验原理理解runtime_env中env_vars为何被视为凭证载体并能依据仓库源码与测试用例落地可验证的安全实践。三条安全规则总览Ray 源码仓库中的安全规则见.claude/rules/security.md虽然只有三条但每一条都指向一个具体且可审计的实现点规则面向对象核心要求规则一所有新增 gRPC endpoint 与 RPC handler必须接入基于 token 的认证维护 Ray 的安全模型规则二C 侧与 Python 侧的调用链在新增 API 调用中传播认证 token保持端到端认证一致规则三新增 Dashboard HTTP endpoint若回显runtime_env必须对浏览器发起的请求执行脱敏redact三条规则环环相扣规则一解决服务端如何识别可信调用者规则二解决客户端如何把身份一路带过去规则三解决认证之外的敏感数据云厂商密钥、数据库口令、API token不得通过 Dashboard 泄露。规则一为新增 gRPC 端点与 RPC handler 接入 Token 认证认证的启用方式与常量定义Ray 的令牌认证通过环境变量RAY_AUTH_MODE启用python/ray/_private/authentication_test_utils.py中明确将RAY_AUTH_MODE、RAY_AUTH_TOKEN、RAY_AUTH_TOKEN_PATH列为认证相关环境变量。启用后所有内部 gRPC 调用都携带标准 HTTP 风格的Authorization元数据// src/ray/common/constants.h constexpr char kAuthTokenKey[] authorization; constexpr char kBearerPrefix[] Bearer ;即每个 RPC 请求的 gRPC metadata 中都会出现authorization: Bearer token服务端据此判断调用方身份。这也意味着新增的每个 gRPC endpoint 与 RPC handler 都必须走到同一套校验逻辑否则就会形成认证旁路auth bypass。AuthenticationToken令牌的安全包装器令牌在内存中以AuthenticationToken对象承载authentication_token.h它不是一个普通字符串而是做了三层安全加固的封装内存擦除析构、赋值、移动后都会调用SecureClear()通过ExplicitBurn将底层字节显式清零Windows 用SecureZeroMemory否则用 volatile 循环写零防止令牌残留在进程内存中被转储恒定时间比较Equals/CompareWithMetadata走ConstTimeEqual逐字节异或累积差值长度不同直接返回 false避免因比较耗时差异泄露令牌信息防时序攻击日志脱敏重载了operator任何日志打印该对象只会输出Redacted Authentication Token杜绝误打日志泄密。同时SetMetadata只在客户端侧使用将令牌写入 gRPCClientContextToAuthorizationHeaderValue返回带Bearer前缀的完整头值供注入 metadata。服务端校验AuthenticationTokenValidator服务端在 authentication_token_validator.cc 的ValidateToken中完成校验认证模式为TOKEN时非 K8s 场景直接对 metadata 做恒定时间比较expected_token-CompareWithMetadata(provided_metadata)K8s 场景ENABLE_K8S_TOKEN_AUTH则调用k8s::ValidateToken对接 Kubernetes TokenReview并对已放行的令牌做 5 分钟 TTL 缓存kCacheTTL(5)避免每个 RPC 都打到 API Server认证模式未启用时ValidateToken返回 true认证被显式关闭。因此新增 RPC handler 时只要在服务端入口复用AuthenticationTokenValidator::ValidateToken或在 gRPC server 层统一注入校验拦截器就能与既有端点保持同一安全级别。对应测试见 grpc_auth_token_tests.cc 与 authentication_token_loader_test.cc。规则二在 C 与 Python 两侧端到端传播认证 Token令牌的四个加载来源C 侧C 侧由AuthenticationTokenLoader单例authentication_token_loader.cc负责加载并缓存令牌优先级从高到低环境变量RAY_AUTH_TOKEN直接读取做空白字符裁剪环境变量RAY_AUTH_TOKEN_PATH指向任意存放令牌的文件读取文件第一行文件不可读或为空会直接报错RAY_AUTH_TOKEN_PATH is set but file cannot be opened or is empty: pathKubernetes ServiceAccount 令牌仅在ENABLE_K8S_TOKEN_AUTH开启时读取/var/run/secrets/ray.io/serviceaccount/token并解析 JWT 的exp字段计算缓存过期时间默认按kRaySATokenDefaultTTLSeconds兜底刷新缓冲见kRaySATokenExpirationBufferSeconds以配合 Kubelet 每小时自动轮换的机制默认路径~/.ray/auth_tokenWindows 下为%USERPROFILE%\.ray\auth_token。任何来源读取成功都会缓存避免每个 RPC 重复读文件若认证已启用却没有任何来源能找到令牌进程会通过RAY_CHECK崩溃并输出清晰的排错指引。客户端注入TokenAuthClientInterceptor令牌的注入并不需要每个调用方手动加 metadata而是通过 gRPC 的客户端拦截器统一完成token_auth_client_interceptor.ccvoid RayTokenAuthClientInterceptor::Intercept( grpc::experimental::InterceptorBatchMethods *methods) { if (methods-QueryInterceptionHookPoint( grpc::experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { if (token_ !token_-empty()) { auto *metadata methods-GetSendInitialMetadata(); metadata-insert( std::make_pair(kAuthTokenKey, token_-ToAuthorizationHeaderValue())); } } methods-Proceed(); }拦截器在PRE_SEND_INITIAL_METADATA钩子点把缓存的令牌写入每个出站 RPC 的初始 metadata。从源码结构看CreateTokenAuthInterceptorFactories()提供工厂方法供各 gRPC 客户端GCS、raylet、core worker、ray_syncer 等参见 node_manager.cc、ray_syncer.cc 等文件注册使用。新增 API 调用时必须复用该拦截器工厂才能保证新链路上的每个 RPC 都自动携带令牌这正是规则二传播 auth token 保持端到端一致的落点。Python 侧的对应实现Python 侧通过ray._private.authentication包与 C 层协作authentication_token_setup.pygenerate_and_save_token()生成 UUID 随机令牌并写入~/.ray/auth_token先mkdir(parentsTrue, exist_okTrue)写文件时显式 flushensure_token_if_auth_enabled()在ray.init()早期被调用检查RAY_AUTH_MODE是否开启认证若开启且无令牌则为新建本地集群自动生成并保存默认令牌若连接既有集群而本地无令牌则抛出AuthenticationError该模块明确指出令牌的加载与缓存由 C 的AuthenticationTokenLoader处理Python 侧通过from ray._raylet import AuthenticationTokenLoader直接复用同一单例保证两侧读到的令牌一致。因此Python 侧新增 API 调用时不需要自行管理令牌细节只要认证模式已启用C 拦截器会在底层 gRPC 传输中自动带上authorization头Python 侧要做的只是不破坏、不绕过这条链路例如不要把认证关闭或不要用裸 gRPC channel 绕过拦截器。跨语言一致性测试可见 python_gcs_subscriber_auth_test.cc。规则三Dashboard 端点回显 runtime_env 必须脱敏为什么env_vars是凭证载体规则原文明确指出runtime_env{env_vars: {...}}是官方文档化的、向 job / actor / task 传递凭据的方式因此这类 payload 日常携带云厂商密钥cloud keys、数据库口令与 API token。如果 Dashboard 的某个 HTTP 端点把runtime_env原样回显给浏览器任何能访问 Dashboard 的人都可能直接看到这些机密——即使认证开启也属于不必要的额外暴露面。脱敏的判定浏览器请求 开关脱敏是否生效由两个条件共同决定runtime_env_redaction.pydef should_redact_runtime_env(req: aiohttp.web.Request) - bool: return RAY_DASHBOARD_REDACT_RUNTIME_ENV and is_browser_request(req)RAY_DASHBOARD_REDACT_RUNTIME_ENV全局开关在 ray_constants.py 中定义为env_bool(RAY_DASHBOARD_REDACT_RUNTIME_ENV, True)默认开启可通过环境变量关闭is_browser_request(req)optional_utils.py从请求特征如Origin/Referer/User-Agent等判断是否来自浏览器。这保证了 CLI、脚本等非浏览器客户端拿到的仍是完整明文便于运维排障而浏览器端拿到的是脱敏后的数据。脱敏实现保留键名、掩蔽值核心函数redact_runtime_env只把env_vars字段的值整体替换为占位符键名保留让操作员仍能看到设置了哪些变量REDACTED_PLACEHOLDER redacted _SECRET_RUNTIME_ENV_FIELDS (env_vars,) def redact_runtime_env(runtime_env): redacted dict(runtime_env) for field in _SECRET_RUNTIME_ENV_FIELDS: value redacted.get(field) if isinstance(value, dict): redacted[field] {key: REDACTED_PLACEHOLDER for key in value} return redacted注意输入永不被修改同一份RuntimeEnv字典还要真正用于拉起 driver 与 worker脱敏只发生在响应序列化阶段。覆盖 runtime_env 的三种承载形态runtime_env在 State API 的各类 schema 中以三种形态出现脱敏模块分别提供处理函数形态举例处理函数普通字典RuntimeEnvState.runtime_envredact_runtime_env序列化 JSON 字符串ActorState.serialized_runtime_envredact_serialized_runtime_env解析失败则整段替换为redactedfail-closed包装结构TaskState.runtime_env_inforedact_runtime_env_info内部再走序列化脱敏列表型热路径redact_state_rows(rows)按行处理成千上万条 State API 记录只在行内确实包含上述键时才复制该行性能开销最小深层嵌套结构redact_runtime_env_deep(payload)递归遍历任意 JSON 结构适用于 Serve 配置这类runtime_env可能出现在多个层级每个 application、deployment 的ray_actor_options、controller_options的小型 payload注释中明确建议热路径优先用浅层 helpers。在 Job API 与前端中的落地job_head.py 在_job_details_to_dict中依据should_redact_runtime_env(req)决定是否对 job 的runtime_env字段执行redact_runtime_env并作用于 job 列表与详情两类端点前端侧 RuntimeEnvRedaction.ts 通过/api/v0/runtime_env_redaction获取开关状态用与后端一致的redacted占位符渲染并在弹窗中向用户解释出于安全原因环境变量值已被脱敏前端测试 CodeDialogButton.component.test.tsx 覆盖了job / Serve / actor 脱敏后的 runtime_env 到达对话框脱敏开启时展示帮助文案脱敏关闭时不展示等场景。新增 Dashboard HTTP endpoint 的检查要点如果端点会回显runtime_env无论来自 job、actor、Serve 还是 State API必须用should_redact_runtime_env(req)判定浏览器请求并走对应脱敏函数而不是直接把原始对象序列化出去。如何验证你的改动符合安全规则仓库中已有成体系的测试可供模仿与回归C 令牌加载与校验authentication_token_loader_test.cc覆盖四个加载来源与错误路径、grpc_auth_token_tests.cc覆盖端到端 gRPC 认证构建目标见 BUILD.bazelPython 侧认证辅助python/ray/_private/authentication_test_utils.py提供set_env_auth_token、set_auth_token_path、reset_auth_token_state等测试工具用于模拟不同令牌来源跨语言/订阅认证python_gcs_subscriber_auth_test.cc 验证 Python 订阅者在认证模式下的行为前端脱敏交互CodeDialogButton.component.test.tsx 验证脱敏占位符与提示文案。小结落地三条规则的开发检查清单在 Ray 仓库中新增任何网络相关代码前对照以下清单逐项自查新 gRPC endpoint / RPC handler是否复用AuthenticationTokenValidator::ValidateToken非 K8s 走恒定时间比较K8s 走 TokenReview 5 分钟缓存是否存在绕过认证的裸调用路径新 API 调用链C 与 Python客户端是否通过CreateTokenAuthInterceptorFactories注册的拦截器自动注入authorization: Bearer tokenPython 侧是否依赖ray._raylet暴露的AuthenticationTokenLoader保持两侧令牌一致新 Dashboard HTTP endpoint响应是否可能包含runtime_env若是是否按should_redact_runtime_env(req)默认开启的RAY_DASHBOARD_REDACT_RUNTIME_ENV 浏览器请求判定执行redact_runtime_env/redact_state_rows/redact_runtime_env_deep之一且保证非浏览器客户端仍可取到明文令牌与机密的生命周期令牌是否始终以AuthenticationToken承载自动擦除、恒定时间比较、日志脱敏env_vars中的值是否从不被写进日志、错误消息或未脱敏的响应体遵循这三条规则新增功能才能与 Ray 既有的安全模型保持一致做到新代码不加新风险。【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →