mcpField
C
cloud-access-management

cloud-access-management

github.com/elastic安全6022.7k 次安装今天更新
代码仓库

关于 cloud-access-management

cloud-access-management 是用于管理 Elastic Cloud 组织及 Serverless 项目身份与访问权限的技能,面向组织成员和项目访问管理。它涵盖成员邀请、角色分配、自定义角色及 Cloud API 密钥,并要求先由 cloud-setup 配置环境。

主要功能

  1. 01邀请、列出和移除组织成员
  2. 02分配组织级与项目级角色
  3. 03创建和管理 Cloud API 密钥
  4. 04创建并分配 Serverless 自定义角色

适用场景

  1. 01为新成员授予 Serverless 项目访问权限
  2. 02调整现有成员的项目角色
  3. 03为程序化访问创建或撤销 API 密钥
  4. 04按索引和集群权限创建自定义角色

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elastic/agent-skills --skill cloud-access-management

安装后在 Claude Code 中输入/cloud-access-management确认已加载。

附带文件references/api-reference.mdscripts/cloud_access.py

详细介绍

Cloud Access Management

管理 Elastic Cloud 组织及其 Serverless 项目的身份与访问权限:邀请用户、分配预定义或自定义角色,以及管理 Cloud API 密钥。

**前提条件:**此技能假设 cloud-setup 技能已运行——EC_API_KEY 已在环境中设置,且组织上下文已建立。如果缺少 EC_API_KEY,请指示 Agent 先调用 cloud-setup。不要直接向用户索要 API 密钥。

如需创建项目,请参阅 cloud-create-project 技能。如需执行第 2 天项目操作(列出、更新、删除),请参阅 cloud-manage-project。如需管理 Elasticsearch 级别的角色(原生用户、角色映射、DLS/FLS),请参阅 elasticsearch-authz 技能。

有关详细的 API 端点和请求架构,请参阅 references/api-reference.md。

待办事项

  • 邀请用户加入组织,并为其分配 Serverless 项目角色
  • 列出组织成员及其当前角色分配
  • 更新用户的角色(组织级或项目级)
  • 将用户从组织中移除
  • 创建具有指定角色和有效期的额外 Cloud API 密钥
  • 创建也可在 Serverless 项目上调用 Elasticsearch 和 Kibana API 的 Cloud API 密钥
  • 列出并撤销 Cloud API 密钥
  • 在 Serverless 项目中创建具有 ES 集群、索引和 Kibana 权限的自定义角色
  • 使用 Cloud API 的 application_roles 为用户分配或移除其在 Serverless 项目上的自定义角色
  • 将自然语言访问请求转换为邀请、角色和 API 密钥相关任务

前提条件和权限

项目描述
EC_API_KEYCloud API 密钥(由 cloud-setup 设置)。所有操作都需要此密钥。
组织 ID使用 GET /organizations 自动发现。不要向用户索取。
项目端点Serverless 项目的 Elasticsearch 端点。仅自定义角色操作需要。
ES 凭据在项目上具有 manage_security 权限的 API 密钥或凭据。仅自定义角色操作需要。
组织所有者角色只有组织所有者才能创建和管理 Cloud API 密钥。API 密钥操作需要此角色。

在执行任何操作前,运行 python3 skills/cloud/access-management/scripts/cloud_access.py list-members,以验证 EC_API_KEY 有效并自动发现组织 ID。

操作级权限

Elastic Cloud Serverless 中常见访问管理操作需要以下权限。

操作所需权限
邀请或移除成员组织所有者(organization-admin)
分配或移除角色组织所有者(organization-admin)
创建或撤销 Cloud API 密钥组织所有者(organization-admin)
列出成员、邀请或密钥任意组织成员
创建或删除自定义角色项目 ES 端点上的 manage_security 集群权限

此技能不会单独预先检查角色。请尝试执行所请求的操作,并由 API 强制执行授权。如果 API 返回授权错误(例如 403 Forbidden),请停止操作,并要求用户确认所提供的 API 密钥权限。

手动设置备用方案(cloud-setup 不可用时)

如果此技能是独立安装的,且 cloud-setup 不可用,请告知用户在运行命令前手动配置 Cloud 环境变量。切勿要求用户在聊天中粘贴 API 密钥。

