资讯动态

Feast Kubernetes 认证与 RBAC 授权配置完全指南:基于 Token Access Review 的组/命名空间/角色鉴权

发布时间:2026/9/17 7:52:23 来源:尧图企业网站定制
Feast Kubernetes 认证与 RBAC 授权配置完全指南基于 Token Access Review 的组/命名空间/角色鉴权【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast导读本文基于 Feast 官方文档 docs/reference/auth/kubernetes_auth_setup.md 展开系统讲解 Feast 如何从 Kubernetes 认证令牌Token中提取用户组Groups、命名空间Namespaces与角色Roles并借助Permission框架实现细粒度访问控制。你将掌握Feast Operator 默认的认证默认开启行为、如何在FeatureStoreCR 中切换认证模式、如何设计角色/组/命名空间四类授权策略以及如何在 SDK、CLI、REST/gRPC 中注入 Kubernetes 用户令牌。读完即可在自己的集群环境中完成从认证到授权的完整落地。一、整体架构Feast 如何从 Kubernetes Token 提取身份信息Feast 的 Kubernetes 认证建立在客户端持有有效 Kubernetes Bearer Token服务端负责验证并提取身份的模型之上。服务端通过Token Access Review API与RBAC 资源完成三方面信息提取Groups用户组与 User/ServiceAccount 直接关联的组以及从关联命名空间中推导出的组Namespaces命名空间与 User/ServiceAccount 关联的 Kubernetes 命名空间Roles角色与 User/ServiceAccount 关联的 Kubernetes 角色。这套逻辑的核心实现位于 sdk/python/feast/permissions/auth/kubernetes_token_parser.py 中的KubernetesTokenParser类。从源码结构看它的工作流程分为两条路径ServiceAccount 路径尝试把令牌当作 JWT 解码jwt.decode且不校验签名从sub声明中解析出system:serviceaccount:NAMESPACE:SA_NAME格式的服务账号身份再通过查询当前命名空间下的RoleBinding得到其绑定的Role列表普通用户路径当 JWT 解码失败说明是用户令牌回退到TokenReview结果中的username并通过全局RoleBinding与ClusterRoleBinding同时解析直接绑定给用户和绑定给用户所属组的角色。在提取组与命名空间时KubernetesTokenParser调用AuthenticationV1Api().create_token_review(...)发起 Token Access Review从响应status.user.groups中取组命名空间则分两种情况推导对 ServiceAccount从system:serviceaccount:namespace:name形式的用户名中截取命名空间并进一步查询该命名空间下RoleBinding中绑定到Group的组名一并并入 groups对普通用户通过扫描dashboard-permissions-*带opendatahub.io/dashboardtrue标签与admin类型的RoleBinding推导出用户被授予数据科学项目Data Science Project访问权的命名空间集合。需要强调Feast 本身不负责颁发令牌参见 docs/getting-started/components/authz_manager.md 中的说明客户端负责管理认证令牌并将其随请求传入服务端只负责校验令牌并提取用户详情。二、Operator 默认行为认证默认开启授权逐步收紧当使用 Feast Operator 部署时Kubernetes 认证默认开启。即使在FeatureStoreCR 中没有显式配置authzOperator 也会自动为所有部署的服务应用kubernetes认证。这意味着所有发往 Feast 服务的 HTTP/gRPC 请求必须携带合法的 Kubernetes Bearer Token放在Authorization请求头中服务端通过 Kubernetes Token Access Review API 校验令牌并提取用户名、组、命名空间与角色如果没有任何Permission对象被定义通过认证的用户将获得全部访问权限同时在日志中输出一条警告提示管理员尽快定义细粒度权限未认证的请求会收到401 Unauthorized响应。该设计遵循Authenticated by Default, Authorized Gradually默认认证、逐步授权的安全模型确保 Feast 部署不会在未认证状态下被意外暴露同时允许团队渐进式引入细粒度 RBAC。2.1 关闭认证noAuth: true如果需要在本地开发或测试环境中以无认证方式运行可以在FeatureStoreCR 中显式设置noAuth: trueapiVersion: feast.dev/v1 kind: FeatureStore metadata: name: my-feature-store spec: feastProject: my_project authz: noAuth: true⚠️警告noAuth: true会关闭所有认证与授权校验所有端点将变为公开可访问。仅限本地开发或测试环境使用生产环境请使用kubernetes或oidc认证。2.2 认证模式选择速查表spec.authz设置行为(未指定)Kubernetes 认证开启默认kubernetes: {}Kubernetes 认证开启显式声明oidc: { ... }OIDC 认证开启noAuth: true关闭所有认证需要说明的是Feast 还内置了基于 OIDC 的认证OidcAuthConfig见 sdk/python/feast/permissions/auth_model.py当客户端auth_config的type为oidc时走 OIDC 客户端管理器获取令牌本文聚焦 Kubernetes 认证路径。三、Kubernetes RBAC 环境与 Feast 权限的对应关系要让 Kubernetes RBAC 环境与 Feast 的 RBAC 配置对齐需要遵循以下规则。3.1 基于角色的认证设置Role-basedFeastPermission实例中定义的角色名必须与 Kubernetes RBACRole的名称一一对应Kubernetes RBACRole必须与 Feast 服务位于同一命名空间客户端应用可以运行在不同命名空间使用自己的专用ServiceAccount将客户端ServiceAccount关联到该 RBACRole的RoleBinding必须定义在 Feast 服务所在的命名空间中。从源码实现看这一点与KubernetesTokenParser.get_roles()的行为完全吻合它只查询list_namespaced_role_binding(current_namespace)Feast 服务所在命名空间匹配subject.kind ServiceAccount、subject.name service_account_name且subject.namespace service_account_namespace的绑定取其role_ref.name作为用户角色。3.2 基于组与命名空间的认证设置Group/Namespace-basedFeastPermission实例中定义的组名与命名空间名必须与 Kubernetes 中实际的Group与Namespace名称对应用户或服务账号必须位于 FeastPermission实例定义的组或命名空间中客户端应用可以运行在不同命名空间使用自己的专用ServiceAccount或用户Feast 服务根据Permission实例中定义的组与命名空间关联关系来授予访问权限。四、策略类型Policy Types四类鉴权策略详解Feast 的权限框架通过策略Policy类描述谁能做什么。四类策略的实现均位于 sdk/python/feast/permissions/policy.py全部继承自抽象基类Policy核心方法是validate_user(user) - (bool, str)返回是否匹配以及不匹配时的原因说明。4.1 RoleBasedPolicy基于角色按用户角色成员关系授权用户至少拥有配置角色中的一个即可通过。from feast.permissions.policy import RoleBasedPolicy policy RoleBasedPolicy(roles[data-team, ml-engineers])实现上validate_user调用user.has_matching_role(self.roles)若用户命中了角色绑定含直接绑定与组绑定见get_user_roles()即可通过校验。4.2 GroupBasedPolicy基于用户组按用户组归属授权用户至少加入其中一个组即可通过。from feast.permissions.policy import GroupBasedPolicy policy GroupBasedPolicy(groups[data-team, ml-engineers])4.3 NamespaceBasedPolicy基于命名空间按用户关联的命名空间授权用户至少位于其中一个被允许的命名空间即可通过。from feast.permissions.policy import NamespaceBasedPolicy policy NamespaceBasedPolicy(namespaces[production, staging])4.4 CombinedGroupNamespacePolicy组与命名空间组合当用户被加入允许的组 OR 允许的命名空间二者满足其一时授权通过。from feast.permissions.policy import CombinedGroupNamespacePolicy policy CombinedGroupNamespacePolicy( groups[data-team], namespaces[production] )源码中该策略的判定逻辑为has_matching_group(groups) or has_matching_namespace(namespaces)不满足时返回原因 User must be in at least one of the permitted groups or namespaces。此外sdk/python/feast/permissions/policy.py 中还提供了一个AllowAll策略实例任何用户都能通过校验作为未定义权限时的默认兜底行为。五、服务端与客户端配置5.1 服务端配置使用 Kubernetes 认证时服务端会自动提取组、命名空间与角色无需在既有 Kubernetes 认证配置之外追加任何额外配置。认证模式的切换kubernetes / oidc / no_auth通过服务端feature_store.yaml中的auth段完成AuthConfig基类定义了type: Literal[oidc, kubernetes, no_auth] no_auth字段。5.2 客户端配置对于非 ServiceAccount 的外部用户需要在客户端配置中提供用户令牌。令牌的提供方式详见下一节也可直接阅读官方文档 docs/reference/auth/user_token_provisioning.md。六、用户令牌的多种提供方式客户端视角Feast 客户端支持从 CLI、API 与 SDK 三种途径注入 Kubernetes 用户令牌。6.1 SDK 配置Python方法一在FeatureStore中直接配置from feast import FeatureStore from feast.permissions.auth_model import KubernetesAuthConfig # Create auth config with user token auth_config KubernetesAuthConfig( typekubernetes, user_tokenyour-kubernetes-user-token-here ) # Initialize FeatureStore with auth config fs FeatureStore( repo_pathpath/to/feature_repo, auth_configauth_config )方法二环境变量import os from feast import FeatureStore # Set environment variable os.environ[LOCAL_K8S_TOKEN] your-kubernetes-user-token-here # FeatureStore will automatically use the token fs FeatureStore(path/to/feature_repo)方法三配置文件在feature_store.yaml中声明auth段project: my-project auth: type: kubernetes user_token: your-kubernetes-user-token-here随后FeatureStore会自动从 YAML 读取认证配置from feast import FeatureStore # FeatureStore will read auth config from feature_store.yaml fs FeatureStore(path/to/feature_repo)注意KubernetesAuthConfig类通过ConfigDict(arbitrary_types_allowedTrue, extraallow)允许额外字段见 sdk/python/feast/permissions/auth_model.py因此user_token字段从 YAML 加载时会被正确识别。6.2 CLI 使用方法一环境变量# Set the token as environment variable export LOCAL_K8S_TOKENyour-kubernetes-user-token-here # Use Feast CLI commands feast apply feast materialize feast get-online-features \ --features feature1,feature2 \ --entity-rows {entity_id: 123}方法二配置文件在feature_store.yaml中配置auth段同上然后直接执行 CLI 命令即可feast apply feast materialize feast get-online-features \ --features feature1,feature2 \ --entity-rows {entity_id: 123}6.3 API 使用REST/gRPCREST API —— 方法一Authorization 请求头import requests # For REST API headers { Authorization: Bearer your-kubernetes-user-token-here, Content-Type: application/json } # Get features response requests.get( http://feast-server/features, headersheaders ) # Get online features response requests.post( http://feast-server/get-online-features, headersheaders, json{ features: [feature1, feature2], entity_rows: [{entity_id: 123}] } )REST API —— 方法二requests Sessionimport requests from requests.auth import HTTPBearerAuth # Create session with auth session requests.Session() session.auth HTTPBearerAuth(your-kubernetes-user-token-here) # Make requests response session.get(http://feast-server/features)gRPC API —— 方法一gRPC Metadataimport grpc from feast.protos.feast.serving.ServingService_pb2_grpc import ServingServiceStub from feast.protos.feast.serving.ServingService_pb2 import GetOnlineFeaturesRequest # Create gRPC channel channel grpc.insecure_channel(feast-server:6565) stub ServingServiceStub(channel) # Create metadata with auth token metadata [(authorization, Bearer your-kubernetes-user-token-here)] # Create request request GetOnlineFeaturesRequest( features[feature1, feature2], entity_rows[{entity_id: 123}] ) # Make gRPC call response stub.GetOnlineFeatures(request, metadatametadata)gRPC API —— 方法二gRPC Interceptor统一注入import grpc from feast.protos.feast.serving.ServingService_pb2_grpc import ServingServiceStub class AuthInterceptor(grpc.UnaryUnaryClientInterceptor): def __init__(self, token): self.token token def intercept_unary_unary(self, continuation, client_call_details, request): # Add auth metadata metadata list(client_call_details.metadata or []) metadata.append((authorization, fBearer {self.token})) # Update call details client_call_details client_call_details._replace(metadatametadata) return continuation(client_call_details, request) # Create channel with interceptor channel grpc.insecure_channel(feast-server:6565) interceptor AuthInterceptor(your-kubernetes-user-token-here) channel grpc.intercept_channel(channel, interceptor) # Use the channel stub ServingServiceStub(channel)6.4 编程式 SDK 用法从 Kubernetes 配置获取令牌对于运行在集群内、需要动态获取令牌的客户端可以结合 Kubernetes Python SDK 从 Secret 等安全存储读取令牌from feast import FeatureStore from feast.permissions.auth_model import KubernetesAuthConfig from kubernetes import client, config # Load kubeconfig and get token config.load_kube_config() v1 client.CoreV1Api() # Get token from Kubernetes API or secure storage def get_token_from_k8s(): # Example: Get token from secret secret v1.read_namespaced_secret( nameuser-token, namespacedefault ) return secret.data[token].decode(utf-8) user_token get_token_from_k8s() auth_config KubernetesAuthConfig( typekubernetes, user_tokenuser_token ) fs FeatureStore( repo_pathpath/to/feature_repo, auth_configauth_config )6.5 令牌解析优先级客户端获取令牌的完整顺序由KubernetesAuthClientManager.get_token()决定见 sdk/python/feast/permissions/client/kubernetes_auth_client_manager.py与官方文档一致服务间通信INTRA_COMMUNICATION_BASE64环境变量服务到服务调用此时会生成一个alg: none的占位 JWT直接配置KubernetesAuthConfig中的user_token字段或feature_store.yaml中的auth.user_token服务账号令牌文件/var/run/secrets/kubernetes.io/serviceaccount/token适用于 Pod 内运行环境变量LOCAL_K8S_TOKEN。同时客户端管理器工厂AuthenticationClientManagerFactory见 sdk/python/feast/permissions/client/auth_client_manager.py会依据auth_config.typekubernetes/oidc选择对应的客户端管理器若检测到INTRA_COMMUNICATION_BASE64则优先走内部通信专用管理器。七、完整实战权限定义与下发7.1 基础权限示例在permissions.py中组合使用全部四类策略定义权限from feast.feast_object import ALL_RESOURCE_TYPES from feast.permissions.action import READ, AuthzedAction, ALL_ACTIONS from feast.permissions.permission import Permission from feast.permissions.policy import ( RoleBasedPolicy, GroupBasedPolicy, NamespaceBasedPolicy, CombinedGroupNamespacePolicy ) # Role-based permission role_perm Permission( namerole_permission, typesALL_RESOURCE_TYPES, policyRoleBasedPolicy(roles[reader-role]), actions[AuthzedAction.DESCRIBE] READ ) # Group-based permission (new) data_team_perm Permission( namedata_team_permission, typesALL_RESOURCE_TYPES, policyGroupBasedPolicy(groups[data-team, ml-engineers]), actions[AuthzedAction.DESCRIBE] READ ) # Namespace-based permission (new) prod_perm Permission( nameproduction_permission, typesALL_RESOURCE_TYPES, policyNamespaceBasedPolicy(namespaces[production]), actions[AuthzedAction.DESCRIBE] READ ) # Combined permission (new) dev_staging_perm Permission( namedev_staging_permission, typesALL_RESOURCE_TYPES, policyCombinedGroupNamespacePolicy( groups[dev-team], namespaces[staging] ), actionsALL_ACTIONS )补充说明代码中用到的动作枚举定义于 sdk/python/feast/permissions/action.py动作含义CREATE创建实例DESCRIBE访问实例状态UPDATE更新实例状态DELETE删除实例READ_ONLINE/READ_OFFLINE仅读取在线/离线存储WRITE_ONLINE/WRITE_OFFLINE仅写入在线/离线存储READ [READ_OFFLINE, READ_ONLINE]WRITE [WRITE_OFFLINE, WRITE_ONLINE]CRUD [CREATE, DESCRIBE, UPDATE, DELETE]ALL_ACTIONS覆盖全部 8 个动作。7.2 下发权限在服务端或在具备权限的客户端通过 CLI/API/SDK 执行feast applyfeast apply会将permissions.py中定义的Permission对象写入注册表之后服务端便会对每个请求按资源类型 动作 策略进行鉴权。未定义任何Permission时认证通过的用户默认拥有全部权限但服务端会记录一条 No permissions defined 警告日志。八、故障排查Troubleshooting常见问题升级后出现 401 UnauthorizedFeast Operator 现在默认启用 Kubernetes 认证如果既有FeatureStoreCR 未指定authz升级会自动开启认证。快速修复仅测试用在FeatureStoreCR 中追加authz.noAuth: true以恢复此前的无认证行为。推荐做法更新客户端应用让所有请求携带有效的 Kubernetes Bearer Token。Token Access Review 失败检查 Feast 服务是否具备所需的 RBAC 权限其运行 Deployment 必须被授予查询RoleBinding、执行 TokenReview 等资源的权限见 sdk/python/feast/permissions/auth/kubernetes_token_parser.py 中get_roles的注释说明确认令牌有效且未过期以 debug 模式查看服务端日志中的详细错误信息。未提取到组/命名空间确认令牌包含预期的 claims检查用户是否已在 Kubernetes/ODH/RHOAI 中正确配置普通用户的命名空间推导依赖dashboard-permissions-*与admin类型的RoleBinding。权限被拒绝Permission Denied确认用户已被加入所需组/命名空间或已分配所需角色检查策略配置是否正确查看权限评估日志。日志中出现 No permissions defined 警告这是 Kubernetes 认证开启但尚未应用任何Permission对象时的预期行为默认情况下认证用户拥有全部访问权限如需强制细粒度授权请通过permissions.pyfeast apply定义权限。客户端常见错误错误信息解决方案Missing authentication token通过上述任一受支持方式提供令牌配置项、文件或环境变量Invalid or expired access token确认令牌有效且未过期User is not added into the permitted groups / Namespaces检查用户是否具备所需组/命名空间访问权限九、迁移指南从基于角色到基于组/命名空间如果团队希望从单一的角色模型迁移到更灵活的组/命名空间模型官方建议按以下步骤渐进推进识别用户组确定用户归属的组映射命名空间确定用户应访问的命名空间创建新策略定义基于组与基于命名空间的策略对应GroupBasedPolicy/NamespaceBasedPolicy/CombinedGroupNamespacePolicy渐进测试先从只读权限开始逐步扩大范围监控持续观察日志确保认证与授权行为符合预期。十、最佳实践最小权限原则Principle of Least Privilege只授予完成任务所需的最小权限合理组织用户组按照职责把用户组织进逻辑组命名空间隔离使用命名空间隔离不同环境或团队定期审计周期性复查与审计权限配置。相关文档Authorization Manager授权管理器组件说明Permission Model权限模型概念RBAC ArchitectureRBAC 架构说明User Token Provisioning用户令牌提供指南权限概念文档【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价