MinIO 多用户管理实践:用户、组与策略授权的完整操作指南
本文以 MinIO 官方的 Multi-user Quickstart Guide 为核心,系统讲解在 MinIO 对象存储中如何为不同访问者建立独立账号:包括创建用户与组、绑定内置/自定义策略、禁用与删除账号、切换策略,以及利用策略变量(aws:username、jwt:*、ldap:*)实现"用户专属目录"级别的细粒度授权。读完后你可以直接在 mc 客户端中复制执行全部命令,完成一套可落地的多用户访问控制方案。
一、背景与前提
MinIO 在服务器启动时会自动创建一个默认的长期凭据(operator credential),但生产环境中绝不应让所有客户端共享这一凭据。MinIO 原生支持多个长期用户:服务器启动后可以随时添加新用户,并为每个用户/组单独配置对桶和资源的允许/拒绝权限。
开始操作前需要准备:
- 安装
mc(MinIO Client),用于执行所有管理命令; - 部署并启动 MinIO 服务;
- 如需将用户身份持久化到 etcd 以便集群间同步,可参考仓库内的 Etcd V3 Quickstart Guide 配置 etcd。
适用前提:以下命令均以已配置好的
mc别名myminio(指向http://localhost:9000)为例,实际操作请替换为你的别名与地址。
二、创建用户并绑定策略
2.1 内置策略(canned policies)
MinIO 服务器提供一组默认的内置策略,主要包括 readwrite、readonly 和 writeonly(此外文档中还演示了 putonly 的切换使用)。这些内置策略默认作用于服务器上的所有资源;当需要限制到特定桶或对象时,应当用自定义策略覆盖它们。
自定义策略通过 mc admin policy create 创建。下面创建一个名为 getonly 的策略:允许用户下载 my-bucketname 桶下的所有对象。
先创建策略文件 getonly.json:
cat > getonly.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucketname/*"
],
"Sid": ""
}
]
}
EOF
然后注册该策略到 MinIO:
mc admin policy create myminio getonly getonly.json
2.2 创建用户并挂载策略
mc admin user add myminio newuser newuser123
用户创建成功后,将 getonly 策略绑定到该用户:
mc admin policy attach myminio getonly --user=newuser
此时 newuser 即只能读取 my-bucketname/* 下的对象,无法写入或列举其他资源(策略采用隐式拒绝:未被显式 Allow 的操作一律拒绝)。
从源码结构看,用户/组的增删与策略绑定等管理操作由服务端的管理处理器实现,核心逻辑位于 用户管理处理器,其对应的行为测试见 用户管理测试;IAM 系统的整体加载与存储位于 IAM 系统入口 与 对象存储型 IAM 后端。
三、创建组(Group)并为组绑定策略
组允许把同一策略一次性授予多个用户,减少逐个授权的成本:
mc admin group add myminio newgroup newuser
组创建成功后,直接将策略挂到组上:
mc admin policy attach myminio getonly --group=newgroup
组内所有成员(如 newuser)都会获得 getonly 策略的权限。
四、禁用与删除用户/组
禁用是比删除更温和的"下线"手段——账号保留但立即失去访问能力:
禁用用户:
mc admin user disable myminio newuser
禁用组(整组失效):
mc admin group disable myminio newgroup
确认不再需要后再执行删除:
删除用户:
mc admin user remove myminio newuser
先把用户从组中移除:
mc admin group remove myminio newgroup newuser
最后删除组本身:
mc admin group remove myminio newgroup
五、变更用户或组的策略
策略可以随时改绑,改绑后新的策略立即生效。例如把用户 newuser 的策略改为内置的 putonly:
mc admin policy attach myminio putonly --user=newuser
同样,组 newgroup 也可以整体切换到 putonly:
mc admin policy attach myminio putonly --group=newgroup
六、列出用户与组
查看当前所有(含启用与禁用状态)的用户:
mc admin user list myminio
查看所有组:
mc admin group list myminio
七、以新用户身份配置 mc 并验证权限
管理员完成授权后,可以切换到新用户身份来验证策略是否按预期生效:
mc alias set myminio-newuser http://localhost:9000 newuser newuser123 --api s3v4
mc cat myminio-newuser/my-bucketname/my-objectname
由于 newuser 只被允许 s3:GetObject,mc cat(读取对象)应当成功,而 mc cp 上传、mc ls 列举(若策略未含 s3:ListBucket)等应被拒绝。
八、策略变量:为每个用户划分"主目录"
8.1 规则说明
策略变量可以出现在 Resource 元素中,也可以出现在 Condition 元素的字符串比较中。当变量用于 Resource 时,只能替换 ARN 中第 5 个冒号(:)之后的资源部分,不能替换服务名、账号等前缀。
下面这个策略适合挂到组上:组内每个用户都能以完全的程序化方式访问属于自己的"主目录"对象——因为 ${aws:username} 会在鉴权时替换为当前用户名:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"]
}
]
}
8.2 OpenID Connect(STS)场景:jwt:* 变量
如果用户是通过 OpenID Connect 授权获得的 STS 临时凭据,MinIO 支持 JWT 规范中定义的全部标准 jwt:* 变量;自定义 jwt:* 或扩展字段不受支持。可用的变量列表如下:
jwt:subjwt:issjwt:audjwt:jtijwt:upnjwt:namejwt:groupsjwt:given_namejwt:family_namejwt:middle_namejwt:nicknamejwt:preferred_usernamejwt:profilejwt:picturejwt:websitejwt:emailjwt:genderjwt:birthdatejwt:phone_numberjwt:addressjwt:scopejwt:client_id
为 OpenID 用户划分专属"主目录"的策略示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${jwt:preferred_username}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${jwt:preferred_username}/*"]
}
]
}
8.3 AD/LDAP(STS)场景:ldap:* 变量
如果用户是通过 AD/LDAP 授权获得的 STS 凭据,可以使用以下 ldap:* 变量:
ldap:usernameldap:userldap:groups
对应的 LDAP 用户"主目录"策略示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${ldap:username}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${ldap:username}/*"]
}
]
}
从源码结构看,STS 临时凭据的签发由 STS 处理器 负责,签发时会将 JWT/LDAP 身份声明注入条件上下文,从而供上述策略变量在鉴权时取值。
8.4 所有请求中都可用的通用上下文键
| 上下文键 | 含义 |
|---|---|
aws:CurrentTime |
当前日期时间,用于日期/时间类条件 |
aws:EpochTime |
epoch(Unix)时间,用于日期/时间类条件 |
aws:PrincipalType |
标识主体类型:账号(Root 凭据)、用户(MinIO 用户)或 assumed role(STS) |
aws:SecureTransport |
布尔值,请求是否通过 TLS 发送 |
aws:SourceIp |
请求方 IP 地址,用于 IP 条件;若部署在 Nginx 等反向代理之后,MinIO 会保留真实源 IP |
aws:UserAgent |
请求方客户端应用的字符串信息;由客户端生成、可靠性有限,建议仅对 mc 或各 MinIO SDK 等标准化了 User-Agent 的客户端使用 |
aws:username |
当前用户的友好名称;在 AssumeRole 请求中它指向 STS 临时凭据。OpenID 场景请用 jwt:preferred_username,AD/LDAP 场景请用 ldap:username。在 MinIO 中 aws:userid 是 aws:username 的别名 |
aws:groups |
当前用户所属组名的数组;OpenID 场景请用 jwt:groups,AD/LDAP 场景请用 ldap:groups |
基于 aws:SourceIp 的 IP 白名单策略示例(只允许 203.0.113.0/24 网段列举 mybucket):
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "s3:ListBucket*",
"Resource": "arn:aws:s3:::mybucket",
"Condition": {"IpAddress": {"aws:SourceIp": "203.0.113.0/24"}}
}
}
策略求值的单元行为可以在 策略测试 中找到直接佐证:测试用例演示了 BucketPolicyArgs 中 Action、Resource 与 ConditionValues(如 SourceIp)如何共同决定一次访问是被允许还是被拒绝。
九、进一步扩展:多管理员用户
上述流程管理的是普通 S3 用户。MinIO 同样支持在默认运维凭据之外创建多个管理员用户,并为其授予细粒度的 admin:* 权限(如 admin:CreateUser、admin:ListUsers、admin:ServerInfo、admin:Heal 等)。完整的操作示例与权限清单参见仓库内的 管理员多用户指南。
十、小结
- 用户与组都可以在服务运行期间动态创建、禁用、删除,并通过
mc admin policy attach随时改绑策略; - 内置策略(
readwrite/readonly/writeonly等)作用于全部资源,涉及具体桶/对象时必须编写自定义策略; - 策略变量是"一人一目录"这类多租户隔离场景的关键:长期用户用
${aws:username},OpenID STS 用jwt:*(以jwt:preferred_username为常用项),AD/LDAP STS 用ldap:username; - 通用上下文键(
aws:SourceIp、aws:SecureTransport等)可组合出 IP 白名单、强制 HTTPS 等更复杂的访问控制规则。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00