- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
导读
ExternalPrincipal 是 lakeFS 开放 API 中用于表示"外部主体(外部身份)"的数据模型,它把一个来自外部认证体系(例如 AWS STS 的assumed-role)的身份标识映射到 lakeFS 内部的用户 ID 上,从而支持联合认证场景。本文以 Rust SDK 生成的 ExternalPrincipal 模型文档 为核心,结合 OpenAPI 规范 与服务端源码,完整讲解该模型的字段语义、settings 扩展机制、配套的增删查 API 端点、Rust SDK 中的实际用法以及对应的权限模型,读完即可在 Rust 客户端中正确构造与消费 ExternalPrincipal 数据。
ExternalPrincipal 模型字段详解
Rust SDK 中ExternalPrincipal模型的核心定义来自 OpenAPI 规范components/schemas/ExternalPrincipal(见 api/swagger.yml#L1913-L1929),生成的结构体位于 clients/rust/src/models/external_principal.rs。其字段如下表:
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | String | 是 | 外部主体的唯一标识,例如aws:sts::123:assumed-role/role-name |
| user_id | String | 是 | 与之关联的 lakeFS 用户 ID |
| settings | Option<Vec<std::collections::HashMap<String, String>>> | 否 | 附加设置,供远程认证器(remote authenticator)消费 |
对应生成的 Rust 结构体:
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct ExternalPrincipal { /// A unique identifier for the external principal i.e aws:sts::123:assumed-role/role-name #[serde(rename = "id")] pub id: String, /// lakeFS user ID to associate with an external principal. #[serde(rename = "user_id")] pub user_id: String, #[serde(rename = "settings", skip_serializing_if = "Option::is_none")] pub settings: Option<Vec<std::collections::HashMap<String, String>>>, } impl ExternalPrincipal { pub fn new(id: String, user_id: String) -> ExternalPrincipal { ExternalPrincipal { id, user_id, settings: None, } } }id:外部身份的唯一标识
id字段承载外部认证体系中的主体标识。OpenAPI 规范给出的示例aws:sts::123:assumed-role/role-name表明,它通常是一个带命名空间的字符串,能够唯一指代外部体系(如 AWS STS)中的某个角色或身份,而不是 lakeFS 内部的用户名。设计意图是让"外部身份"与"内部用户"解耦:外部系统怎么称呼这个主体,就由id原样记录。
user_id:与 lakeFS 用户的绑定关系
user_id是该外部主体所映射的 lakeFS 用户 ID,是模型中的另一个必填字段。两者组合的含义是:当外部主体通过联合认证方式访问 lakeFS 时,系统可以据此解析出它对应哪个内部用户,进而继承该用户的权限。这种"外部身份 → 内部用户"的一对一映射正是联合登录(external login)机制的基础。
settings:供远程认证器消费的扩展配置
settings是可选字段,类型为Option<Vec<std::collections::HashMap<String, String>>>,即一组键值对集合。在 OpenAPI 规范中,其元素类型被单独定义为ExternalPrincipalSettings(见 api/swagger.yml#L1901-L1905):
ExternalPrincipalSettings: type: object additionalProperties: type: string description: Additional settings to be consumed by the remote authenticator也就是说,settings中的每一项都是一个字符串到字符串的字典(additionalProperties: string),官方描述为"供远程认证器消费的附加设置"。它给了外部认证插件一个透明的扩展通道:例如某些远程认证器需要记录额外的身份上下文、租户信息或自定义属性时,可以写入该字段,而 lakeFS 侧只需原样存储与透传。由于是字符串字典,调用方需要自行约定键的语义。
配套的 API 端点:外部主体的完整生命周期
ExternalPrincipal并非孤立模型,OpenAPI 规范围绕它定义了 5 个端点(均标记了experimental标签),完整覆盖"创建关联、删除关联、查询、列举、登录":
| 方法与路径 | operationId | 功能 | 主要参数 | 成功响应 |
|---|---|---|---|---|
POST/auth/users/{userId}/external/principals | createUserExternalPrincipal | 将外部主体附加到用户 | path:userId;query:principalId;body:ExternalPrincipalCreation | 201 |
DELETE/auth/users/{userId}/external/principals | deleteUserExternalPrincipal | 从用户上解除外部主体 | path:userId;query:principalId | 204 |
GET/auth/users/{userId}/external/principals/ls | listUserExternalPrincipals | 列出某用户的外部主体 | path:userId;query: 分页参数prefix/after/amount | 200 返回ExternalPrincipalList |
GET/auth/external/principals | getExternalPrincipal | 按 id 查询外部主体 | query:principalId | 200 返回ExternalPrincipal |
POST/auth/external/principal/login | externalPrincipalLogin | 使用外部认证器执行登录 | body:ExternalLoginInformation | 200 返回AuthenticationToken |
端点定义分别见 api/swagger.yml#L2861-L2989(前 4 个)与 api/swagger.yml#L2146-L2174(登录端点)。
其中几个值得注意的细节:
- 创建/删除均以
principalId作为 query 参数,而非放在请求体中——即调用方通过 URL 指定要绑定/解绑的外部主体 id。 - 创建请求体是可选的,类型为
ExternalPrincipalCreation,它只包含一个可选字段settings(见 clients/rust/src/models/external_principal_creation.rs):
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct ExternalPrincipalCreation { #[serde(rename = "settings", skip_serializing_if = "Option::is_none")] pub settings: Option<Vec<std::collections::HashMap<String, String>>>, }即创建时可以在请求体中携带需要透传给远程认证器的附加设置。
- 列表接口返回分页结构
ExternalPrincipalList,其中pagination为Pagination对象、results为Vec<ExternalPrincipal>(见 clients/rust/src/models/external_principal_list.rs)。 - 登录端点使用
ExternalLoginInformation(必填字段为identityRequest,另有可选的token_expiration_duration,见 api/swagger.yml#L1139-L1147),成功后返回AuthenticationToken,与 lakeFS 常规登录的令牌模型保持一致。
Rust SDK 中的调用方式
Rust SDK 在apis模块中为上述端点生成了对应的异步函数,分布在 auth_api.rs 与 experimental_api.rs 中(部分端点同时在两个 API 模块中暴露,均由 ExternalApi、AuthApi 等文档入口索引)。函数签名如下:
// 创建关联:POST /auth/users/{userId}/external/principals?principalId=... pub async fn create_user_external_principal( configuration: &configuration::Configuration, user_id: &str, principal_id: &str, external_principal_creation: Option<models::ExternalPrincipalCreation>, ) -> Result<(), Error<CreateUserExternalPrincipalError>> // 解除关联:DELETE /auth/users/{userId}/external/principals?principalId=... pub async fn delete_user_external_principal( configuration: &configuration::Configuration, user_id: &str, principal_id: &str, ) -> Result<(), Error<DeleteUserExternalPrincipalError>> // 列举:GET /auth/users/{userId}/external/principals/ls pub async fn list_user_external_principals( configuration: &configuration::Configuration, user_id: &str, prefix: Option<&str>, after: Option<&str>, amount: Option<i32>, ) -> Result<models::ExternalPrincipalList, Error<ListUserExternalPrincipalsError>> // 按 id 查询:GET /auth/external/principals?principalId=... pub async fn get_external_principal( configuration: &configuration::Configuration, principal_id: &str, ) -> Result<models::ExternalPrincipal, Error<GetExternalPrincipalError>> // 外部登录:POST /auth/external/principal/login pub async fn external_principal_login( configuration: &configuration::Configuration, external_login_information: Option<models::ExternalLoginInformation>, ) -> Result<models::AuthenticationToken, Error<ExternalPrincipalLoginError>>从源码实现看(以 experimental_api.rs#L388-L405 为例),create_user_external_principal会构造POST {base_path}/auth/users/{userId}/external/principals请求,把principalId通过query(&[("principalId", ...)])附加到 URL,并依次配置 User-Agent、Basic Auth 或 Bearer Token 后发送 JSON 请求体;返回码落在 2xx 时返回Ok(()),否则包装为对应的CreateUserExternalPrincipalError枚举(内含 400/401/404/409/429 等分支,见 external_api.rs#L18-L78)。所有函数均为async,底层基于reqwest客户端,需要调用方运行在异步运行时中。
一个典型的"创建关联"调用示意:
let cfg = configuration::Configuration::new("http://localhost:8000"); let creation = Some(models::ExternalPrincipalCreation::new()); // settings 可选 auth_api::create_user_external_principal(&cfg, "alice", "aws:sts::123:assumed-role/role-name", creation) .await?;权限模型:为外部主体准备的 ARN 与操作权限
lakeFS 的权限系统为外部主体预留了一等公民的访问控制能力,这可以从两个源码事实得到印证:
其一,ARN 构造。在 pkg/permissions/permission.go#L62-L64 中定义了ExternalPrincipalArn:
func ExternalPrincipalArn(principalID string) string { return authArnPrefix + "externalPrincipal/" + principalID }即每个外部主体会对应形如arn:lakefs:auth:::externalPrincipal/{principalID}的资源 ARN,使其可以独立出现在授权策略的资源匹配中。
其二,操作权限枚举。在 pkg/permissions/actions.gen.go#L51-L53 中注册了三个与外部主体直接相关的 action:
auth:CreateUserExternalPrincipal—— 创建"外部主体↔用户"关联;auth:DeleteUserExternalPrincipal—— 解除关联;auth:ReadExternalPrincipal—— 读取外部主体信息。
这意味着管理员可以通过策略精确控制"谁可以给用户附加外部主体、谁可以查询/删除"。
当前实现状态与使用前提
需要特别说明的是,从当前仓库服务端源码看,这些端点在控制器层面仍处于实验性/占位实现阶段:ExternalPrincipalLogin及CreateUserExternalPrincipal、DeleteUserExternalPrincipal、GetExternalPrincipal、ListUserExternalPrincipals四个 handler 目前统一返回http.StatusNotImplemented(501),见 pkg/api/controller.go#L801-L803 与 pkg/api/controller.go#L6091-L6104:
func (c *Controller) CreateUserExternalPrincipal(w http.ResponseWriter, r *http.Request, _ apigen.CreateUserExternalPrincipalJSONRequestBody, _ string, _ apigen.CreateUserExternalPrincipalParams) { writeError(w, r, http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) }此外,配置层也保留了相关开关的历史痕迹:pkg/config/config.go#L698-L702 中的authentication_api.external_principals_enabled(以及remote_authenticator相关配置)已被标注为Deprecated: Value ignored,即当前版本读取配置时会忽略该开关。
因此,在使用本文介绍的 Rust SDK 函数前,请先确认所连接的 lakeFS 服务端版本是否已启用并实现了外部主体(external principal)功能;若服务端返回 501,说明该能力尚未在目标版本落地。本文内容以模型契约(OpenAPI 规范与生成的 Rust 代码)为准,适用于对接已实现该能力的服务端版本,或用于理解该特性的数据结构与调用约定。
典型应用场景
综合id字段的 AWS STS 示例(aws:sts::123:assumed-role/role-name)、settings的"远程认证器消费"定位以及externalPrincipalLogin端点的存在,可以推断该模型的典型使用场景是基于外部身份提供方的联合登录:
- 管理员预先通过
createUserExternalPrincipal把一个外部身份(如某个 AWS 角色)绑定到 lakeFS 内部用户; - 外部用户持身份凭据访问
/auth/external/principal/login,提交ExternalLoginInformation(内含identityRequest); - 远程认证器校验身份,并通过
ExternalPrincipal中的映射找到对应 lakeFS 用户,最终签发AuthenticationToken,后续请求即可携带该令牌访问对象数据。
小结
ExternalPrincipal是 lakeFS 联合认证体系中的核心数据模型:id描述外部身份、user_id完成到内部用户的映射、settings为远程认证器提供扩展配置空间;配合ExternalPrincipalCreation(创建入参)与ExternalPrincipalList(分页列表)两个辅助模型,以及 5 个 experimental 级 API 端点,形成了完整的"外部主体生命周期管理"契约。Rust SDK 已为开发者生成类型安全的异步调用函数,同时权限系统也预置了对应的 ARN 与操作权限。对于希望在 Rust 生态中对接 lakeFS 联合登录能力的开发者而言,本文的模型字段说明与调用签名即可作为直接可用的接入参考。
- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
相关推荐
lakeFS ExternalPrincipal 详解:外部身份主体数据模型与 Java SDK 对接实战
lakeFS ExternalPrincipal 详解:外部身份主体数据模型与 Java SDK 对接实战 在 lakeFS 的认证体系中,ExternalPr
数据工程数据湖大数据对象存储后端lakeFS Python SDK 中 ExternalLoginInformation 模型详解:外部身份登录请求的构造与使用
lakeFS Python SDK 中 ExternalLoginInformation 模型详解:外部身份登录请求的构造与使用 导读 ExternalLogi
数据工程数据湖大数据对象存储后端lakeFS Python SDK 中 ExternalPrincipal 模型全解析:外部主体绑定、查询与登录实战
lakeFS Python SDK 中 ExternalPrincipal 模型全解析:外部主体绑定、查询与登录实战 本文聚焦 lakeFS Python SD
数据工程数据湖大数据对象存储后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考