变量必需性描述
EC_API_KEY是具有 Organization owner 角色的 Elastic Cloud API 密钥。
EC_BASE_URL否Cloud API 基础 URL(默认值:https://api.elastic-cloud.com)。
ELASTICSEARCH_URL有条件Elasticsearch URL。仅自定义角色操作需要。
ELASTICSEARCH_API_KEY有条件具有 manage_security 权限的 Elasticsearch API 密钥。仅自定义角色操作需要。

注意: 如果缺少 EC_API_KEY,或用户还没有 Cloud API 密钥,请引导用户前往 Elastic Cloud API keys 生成密钥,然后按照以下步骤在本地配置。

首选方法(适合 Agent):在项目根目录创建 .env 文件:

EC_API_KEY=your-api-key
EC_BASE_URL=https://api.elastic-cloud.com
# Only needed for custom role operations against the project Elasticsearch endpoint:
# ELASTICSEARCH_URL=https://<project-id>.es.<region>.elastic-cloud.com
# ELASTICSEARCH_API_KEY=<your-es-manage-security-api-key>

所有 cloud/* 脚本都会自动从工作目录加载 .env。

替代方法:直接在终端中导出:

export EC_API_KEY="<your-cloud-api-key>"
export EC_BASE_URL="https://api.elastic-cloud.com"
# Only needed for custom role operations against the project Elasticsearch endpoint:
# export ELASTICSEARCH_URL="https://<project-id>.es.<region>.elastic-cloud.com"
# export ELASTICSEARCH_API_KEY="<your-es-manage-security-api-key>"

终端中的导出变量可能无法被运行在独立 Shell 会话中的沙盒 Agent 访问,因此使用 Agent 时优先选择 .env。

拆解访问权限请求

当用户用自然语言描述访问权限需求时(例如,“将 Alice 添加为我的搜索项目的开发者”),请在执行前将请求拆分为具体任务。

步骤 1 — 确认各项要素
要素需要回答的问题
对象新的组织成员(邀请),还是现有成员(更新角色)?
范围哪些 Serverless 项目,或组织级访问权限?
访问级别预定义角色(Admin/Developer/Viewer/Editor),还是自定义角色?
API 密钥?请求是否还需要用于编程访问的 Cloud API 密钥?
步骤 2 — 检查预定义角色是否合适

查阅下方的预定义角色表。优先使用预定义角色 — 仅当预定义角色无法提供所需的粒度时,才创建自定义角色。

步骤 3 — 检查现有状态

在创建或邀请之前,先检查现有内容:

python3 skills/cloud/access-management/scripts/cloud_access.py list-members
python3 skills/cloud/access-management/scripts/cloud_access.py list-api-keys

如果用户已经是成员,则跳过邀请,改为更新其角色。

对于 API 密钥请求,只有 Organization owners 才能创建和管理 Cloud API 密钥。如果已通过身份验证的用户没有 organization-admin 角色,API 密钥操作将因 403 错误而失败。查看 list-api-keys 返回的现有密钥。如果已有一个用于相同目的或任务的活动密钥,且具备所需角色并有足够的剩余有效期,请重复使用,而不是创建新密钥。如果两个密钥权限相同,但用途不同(例如,用于不同的 CI 管道),则可以同时存在;但为同一任务创建第二个密钥没有必要,还会增加管理负担。

步骤 4 — 执行

运行 skills/cloud/access-management/scripts/cloud_access.py 中相应的命令。执行破坏性操作(移除成员、撤销密钥)前,请先与用户确认。

步骤 5 — 验证

执行后,再次列出成员或密钥,以确认更改已生效。

预定义角色

组织级角色
角色Cloud API role_id描述
组织所有者organization-admin对组织、部署和项目拥有完整的管理权限
账单管理员billing-admin仅管理账单详情
无服务器项目级角色
角色Cloud API role_id适用范围描述
管理员adminSearch、Obs、Security完整的项目管理权限,登录后拥有超级用户权限
开发者developer仅限 Search创建索引、API 密钥、连接器和可视化
查看者viewerSearch、Obs、Security对项目数据和功能拥有只读访问权限
编辑者editorObs、Security配置项目功能,对数据索引拥有只读访问权限
一级分析师t1_analyst仅限 Security告警分流、常规读取、创建仪表板
二级分析师t2_analyst仅限 Security告警分流、启动调查、创建案例
三级分析师t3_analyst仅限 Security深入调查、规则、列表、响应操作
SOC 经理soc_manager仅限 Security告警、案例、端点策略、响应操作
规则作者rule_author仅限 Security检测工程、规则创建

项目级角色会在邀请时(POST /organizations/{org_id}/invitations)分配,也可以通过角色分配更新接口(POST /users/{user_id}/role_assignments)进行分配。有关包含 project 范围的 role_assignments JSON 架构,请参阅 references/api-reference.md。

自定义角色(无服务器)

如果预定义角色无法满足所需的细化程度,可以在无服务器项目中使用 Elasticsearch 安全 API 创建自定义角色,并通过 Cloud API 的 application_roles 字段将其分配给用户。

安全提示:使用自定义角色时,不要另外分配预定义的 Cloud 角色。 自定义角色会隐式授予项目范围内的查看者级 Cloud 访问权限。如果还将 viewer(或任何其他预定义角色)作为单独的 Cloud 角色分配给同一项目,用户通过 SSO 登录项目时会获得两种角色权限的并集——查看者栈角色的权限范围比大多数自定义角色更广,会覆盖你原本想要设置的限制。

自定义角色分配的工作方式
  • 预定义角色(viewer、developer、admin 等)通过 Cloud API(invite-user、assign-role)分配。当用户通过 SSO 登录项目时,会获得映射到其 Cloud 角色的堆栈角色(例如,Cloud viewer 映射到 viewer 堆栈角色)。
  • 自定义角色通过 Elasticsearch 安全 API(create-custom-role)在项目中创建,并通过 Cloud API 的 application_roles 字段(assign-custom-role)分配。设置 application_roles 后,用户通过 SSO 登录时只会获得指定的自定义角色,而不会获得其 Cloud 角色对应的默认堆栈角色。
  • assign-custom-role 命令会将 role_id 设为项目类型对应的 Viewer 角色(elasticsearch-viewer、observability-viewer 或 security-viewer),并将 application_roles 设为自定义角色名称。这样可确保用户能在 Cloud 控制台中查看和访问项目,但在项目内只获得自定义角色所限制的权限。
  • Cloud API 密钥也可以使用 application_roles,以在 Serverless 项目上获得 ES/Kibana API 访问权限。详情请参阅下文的 Cloud API 密钥 — ES 和 Kibana API 访问权限。
自定义角色的标准引导流程
  1. 在项目中创建自定义角色(create-custom-role)。
  2. 如果用户尚未加入组织,则邀请其加入(invite-user)。邀请中不要包含项目角色分配——下一步的自定义角色分配会处理项目访问权限。
  3. 将自定义角色分配给用户(assign-custom-role --user-id ... --project-id ... --custom-role-name ...)。
  4. 使用 list-members 和 list-roles 进行验证。
创建自定义角色
python3 skills/cloud/access-management/scripts/cloud_access.py create-custom-role \
  --role-name marketing-analyst \
  --body '{"cluster":[],"indices":[{"names":["marketing-*"],"privileges":["read","view_index_metadata"]}]}'

这会在项目的 Elasticsearch 端点上调用 PUT /_security/role/{name}。

命名限制

角色名称必须以字母或数字开头,且只能包含字母、数字、_、- 和 .。Serverless 中不提供 Run-as 权限。

何时使用自定义角色而非预定义角色
场景使用
标准管理员/开发者/查看者访问权限预定义角色
对特定索引模式的只读访问权限自定义角色
DLS 或 FLS 限制自定义角色
Kibana 功能级访问控制自定义角色

有关高级 DLS/FLS 模式(模板化查询、ABAC),请参阅 elasticsearch-authz 技能。

Cloud API 密钥 — ES 和 Kibana API 访问权限

Cloud API 密钥现在也可以选择在 Serverless 项目上访问 Elasticsearch 和 Kibana API,而不仅限于 Cloud API。这样,单个凭据即可同时用于控制平面(Cloud API)和数据平面(ES/Kibana API)操作——例如,CI 管道通过 Cloud API 创建项目后,再通过 ES API 索引数据。

工作方式

创建密钥时,将 application_roles 添加到密钥的 role_assignments 中。此字段接受预定义角色名称数组(admin、developer、viewer 以及解决方案专属角色,例如 t1_analyst、editor),也接受通过 PUT /_security/role/{name} 在项目中创建的自定义角色名称。每个项目默认都提供预定义角色。必须在密钥需要访问的每个项目中单独创建自定义角色——如果某个项目中不存在所引用的自定义角色,密钥在该项目中将不会获得任何访问权限,且不会显示提示。

关键规则:不会隐式继承

与用户不同,API 密钥绝不会从其 role_id 继承堆栈角色。如果省略 application_roles 或将其留空,密钥将仅能访问 Cloud API。使用此类密钥调用 ES 或 Kibana 端点会返回 403 Forbidden。这是为了向后兼容而设计的——现有未设置 application_roles 的密钥会继续作为仅限 Cloud 的密钥使用。

作用域模式
  • 项目作用域(首选)——授予对特定项目或指定类型的所有项目的访问权限。在 role_assignments 中使用 project 键,并在每个条目中设置 application_roles。除非用户明确需要跨项目访问权限,否则默认使用此模式。

  • 组织作用域——授予对组织中所有现有和未来项目的访问权限。在 role_assignments 中使用 organization 键,并设置 application_roles。**这是数据平面的最大作用域。**仅当密钥确实需要访问每个项目时才使用此模式(例如,平台自动化,或在整个组织范围内进行跨项目搜索)。使用 application_roles 创建组织作用域密钥前,务必先与用户确认,因为它会授予对可能尚不存在的项目的 ES/Kibana 访问权限。

**自定义角色和组织作用域访问:**在组织作用域分配中使用 application_roles 指定自定义角色名称时,必须在需要授予密钥访问权限的每个项目中都创建该自定义角色。如果某个项目未定义该自定义角色(通过 PUT /_security/role/{name}),密钥将静默地无法访问该项目——不会报错。对于组织范围的访问,建议使用预定义角色(admin、developer、viewer),这些角色默认在每个项目中都可用。如果必须在多个项目中使用自定义角色,请先确保已在每个目标项目中创建该角色。

**Agent 指南:**用户请求具有 ES/Kibana 访问权限的 API 密钥时,默认使用项目作用域分配。只有当用户明确需要访问所有项目时,才建议使用组织作用域 application_roles。继续操作前,请确认用户意图——组织作用域访问也适用于未来的项目。如果用户指定了组织作用域访问的自定义角色名称,请提醒他们必须在每个项目中分别定义该角色。

示例

具有 developer ES 访问权限的项目作用域密钥(使用 --stack-access 便捷标志):

python3 skills/cloud/access-management/scripts/cloud_access.py create-api-key \
  --description "CI pipeline - ES ingest" \
  --expiration 30d \
  --roles '{"project":{"elasticsearch":[{"role_id":"developer","organization_id":"$ORG_ID","all":true}]}}' \
  --stack-access developer

具有 admin ES 访问权限的组织作用域密钥(可访问所有项目——请谨慎使用):

python3 skills/cloud/access-management/scripts/cloud_access.py create-api-key \
  --description "Platform automation" \
  --expiration 7d \
  --roles '{"organization":[{"role_id":"organization-admin","organization_id":"$ORG_ID"}]}' \
  --stack-access admin

使用自定义角色的项目作用域密钥(原始 JSON):

python3 skills/cloud/access-management/scripts/cloud_access.py create-api-key \
  --description "Marketing ETL" \
  --expiration 14d \
  --roles '{"project":{"elasticsearch":[{"role_id":"elasticsearch-viewer","organization_id":"$ORG_ID","all":false,"project_ids":["$PROJECT_ID"],"application_roles":["marketing-writer"]}]}}'

将 $ORG_ID 和 $PROJECT_ID 替换为实际的组织 ID 和项目 ID。使用 list-members 查找组织 ID。

**常见错误:**如果 API 密钥在调用 ES 或 Kibana 端点时返回 403,最可能的原因是缺少 application_roles。与用户不同,API 密钥必须显式设置 application_roles 才能访问堆栈——仅设置 role_id 并不足够。

示例

邀请用户以 Viewer 身份加入搜索项目

提示词:“将 [email protected] 添加到我的搜索项目,并授予只读访问权限。”

python3 skills/cloud/access-management/scripts/cloud_access.py invite-user \
  --emails [email protected] \
  --roles '{"project":{"elasticsearch":[{"role_id":"viewer","organization_id":"$ORG_ID","all":false,"project_ids":["$PROJECT_ID"]}]}}'

将 $ORG_ID 和 $PROJECT_ID 替换为实际的 ID。接受邀请后,将为用户分配 Viewer 角色。若要授予自定义角色访问权限,请在用户接受邀请后使用 assign-custom-role——不要为同一项目同时分配预定义角色和自定义角色。

创建 CI/CD API 密钥

提示词:“为我们的 CI 流水线创建一个 API 密钥,30 天后过期,并可编辑所有部署。”

python3 skills/cloud/access-management/scripts/cloud_access.py create-api-key \
  --description "CI/CD pipeline" \
  --expiration "30d" \
  --roles '{"deployment":[{"role_id":"deployment-editor","all":true}]}'

实际密钥值会写入权限为 0600 的安全临时文件。stdout JSON 中包含 _secret_file 路径,而不是原始密钥。请告知用户从该文件中获取密钥——密钥仅显示一次。当 CI 流水线不再需要此密钥时,请使用 delete-api-key 撤销它,以免未使用的密钥不断累积。

创建具有 ES 访问权限的 CI/CD API 密钥

提示词:“为我们的 CI 流水线创建一个 API 密钥,以便将数据编入搜索项目。”

python3 skills/cloud/access-management/scripts/cloud_access.py create-api-key \
  --description "CI pipeline - ES ingest" \
  --expiration 30d \
  --roles '{"project":{"elasticsearch":[{"role_id":"developer","organization_id":"$ORG_ID","all":true}]}}' \
  --stack-access developer

将 $ORG_ID 替换为实际的组织 ID。--stack-access 标志会在角色分配中注入 application_roles: ["developer"],授予该密钥对所有 Elasticsearch 项目的开发者级 ES/Kibana API 访问权限。如果不使用 --stack-access(也未在 JSON 中显式指定 application_roles),该密钥将只能访问 Cloud API,调用 ES/Kibana 时会收到 403 错误。

为营销数据创建自定义角色

提示词:“创建一个角色,使其对我的搜索项目中的 marketing-* 索引具有只读访问权限。”

python3 skills/cloud/access-management/scripts/cloud_access.py create-custom-role \
  --role-name marketing-reader \
  --body '{"cluster":[],"indices":[{"names":["marketing-*"],"privileges":["read","view_index_metadata"]}]}'

然后使用 assign-custom-role 命令将自定义角色分配给用户,该命令会在 Cloud API 角色分配中设置 application_roles。

用于只读仪表板的完整自定义角色流程

提示词:“将 [email protected] 添加到我的搜索项目,并授予只读仪表板访问权限。”

# 1) Create custom role in the project
python3 skills/cloud/access-management/scripts/cloud_access.py create-custom-role \
  --role-name dashboard-reader \
  --body '{"cluster":[],"indices":[],"applications":[{"application":"kibana-.kibana","privileges":["feature_dashboard.read"],"resources":["*"]}]}'

# 2) Invite user to the organization (no project roles — custom role handles access)
python3 skills/cloud/access-management/scripts/cloud_access.py invite-user \
  --emails [email protected]

# 3) After invitation is accepted, assign the custom role via application_roles
python3 skills/cloud/access-management/scripts/cloud_access.py assign-custom-role \
  --user-id "$USER_ID" \
  --project-id "$PROJECT_ID" \
  --project-type elasticsearch \
  --custom-role-name dashboard-reader

用户将获得 Viewer 级别的 Cloud 访问权限(可在控制台中查看项目),并且在通过 SSO 登录项目时仅拥有 dashboard-reader 权限。不要同时为该项目单独分配 viewer Cloud 角色,否则将授予范围更广的 Viewer Stack 角色,并覆盖自定义角色的限制。

更新用户的项目角色

提示词:“将 Bob 在我们的可观测性项目中的角色提升为管理员。”

python3 skills/cloud/access-management/scripts/cloud_access.py assign-role \
  --user-id "$USER_ID" \
  --roles '{"project":{"observability":[{"role_id":"admin","organization_id":"$ORG_ID","all":false,"project_ids":["$PROJECT_ID"]}]}}'

将 $USER_ID、$ORG_ID 和 $PROJECT_ID 替换为实际值。使用 list-members 查找用户 ID。要移除角色分配,请使用 remove-role-assignment,并采用相同的 --roles 架构。

列出所有成员及其角色

提示词:“告诉我谁有权访问我的组织。”

python3 skills/cloud/access-management/scripts/cloud_access.py list-members

输出包含每位成员的用户 ID、电子邮件地址和已分配的角色。

指南

  • 如果未设置 EC_API_KEY,不要提示用户输入;应指示 Agent 先调用 cloud-setup。
  • 执行破坏性操作(移除成员、撤销密钥)前,始终先向用户确认。
  • 如果预定义角色能够满足访问要求,优先使用预定义角色,而不是自定义角色。
  • 在此处创建的 API 密钥是额外密钥,用于 CI/CD、限定访问权限或团队成员。初始密钥由 cloud-setup 管理。
  • 绝不将机密信息输出到 stdout 或 stderr。 脚本会在 stdout 中将敏感字段(key、token、invitation_token)替换为 REDACTED 占位符,并将完整的未脱敏响应写入权限为 0600(仅所有者可读)的临时文件。stdout 中的 JSON 包含指向该文件的 _secret_file 路径。绝不要尝试读取、提取或概述机密文件的内容。 如果用户索要密钥,告知他们打开 _secret_file 路径所指向的文件。用户获取机密信息后,提醒他们删除该文件。
  • Cloud API 密钥在创建时继承角色,之后无法更新;如需更改角色,请先撤销密钥,再重新创建。
  • API 密钥卫生——尽量减少数量、限定权限并设置有效期:
    • 创建密钥前,始终先运行 list-api-keys,并检查是否已有用途或任务相同的密钥,且该密钥具有所需角色并有足够的剩余有效期。权限相同但用途不同的密钥(例如,供两个独立 CI 流水线使用的密钥)是合理的;目标是避免为同一任务创建多余密钥。
    • 始终设置与任务预期时长相符的 --expiration。短期任务(CI 运行、一次性迁移)应使用短期密钥(例如 1d、7d)。
    • 任务完成后,提示用户使用 delete-api-key 撤销不再需要的密钥。短期和长期密钥均适用。
    • 长期密钥(例如,用于监控流水线的密钥)也应设置明确的有效期,并定期轮换,而不是设为永不过期。
  • 每个组织最多支持 500 个有效 API 密钥。默认有效期为 3 个月。
  • 邀请默认在 72 小时后过期。如果用户尚未接受,请重新发送邀请。
  • 有关 SAML SSO 配置,请参阅 Elastic Cloud SAML docs。
  • 自定义角色安全——不要过度授权: 使用 assign-custom-role 为某个项目分配自定义角色时,绝不要为同一项目分配预定义 Cloud 角色(例如 viewer)。自定义角色分配会隐式授予 Viewer 级别的 Cloud 访问权限。在此基础上再添加预定义角色,会扩大用户在项目中的权限,超出自定义角色预期的范围。
  • 如果自定义角色已存在,但用户无法访问项目,请确认是否已通过 assign-custom-role 分配该角色(该命令会在 Cloud API 中使用 application_roles)。仅创建自定义角色不会授予项目访问权限——必须通过 Cloud API 进行分配。
  • 有关网络级安全(流量筛选器、专用链接),请参阅 cloud-network-security 技能。
  • 有关超出 Cloud 角色范围的 ES 级角色管理(原生用户、DLS/FLS),请参阅 elasticsearch-authz。

评论

支持 Markdown