cloud-access-management by elastic/agent-skills
npx skills add https://github.com/elastic/agent-skills --skill cloud-access-management管理 Elastic Cloud 组织及其无服务器项目的身份和访问权限:邀请用户、分配预定义或自定义角色,以及管理云 API 密钥。
前提条件: 此技能假设 cloud-setup 技能已运行 ——
EC_API_KEY已在环境中设置且组织上下文已建立。如果缺少EC_API_KEY,请指示代理先调用 cloud-setup。请勿直接向用户索要 API 密钥。
关于项目创建,请参阅 cloud-create-project 技能。关于项目日常运维(列出、更新、删除),请参阅 cloud-manage-project。关于 Elasticsearch 级别的角色管理(本地用户、角色映射、DLS/FLS),请参阅 elasticsearch-authz 技能。
关于详细的 API 端点和请求模式,请参阅 references/api-reference.md。
application_roles 为无服务器项目上的用户分配或移除自定义角色广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 项目 | 描述 |
|---|---|
| EC_API_KEY | 云 API 密钥(由 cloud-setup 设置)。所有操作都需要。 |
| 组织 ID | 使用 GET /organizations 自动发现。不要向用户询问。 |
| 项目端点 | 无服务器项目的 Elasticsearch 端点。仅自定义角色操作需要。 |
| ES 凭据 | 在项目上具有 manage_security 权限的 API 密钥或凭据。仅自定义角色需要。 |
| 组织所有者角色 | 只有组织所有者可以创建和管理云 API 密钥。API 密钥操作需要。 |
在执行任何操作之前,运行 python3 skills/cloud/access-management/scripts/cloud_access.py list-members 以验证 EC_API_KEY 是否有效并自动发现组织 ID。
当用户用自然语言描述访问权限时(例如,“将 Alice 以开发者身份添加到我的搜索项目”),在执行之前将请求分解为离散的任务。
| 组件 | 需要回答的问题 |
|---|---|
| 谁 | 新组织成员(邀请)还是现有成员(角色更新)? |
| 什么 | 哪个无服务器项目或组织级别的访问? |
| 访问级别 | 预定义角色(Admin/Developer/Viewer/Editor)还是自定义角色? |
| API 密钥? | 请求是否还需要用于编程访问的云 API 密钥? |
参考下面的预定义角色表。优先使用预定义角色 —— 仅当预定义角色无法提供所需的粒度时才创建自定义角色。
在创建或邀请之前,检查已存在的内容:
python3 skills/cloud/access-management/scripts/cloud_access.py list-members
python3 skills/cloud/access-management/scripts/cloud_access.py list-api-keys
如果用户已经是成员,则跳过邀请,改为更新其角色。
对于 API 密钥请求,只有组织所有者可以创建和管理云 API 密钥。如果经过身份验证的用户没有 organization-admin 角色,API 密钥操作将失败并返回 403 错误。查看 list-api-keys 返回的现有密钥。如果已经存在一个用于相同目的或任务的活跃密钥,且具有所需的角色和足够的剩余生命周期,请重用该密钥,而不是创建新密钥。当两个具有相同权限的密钥服务于不同目的时(例如,独立的 CI 流水线),这是可以的,但为同一任务创建第二个密钥是不必要的,并且会增加管理负担。
从 skills/cloud/access-management/scripts/cloud_access.py 运行适当的命令。在执行破坏性操作(移除成员、撤销密钥)之前,请与用户确认。
执行后,再次列出成员或密钥以确认更改生效。
| 角色 | Cloud API role_id | 描述 |
|---|---|---|
| 组织所有者 | organization-admin | 对组织、部署、项目的完全管理权限 |
| 计费管理员 | billing-admin | 仅管理账单详情 |
| 角色 | Cloud API role_id | 可用项目类型 | 描述 |
|---|---|---|---|
| 管理员 | admin | Search, Obs, Security | 完整的项目管理,登录时具有超级用户权限 |
| 开发者 | developer | Search only | 创建索引、API 密钥、连接器、可视化 |
| 查看者 | viewer | Search, Obs, Security | 对项目数据和功能的只读访问权限 |
| 编辑者 | editor | Obs, Security | 配置项目功能,对数据索引只读 |
| 一级分析师 | t1_analyst | Security only | 告警分类、常规读取、创建仪表板 |
| 二级分析师 | t2_analyst | Security only | 告警分类、开始调查、创建案例 |
| 三级分析师 | t3_analyst | Security only | 深度调查、规则、列表、响应操作 |
| SOC 经理 | soc_manager | Security only | 告警、案例、端点策略、响应操作 |
| 规则作者 | rule_author | Security only | 检测工程、规则创建 |
项目级别角色在邀请期间(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 堆栈角色比大多数自定义角色更广泛,将覆盖您预期的限制。
viewer、developer、admin 等)通过 Cloud API(invite-user、assign-role)分配。当用户 SSO 进入项目时,他们会收到映射到其 Cloud 角色的堆栈角色(例如,Cloud viewer 映射到 viewer 堆栈角色)。create-custom-role)在项目中创建,并通过 Cloud API 的 application_roles 字段(assign-custom-role)分配。当设置 application_roles 时,用户在 SSO 时仅获得指定的自定义角色 —— 而不是其 Cloud 角色的默认堆栈角色。assign-custom-role 命令将 role_id 设置为项目类型的查看者角色(elasticsearch-viewer、observability-viewer 或 security-viewer),并将 application_roles 设置为自定义角色名称。这确保用户可以在 Cloud 控制台中看到并访问项目,但在项目内部仅获得自定义角色的受限权限。create-api-key)目前仅携带 Cloud 角色。计划支持将自定义角色分配给云 API 密钥,一旦在生产环境中可用,将在此处记录。create-custom-role)。invite-user)。在邀请中不要包含项目角色分配 —— 下一步的自定义角色分配会处理项目访问。assign-custom-role --user-id ... --project-id ... --custom-role-name ...)。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}。
角色名称必须以字母或数字开头,并且只能包含字母、数字、_、- 和 .。在无服务器环境中不可用 Run-as 权限。
| 场景 | 使用 |
|---|---|
| 标准管理员/开发者/查看者访问 | 预定义角色 |
| 对特定索引模式的只读访问 | 自定义角色 |
| DLS 或 FLS 限制 | 自定义角色 |
| Kibana 功能级别访问控制 | 自定义角色 |
关于高级 DLS/FLS 模式(模板化查询、ABAC),请参阅 elasticsearch-authz 技能。
提示: “将 alice@example.com 添加到我的搜索项目,授予只读访问权限。”
python3 skills/cloud/access-management/scripts/cloud_access.py invite-user \
--emails alice@example.com \
--roles '{"project":{"elasticsearch":[{"role_id":"viewer","organization_id":"$ORG_ID","all":false,"project_ids":["$PROJECT_ID"]}]}}'
将 $ORG_ID 和 $PROJECT_ID 替换为实际 ID。查看者角色在邀请被接受时分配。对于自定义角色访问,请在用户接受邀请后使用 assign-custom-role —— 不要将预定义角色分配与同一项目的自定义角色结合使用。
提示: “为我们的 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 撤销它,以避免未使用的密钥累积。
提示: “创建一个角色,授予对我的搜索项目上 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。
提示: “将 bob@example.com 添加到我的搜索项目,授予只读仪表板访问权限。”
# 1) 在项目中创建自定义角色
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) 邀请用户加入组织(不分配项目角色 —— 自定义角色处理访问)
python3 skills/cloud/access-management/scripts/cloud_access.py invite-user \
--emails bob@example.com
# 3) 邀请被接受后,通过 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
用户获得查看者级别的 Cloud 访问权限(可以在控制台中看到项目),并且在 SSO 进入项目时仅获得 dashboard-reader 权限。不要为此项目也分配 viewer 作为单独的 Cloud 角色 —— 这样做将授予更广泛的 Viewer 堆栈角色,并覆盖自定义角色的限制。
提示: “将 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。要移除角色分配,请使用具有相同 --roles 模式的 remove-role-assignment。
提示: “显示谁有权访问我的组织。”
python3 skills/cloud/access-management/scripts/cloud_access.py list-members
输出包括每个成员的用户 ID、电子邮件和分配的角色。
EC_API_KEY,不要提示用户 —— 指示代理先调用 cloud-setup。key、token、invitation_token)替换为 REDACTED 占位符,并将完整的未编辑响应写入具有 0600(仅所有者可读)权限的临时文件。stdout JSON 包含指向该文件的 _secret_file 路径。切勿尝试读取、提取或总结密钥文件的内容。 如果用户索要密钥,请告诉他们打开 _secret_file 路径处的文件。用户检索到密钥后,建议他们删除该文件。list-api-keys 并检查是否已存在一个用于相同目的或任务的现有密钥,且具有所需的角色和足够的剩余生命周期。具有相同权限但服务于不同目的的密钥(例如,两个独立的 CI 流水线)是合法的 —— 目标是避免为同一任务创建冗余密钥。--expiration。短期任务(CI 运行、一次性迁移)应使用短期密钥(例如,1d、7d)。delete-api-key 撤销任何不再需要的密钥。这适用于短期和长期运行的密钥。assign-custom-role 时,切勿为该项目分配预定义的 Cloud 角色(例如,viewer)。自定义角色分配隐式授予查看者级别的 Cloud 访问权限。在此基础上添加预定义角色会扩大用户在项目内的权限,超出自定义角色的预期。assign-custom-role 分配了角色(该命令在 Cloud API 中使用 application_roles)。仅创建自定义角色不会授予项目访问权限 —— 需要 Cloud API 分配。每周安装次数
114
仓库
GitHub 星标数
89
首次出现
10 天前
安全审计
安装于
cursor102
github-copilot95
opencode94
gemini-cli94
codex94
amp94
Manage identity and access for an Elastic Cloud organization and its Serverless projects: invite users, assign predefined or custom roles, and manage Cloud API keys.
Prerequisite: This skill assumes the cloud-setup skill has already run —
EC_API_KEYis set in the environment and the organization context is established. IfEC_API_KEYis missing, instruct the agent to invoke cloud-setup first. Do NOT prompt the user for an API key directly.
For project creation, see the cloud-create-project skill. For day-2 project operations (list, update, delete), see cloud-manage-project. For Elasticsearch-level role management (native users, role mappings, DLS/FLS), see the elasticsearch-authz skill.
For detailed API endpoints and request schemas, see references/api-reference.md.
application_roles| Item | Description |
|---|---|
| EC_API_KEY | Cloud API key (set by cloud-setup). Required for all operations. |
| Organization ID | Auto-discovered using GET /organizations. Do not ask the user for it. |
| Project endpoint | Elasticsearch endpoint of a Serverless project. Required only for custom role operations. |
| ES credentials | API key or credentials with manage_security privilege on the project. Required only for custom roles. |
| Org owner role | Only Organization owners can create and manage Cloud API keys. Required for API key operations. |
Run python3 skills/cloud/access-management/scripts/cloud_access.py list-members to verify that EC_API_KEY is valid and auto-discover the org ID before proceeding with any operation.
When the user describes access in natural language (for example, "add Alice to my search project as a developer"), break the request into discrete tasks before executing.
| Component | Question to answer |
|---|---|
| Who | New org member (invite) or existing member (role update)? |
| What | Which Serverless project(s) or org-level access? |
| Access level | Predefined role (Admin/Developer/Viewer/Editor) or custom role? |
| API key? | Does the request also need a Cloud API key for programmatic access? |
Consult the predefined roles table below. Prefer predefined roles — only create a custom role when predefined roles do not provide the required granularity.
Before creating or inviting, check what already exists:
python3 skills/cloud/access-management/scripts/cloud_access.py list-members
python3 skills/cloud/access-management/scripts/cloud_access.py list-api-keys
If the user is already a member, skip the invitation and update their roles instead.
For API key requests , only Organization owners can create and manage Cloud API keys. If the authenticated user does not have the organization-admin role, API key operations will fail with a 403 error. Review the existing keys returned by list-api-keys. If an active key already exists for the same purpose or task with the required roles and sufficient remaining lifetime, reuse it instead of creating a new one. Two keys with identical permissions are fine when they serve different purposes (for example, separate CI pipelines), but creating a second key for the same task is unnecessary and increases the management burden.
Run the appropriate command(s) from skills/cloud/access-management/scripts/cloud_access.py. Confirm destructive actions (remove member, revoke key) with the user before executing.
After execution, list members or keys again to confirm the change took effect.
| Role | Cloud API role_id | Description |
|---|---|---|
| Organization owner | organization-admin | Full admin over org, deployments, projects |
| Billing admin | billing-admin | Manage billing details only |
| Role | Cloud API role_id | Available on | Description |
|---|---|---|---|
| Admin | admin | Search, Obs, Security | Full project management, superuser on sign-in |
| Developer | developer | Search only | Create indices, API keys, connectors, visualizations |
| Viewer | viewer | Search, Obs, Security | Read-only access to project data and features |
| Editor | editor |
Project-level roles are assigned during invitation (POST /organizations/{org_id}/invitations) or using the role assignment update (POST /users/{user_id}/role_assignments). See references/api-reference.md for the role_assignments JSON schema including the project scope.
When predefined roles lack the required granularity, create a custom role inside the Serverless project using the Elasticsearch security API and assign it to users through the Cloud API's application_roles field.
Security: do not assign a predefined Cloud role separately when using a custom role. Custom roles implicitly grant Viewer-level Cloud access for the project scope. If you also assign
viewer(or any other predefined role) as a separate Cloud role assignment for the same project, the user receives the union of both roles when they SSO into the project — the Viewer stack role is broader than most custom roles and will override the restrictions you intended.
viewer, developer, admin, etc.) are assigned via Cloud APIs (invite-user, assign-role). When the user SSOs into the project, they receive the stack role mapped to their Cloud role (for example, Cloud viewer maps to the viewer stack role).create-custom-role) and assigned via the Cloud API's application_roles field (assign-custom-role). When is set, the user gets the specified custom role on SSO — not the default stack role for their Cloud role.create-custom-role).invite-user). Do not include project role assignments in the invitation — the custom role assignment in the next step handles project access.assign-custom-role --user-id ... --project-id ... --custom-role-name ...).list-members and 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"]}]}'
This calls PUT /_security/role/{name} on the project Elasticsearch endpoint.
Role names must begin with a letter or digit and contain only letters, digits, _, -, and .. Run-as privileges are not available in Serverless.
| Scenario | Use |
|---|---|
| Standard admin/developer/viewer access | Predefined role |
| Read-only access to specific index pattern | Custom role |
| DLS or FLS restrictions | Custom role |
| Kibana feature-level access control | Custom role |
For advanced DLS/FLS patterns (templated queries, ABAC), see the elasticsearch-authz skill.
Prompt: "Add alice@example.com to my search project with read-only access."
python3 skills/cloud/access-management/scripts/cloud_access.py invite-user \
--emails alice@example.com \
--roles '{"project":{"elasticsearch":[{"role_id":"viewer","organization_id":"$ORG_ID","all":false,"project_ids":["$PROJECT_ID"]}]}}'
Replace $ORG_ID and $PROJECT_ID with the actual IDs. The Viewer role is assigned when the invitation is accepted. For custom role access, use assign-custom-role after the user has accepted the invitation — do not combine a predefined role assignment with a custom role for the same project.
Prompt: "Create an API key for our CI pipeline that expires in 30 days with editor access to all deployments."
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}]}'
The actual key value is written to a secure temp file (0600 permissions). The stdout JSON contains a _secret_file path instead of the raw secret. Tell the user to retrieve the key from that file — it is shown only once. When the CI pipeline no longer needs this key, revoke it using delete-api-key to avoid unused keys accumulating.
Prompt: "Create a role that gives read-only access to marketing-* indices on my search project."
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"]}]}'
Then assign the custom role to a user using the assign-custom-role command, which sets application_roles in the Cloud API role assignment.
Prompt: "Add bob@example.com to my search project with read-only dashboard access."
# 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 bob@example.com
# 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
The user receives Viewer-level Cloud access (can see the project in the console) and only dashboard-reader permissions when they SSO into the project. Do not also assign viewer as a separate Cloud role for this project — doing so would grant the broader Viewer stack role and override the custom role's restrictions.
Prompt: "Promote Bob to admin on our observability project."
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"]}]}}'
Replace $USER_ID, $ORG_ID, and $PROJECT_ID with actual values. Use list-members to look up the user ID. To remove a role assignment, use remove-role-assignment with the same --roles schema.
Prompt: "Show me who has access to my organization."
python3 skills/cloud/access-management/scripts/cloud_access.py list-members
The output includes each member's user ID, email, and assigned roles.
EC_API_KEY is not set, do not prompt the user — instruct the agent to invoke cloud-setup first.key, token, invitation_token) with a REDACTED placeholder in stdout and writes the full unredacted response to a temporary file with 0600 (owner-read-only) permissions. The stdout JSON includes a _secret_file path pointing to that file. Never attempt to read, extract, or summarize the contents of the secret file. If the user asks for the key, tell them to open the file at the _secret_file path. After the user retrieves the secret, advise them to delete the file.Weekly Installs
114
Repository
GitHub Stars
89
First Seen
10 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
cursor102
github-copilot95
opencode94
gemini-cli94
codex94
amp94
Azure 升级评估与自动化工具 - 轻松迁移 Functions 计划、托管层级和 SKU
104,900 周安装
| Obs, Security |
| Configure project features, read-only data indices |
| Tier 1 analyst | t1_analyst | Security only | Alert triage, general read, create dashboards |
| Tier 2 analyst | t2_analyst | Security only | Alert triage, begin investigations, create cases |
| Tier 3 analyst | t3_analyst | Security only | Deep investigation, rules, lists, response actions |
| SOC manager | soc_manager | Security only | Alerts, cases, endpoint policy, response actions |
| Rule author | rule_author | Security only | Detection engineering, rule creation |
application_rolesassign-custom-role command sets role_id to the project-type Viewer role (elasticsearch-viewer, observability-viewer, or security-viewer) and sets application_roles to the custom role name. This ensures the user can see and access the project in the Cloud console but receives only the custom role's restricted permissions inside the project.create-api-key) currently carry Cloud roles only. Support for assigning custom roles to Cloud API keys is planned and will be documented here once available in production.list-api-keys and check whether an existing key for the same purpose or task already has the required roles and sufficient remaining lifetime. Keys with identical permissions serving different purposes (for example, two separate CI pipelines) are legitimate — the goal is to avoid redundant keys for the same task.--expiration that matches the intended task lifetime. Short-lived tasks (CI runs, one-time migrations) should use short-lived keys (for example, 1d, 7d).delete-api-key. This applies to both short-lived and long-running keys.viewer) for a project when using assign-custom-role for the same project. The custom role assignment implicitly grants Viewer-level Cloud access. Adding a predefined role on top widens the user's in-project permissions beyond what the custom role intended.assign-custom-role (which uses application_roles in the Cloud API). Creating a custom role alone does not grant project access — the Cloud API assignment is required.