关于 elasticsearch-authz
用于管理 Elasticsearch 基于角色的访问控制的技能,涵盖用户、角色、角色分配及外部 Realm 映射。适合负责集群权限配置的团队,可设置索引和 Kibana 权限,并通过文档级、字段级安全与模板实现细粒度控制。
主要功能
- 01管理原生用户和角色
- 02分配用户角色并验证权限
- 03配置 Kibana 功能与空间权限
- 04映射外部 Realm 用户
- 05设置文档级和字段级安全
- 06使用模板实现属性访问控制
适用场景
- 01为用户配置特定索引的只读权限
- 02限制不同部门可查看的文档
- 03隐藏角色不可见的敏感字段
- 04根据 LDAP 或 SAML 属性映射角色
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elastic/ agent-skills --skill elasticsearch-authz安装后在 Claude Code 中输入/elasticsearch-authz确认已加载。
附带文件references/api-reference.mdreferences/deployment-compatibility.md
详细介绍
Elasticsearch 授权
管理 Elasticsearch 基于角色的访问控制:原生用户、角色、角色分配,以及外部领域的角色映射。
如需了解身份验证方法和 API 密钥管理,请参阅 elasticsearch-authn 技能。
如需查看详细的 API 端点,请参阅 references/api-reference.md。
部署说明: 自行管理、ECH 和 Serverless 的功能可用性有所不同。详情请参阅 部署兼容性。
待办事项
- 创建具有特定权限集的原生用户
- 定义具有最小权限索引和集群访问权限的自定义角色
- 为现有用户分配一个或多个角色
- 创建具有 Kibana 功能或空间权限的角色
- 为外部领域用户(SAML、LDAP、PKI)配置角色映射
- 根据用户属性动态派生角色分配(Mustache 模板)
- 按用户或部门限制文档可见性(文档级安全)
- 对某些角色隐藏 PII 等敏感字段(字段级安全)
- 使用模板化角色查询实现基于属性的访问控制(ABAC)
- 将自然语言访问请求转换为用户、角色和角色映射任务
先决条件
| 项目 | 说明 |
|---|---|
| Elasticsearch URL | 集群端点(例如 https://localhost:9200 或云部署 URL) |
| Kibana URL | 仅在设置 Kibana 功能/空间权限时需要 |
| 身份验证 | 有效凭据(请参阅 elasticsearch-authn 技能) |
| 集群权限 | 用户和角色管理操作需要 manage_security |
如有任何缺失值,请向用户询问。
分解访问请求
当用户用自然语言描述访问需求时(例如“创建一个对 logs-* 具有只读访问权限的用户”),请先将请求拆分为具体任务,再执行。遵循以下工作流:
步骤 1 — 确定组成部分
从提示词中提取以下信息:
| 组成部分 | 需要回答的问题 |
|---|---|
| 对象 | 新建的原生用户、现有用户,还是外部领域用户(LDAP、SAML 等)? |
| 内容 | 哪些索引、数据流或 Kibana 功能? |
| 访问级别 | 读取、写入、管理,还是特定的权限集? |
| 范围 | 所有文档/字段,还是按地区、部门、敏感级别限制? |
| Kibana? | 请求是否提及任何 Kibana 功能(仪表板、Discover 等)? |
| 部署? | 自行管理、ECH 还是 Serverless?Serverless 使用不同的用户模型。 |
步骤 2 — 检查现有角色
创建新角色之前,请检查现有角色是否已授予所需访问权限:
curl "${ELASTICSEARCH_URL}/_security/role" <auth_flags>
如果存在匹配的角色,请跳过角色创建并重复使用该角色。
步骤 3 — 创建角色(如有需要)
根据请求确定角色名称和显示名称。对于纯索引/集群角色,请使用 Elasticsearch API。如果涉及 Kibana 功能,请使用 Kibana API(请参阅选择合适的 API)。
第 4 步 — 创建或更新用户
| 场景 | 操作 |
|---|---|
| 新建本地用户 | 使用该角色和生成的强密码创建用户。(仅限自管理 / ECH。) |
| 现有本地用户 | 获取当前角色,追加新角色,然后使用完整数组更新用户。(仅限自管理 / ECH。) |
| 外部 Realm 用户 | 创建角色映射,将用户的 Realm 属性与角色相匹配。(仅限自管理 / ECH。) |
| Serverless 用户 | 使用 cloud-access-management 技能。先分配预定义角色或创建自定义角色,然后通过 Cloud API 分配该角色。 |
示例拆解
提示词:“创建一个用户 analyst,使其对 logs-* 和 metrics-* 具有只读访问权限,并能在 Kibana 中查看仪表板。”
- 确认信息:新用户
analyst、索引logs-*/metrics-*、仪表板、读取权限。 - 检查角色:
GET /_security/role— 没有匹配项。 - 通过 Kibana API 创建角色(涉及仪表板):
logs-metrics-dashboard-viewer。 - 创建用户:通过
POST /_security/user/analyst,并设置roles: ["logs-metrics-dashboard-viewer"]。
如果请求含糊不清,请在每个步骤中向用户确认。
管理本地用户
本地用户管理适用于自管理和 ECH 部署。在 Serverless 上,用户由组织级别管理 — 请跳过本节。
创建用户
curl -X POST "${ELASTICSEARCH_URL}/_security/user/${USERNAME}" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"password": "'"${PASSWORD}"'",
"roles": ["'"${ROLE_NAME}"'"],
"full_name": "'"${FULL_NAME}"'",
"email": "'"${EMAIL}"'",
"enabled": true
}'
更新用户
使用 PUT /_security/user/${USERNAME} 并提供要更改的字段。省略 password 可保留现有密码。
其他用户操作
curl -X POST "${ELASTICSEARCH_URL}/_security/user/${USERNAME}/_password" \
<auth_flags> -H "Content-Type: application/json" \
-d '{"password": "'"${NEW_PASSWORD}"'"}'
curl -X PUT "${ELASTICSEARCH_URL}/_security/user/${USERNAME}/_disable" <auth_flags>
curl -X PUT "${ELASTICSEARCH_URL}/_security/user/${USERNAME}/_enable" <auth_flags>
curl "${ELASTICSEARCH_URL}/_security/user/${USERNAME}" <auth_flags>
curl -X DELETE "${ELASTICSEARCH_URL}/_security/user/${USERNAME}" <auth_flags>
管理角色
选择合适的 API
如果角色只需要 cluster 和 indices 权限,请使用 Elasticsearch API(PUT /_security/role/{name})。这是默认选项 — 无需 Kibana 端点。
如果角色包含任何 Kibana 功能或空间权限,请使用 Kibana 角色 API(PUT /api/security/role/{name})。Elasticsearch API 无法设置 Kibana 功能授权、空间范围或基本权限,因此,如果用户提到 Discover、Dashboards、Maps、Visualize、Canvas 或其他任何 Kibana 应用,则必须使用 Kibana API。
如果 Kibana 端点不可用,或向 Kibana 进行 API 密钥身份验证失败,则退回使用 Elasticsearch API 设置 cluster 和 indices 部分,并告知用户无法设置 Kibana 权限。在放弃之前,请用户提供 Kibana URL 或其他凭据。
创建或更新角色(Elasticsearch API)
当角色仅包含索引和集群权限时,默认选择:
curl -X PUT "${ELASTICSEARCH_URL}/_security/role/${ROLE_NAME}" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"description": "'"${ROLE_DISPLAY_NAME}"'",
"cluster": [],
"indices": [
{
"names": ["'"${INDEX_PATTERN}"'"],
"privileges": ["read", "view_index_metadata"]
}
]
}'
创建或更新角色(Kibana API)
当角色包含 Kibana 功能或空间权限时,必须使用:
curl -X PUT "${KIBANA_URL}/api/security/role/${ROLE_NAME}" \
<auth_flags> \
-H "kbn-xsrf: true" \
-H "Content-Type: application/json" \
-d '{
"description": "'"${ROLE_DISPLAY_NAME}"'",
"elasticsearch": {
"cluster": [],
"indices": [
{
"names": ["'"${INDEX_PATTERN}"'"],
"privileges": ["read", "view_index_metadata"]
}
]
},
"kibana": [
{
"base": [],
"feature": {
"discover": ["read"],
"dashboard": ["read"]
},
"spaces": ["*"]
}
]
}'
获取、列出和删除角色
curl "${ELASTICSEARCH_URL}/_security/role/${ROLE_NAME}" <auth_flags>
curl "${ELASTICSEARCH_URL}/_security/role" <auth_flags>
curl -X DELETE "${ELASTICSEARCH_URL}/_security/role/${ROLE_NAME}" <auth_flags>
文档级和字段级安全
角色可以在索引内限制对文档和字段的访问,权限范围比索引级权限更精细。
字段级安全(FLS)
限制角色可见的字段。使用 grant 将字段加入允许列表,或使用 except 将字段加入屏蔽列表:
curl -X PUT "${ELASTICSEARCH_URL}/_security/role/pii-redacted-reader" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"description": "PII Redacted Reader",
"indices": [
{
"names": ["customers-*"],
"privileges": ["read"],
"field_security": {
"grant": ["*"],
"except": ["ssn", "credit_card", "date_of_birth"]
}
}
]
}'
具有此角色的用户可以看到除 PII 字段以外的所有字段。FLS 会对搜索、获取和聚合结果强制执行。
文档级安全(DLS)
通过附加查询过滤器来限制角色可见的文档:
curl -X PUT "${ELASTICSEARCH_URL}/_security/role/emea-logs-reader" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"description": "EMEA Logs Reader",
"indices": [
{
"names": ["logs-*"],
"privileges": ["read"],
"query": "{\"term\": {\"region\": \"emea\"}}"
}
]
}'
query 字段是一个包含 Query DSL 过滤器的 JSON 字符串。具有此角色的用户只能看到 region 等于 emea 的文档。
模板化 DLS 查询(ABAC)
DLS 查询支持 Mustache 模板,可在查询时注入用户元数据,从而在 RBAC 之上实现基于属性的访问控制
(ABAC)。将用户专属属性存储在用户的 metadata 字段中,然后在角色
查询模板中使用 {{_user.metadata.<key>}} 引用。
curl -X PUT "${ELASTICSEARCH_URL}/_security/role/department-reader" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"description": "Department Reader",
"indices": [
{
"names": ["records-*"],
"privileges": ["read"],
"query": "{\"template\": {\"source\": \"{\\\"term\\\": {\\\"department\\\": \\\"{{_user.metadata.department}}\\\"}}\"}}"
}
]
}'
具有 "metadata": {"department": "engineering"} 的用户只能看到 department 等于 engineering 的文档。同一个
角色适用于所有部门,无需为每个部门创建单独的角色。
对于多值属性(例如,必需项目的列表),可使用 terms_set 和 minimum_should_match_field,以
确保用户持有文档中列出的所有必需属性。这样,只需使用单个角色,即可实现复杂的 ABAC 策略,例如组合
安全级别、项目列表和认证日期。完整的 terms_set ABAC 示例(包括组合多条件策略和用户元数据设置),请参阅
references/api-reference.md。
组合使用 DLS 和 FLS
单个索引权限条目可以同时包含 query(DLS)和 field_security(FLS)。实际组合用例请参阅
HR 部门示例。
当用户持有多个角色时,DLS 查询会以 OR 组合,FLS 授权字段会合并。没有 DLS/FLS 限制的宽泛角色可能会意外扩大访问范围。组合角色时,务必检查最终生效的权限,并确保不受限制的角色不会覆盖 DLS/FLS 的预期限制。
为用户分配角色
仅适用于自托管和 ECH。在 Serverless 上,请使用 cloud-access-management 技能 — 参阅 Serverless 用户访问。
使用新的 roles 数组更新用户:
curl -X PUT "${ELASTICSEARCH_URL}/_security/user/${USERNAME}" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"roles": ["role-a", "role-b"]
}'
roles 数组会被整体替换 — 请包含用户应拥有的所有角色。更新前先获取用户信息,以查看当前角色。
验证生效的权限
更新角色或用户后,使用以下命令验证实际访问权限:
curl -X POST "${ELASTICSEARCH_URL}/_security/user/_has_privileges" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"cluster": ["monitor"],
"index": [
{
"names": ["'"${INDEX_PATTERN}"'"],
"privileges": ["read", "view_index_metadata"]
}
]
}'
管理角色映射
Serverless 上不提供角色映射(ES API 和 Kibana UI 均已禁用)。请改用 cloud-access-management 技能 — 参阅 Serverless 用户访问。
角色映射会根据属性规则,将外部领域用户(LDAP、AD、SAML、PKI)分配给角色。仅适用于自托管和 ECH。 支持的规则运算符和资源字段,请参阅 角色映射资源属性。
静态角色映射
curl -X PUT "${ELASTICSEARCH_URL}/_security/role_mapping/saml-default-access" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"roles": ["viewer"],
"enabled": true,
"rules": {
"field": { "realm.name": "saml1" }
}
}'
基于 LDAP 组的映射
curl -X PUT "${ELASTICSEARCH_URL}/_security/role_mapping/ldap-admins" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"roles": ["superuser"],
"enabled": true,
"rules": {
"all": [
{ "field": { "realm.name": "ldap1" } },
{ "field": { "groups": "cn=admins,ou=groups,dc=example,dc=com" } }
]
}
}'
使用 Mustache 模板动态分配角色
使用 role_templates 而非 roles,根据用户属性推导角色名称。必须启用脚本功能。
curl -X PUT "${ELASTICSEARCH_URL}/_security/role_mapping/ldap-group-roles" \
<auth_flags> \
-H "Content-Type: application/json" \
-d '{
"role_templates": [
{
"template": { "source": "{{#tojson}}groups{{/tojson}}" },
"format": "json"
}
],
"enabled": true,
"rules": {
"field": { "realm.name": "ldap1" }
}
}'
更多 Mustache 模式示例(包括根据领域用户名推导角色和分级组访问),请参阅 references/api-reference.md。
获取、列出和删除角色映射
curl "${ELASTICSEARCH_URL}/_security/role_mapping/saml-default-access" <auth_flags>
curl "${ELASTICSEARCH_URL}/_security/role_mapping" <auth_flags>
curl -X DELETE "${ELASTICSEARCH_URL}/_security/role_mapping/saml-default-access" <auth_flags>
Serverless 用户访问
在 Serverless 上,没有原生用户或角色映射。用户通过 Cloud 级别的角色分配获得项目访问权限。
- 预定义角色(例如
admin、developer、viewer)适用于常见访问场景。如果其中一个符合需求,可直接通过 Cloud API 分配 — 无需创建自定义角色。 - 当用户需要精细化访问权限(特定索引、Kibana 功能、DLS/FLS)时,必须使用自定义角色。 使用 Elasticsearch API 或 Kibana API 创建自定义角色(与自托管相同 — 请参阅 管理角色),然后通过 Cloud API 将其与预定义基础角色一同分配给用户。
- Serverless 自定义角色不提供 Run-as 权限。
完整工作流(邀请用户、分配角色、管理 Cloud API 密钥和验证访问权限)请使用 cloud-access-management 技能。此技能仅处理角色定义;cloud-access-management 负责用户分配。
示例
创建用于查看日志的只读用户
请求:“创建一个用户 joe,使其拥有对 logs-* 的只读访问权限。”
- 通过
PUT /_security/role/logs-reader创建角色,并设置"description": "Logs Reader"和indices: [{ names: ["logs-*"], privileges: ["read", "view_index_metadata"] }]。 - 通过
POST /_security/user/joe创建用户,并设置"roles": ["logs-reader"]和一个强度高的生成密码。
创建可访问 Kibana 仪表板的角色
请求:“允许用户读取 logs-*,并在 Kibana 中查看仪表板。”
使用 Kibana API(PUT <KIBANA_URL>/api/security/role/logs-dashboard-viewer),通过
elasticsearch.indices 设置数据访问权限,并通过 kibana[].feature 设置对所有空间中仪表板和 Discover 的只读访问权限。完整请求结构请参阅
创建或更新角色(Kibana API)。
为现有用户添加角色
请求:“在 Alice 现有角色的基础上,授予她对 apm-* 的访问权限。”
GET /_security/user/alice— 响应显示"roles": ["viewer"]。- 创建
apm-reader角色,并设置indices: [{ names: ["apm-*"], privileges: ["read", "view_index_metadata"] }]。 - 使用
"roles": ["viewer", "apm-reader"]执行PUT /_security/user/alice(包括所有角色)。
授予 Serverless 用户对 Kibana 仪表板的读写访问权限
请求:“授予 [email protected] 对 colors 索引的读写访问权限,并允许她使用仪表板和 Discover。”
- 通过 Kibana API 创建自定义角色:
PUT <KIBANA_URL>/api/security/role/colors-rw-kibana,通过elasticsearch.indices为colors设置read、write、view_index_metadata权限,并通过kibana[].feature设置dashboard、discover权限。 - 使用 cloud-access-management 技能为该用户分配自定义角色
colors-rw-kibana。
按部门限制 HR 数据(DLS + FLS)
请求:“每位经理只能查看自己部门的 HR 记录,并且应隐藏个人身份信息字段。”
- 创建带部门元数据的用户:
POST /_security/user/manager_a,并设置"metadata": {"department": "engineering"}。 - 创建具有 DLS + FLS 的角色:
PUT /_security/role/hr-department-viewer
{
"description": "HR Department Viewer",
"indices": [
{
"names": ["hr-*"],
"privileges": ["read"],
"field_security": { "grant": ["*"], "except": ["ssn", "salary", "date_of_birth"] },
"query": "{\"template\": {\"source\": \"{\\\"term\\\": {\\\"department\\\": \\\"{{_user.metadata.department}}\\\"}}\"}}"
}
]
}
同一角色适用于所有部门 — 每位用户只能看到自己部门的记录,且个人身份信息字段会被移除。
指南
最小权限原则
- 日常操作绝不要使用
elastic超级用户。应创建专用的最小权限角色,并将elastic保留用于初始设置和紧急恢复。 - 使用
read和view_index_metadata进行只读数据访问。除非有明确需要,否则不要设置cluster权限。 - 使用 DLS(
query)和 FLS(field_security)限制对索引内数据的访问。
仅使用命名权限
绝不要使用内部操作名称(例如 indices:data/read/search)。始终使用官方文档中列出的命名权限。
优先使用细粒度权限(manage_ingest_pipelines、monitor),而不是宽泛权限(manage、all)。完整的权限参考表请参阅
references/api-reference.md。
角色命名约定
- 使用简短的小写名称,并以连字符分隔:
logs-reader、apm-data-viewer、metrics-writer。 - 避免使用
custom-role或new-role之类的通用名称。 - 将
description设为简短、易读的显示名称,而不是长句。它会在 Kibana UI 中显示为角色标签。好的示例:"Logs Reader"、"APM Data Viewer"。不好的示例:"Read-only access to all logs-* indices for the operations team"。
用户管理
- 默认生成强密码:至少 16 个字符,混合使用大写字母、小写字母、数字和符号(例如
X9k#mP2vL!qR7wZn)。绝不要使用changeme或password123之类的占位值。 - 优先停用用户,而不是删除用户,以保留审计记录。
- 更新用户时,
roles数组会被完全替换。修改前务必获取当前角色。
角色映射最佳实践
- 对于简单、固定的分配(例如,所有 SAML 用户都获得
viewer角色),使用静态roles。 - 仅当角色必须根据用户属性动态生成时,才使用带 Mustache 的
role_templates。 - 组合使用
all、any、field和except规则,以表达复杂条件,避免重复映射。 - 先使用
enabled: false测试新映射,验证通过后再启用。
部署兼容性
请参阅 references/deployment-compatibility.md,了解功能矩阵以及关于自管理、ECH 和 Serverless 部署差异的详细说明。