多个团队共用同一套 Kibana 时,页面组织、对象可见性和操作权限不能混成一个概念。Spaces 为 Saved Object 提供命名空间,RBAC 决定用户能做什么,Feature Controls 则裁剪可见功能。三层组合后,Kibana 才具备平台级多租户能力。

隔离需求的来源

一个 Elasticsearch 集群承载多个团队的数据是常态。但 Kibana 默认只有一个全局视图——所有 Dashboard、Index Pattern、Saved Search 堆在一起。团队 A 看到团队 B 的运维面板,不是安全问题(数据权限可以通过 ES 索引级别的角色控制),而是噪音问题。Spaces 的出发点是 UI 级别的组织隔离,不是数据安全隔离。安全隔离由 RBAC 叠加在 Spaces 之上实现。

架构总览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌─────────────────────────────────────────────────┐
│ Kibana Server │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Space: A │ │ Space: B │ │ Default │ │
│ │ │ │ │ │ Space │ │
│ │ namespace│ │ namespace│ │ namespace│ │
│ │ = "a" │ │ = "b" │ │ = (none) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
├───────┼──────────────┼──────────────┼───────────┤
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Saved Object Repository │ │
│ │ type + id + namespace → unique key │ │
│ └─────────────────────────────────────────┘ │
│ │ │
├──────────────────────┼──────────────────────────┤
│ RBAC Layer │ │
│ role → [space_a:read, space_b:all, ...] │
│ Feature Controls → per-space feature toggle │
└──────────────────────┼──────────────────────────┘

.kibana index (ES)

三个层次各管一件事:Spaces 管命名空间隔离,RBAC 管谁能进哪个 Space 做什么操作,Feature Controls 管进了 Space 之后能看到哪些功能入口。

Spaces:命名空间与 Saved Object 归属

Spaces 在 Kibana 6.5 引入。每个 Space 有唯一 ID(小写字母、数字、连字符),URL 路由体现为 /s/{space-id}/app/...。Default Space 的 ID 是 default,URL 不带 /s/ 前缀。

Saved Object 归属到 Space 的机制是 namespace 字段。一个 Dashboard 的存储记录在 .kibana 索引中大致是:

1
2
3
4
5
6
7
8
9
{
"type": "dashboard",
"id": "revenue-overview",
"namespace": "team-sre",
"attributes": { "title": "SRE Revenue Overview", "..." : "..." },
"references": [
{ "type": "index-pattern", "id": "logs-*", "name": "..." }
]
}

Default Space 的对象 namespace 字段不存储(undefined)。这意味着老版本升级上来的 Saved Object 自动落入 Default Space,无需迁移。

命名空间隔离的边界:同一个 type + id 在不同 namespace 下是独立对象。Space A 里的 dashboard:revenue 与 Space B 里的 dashboard:revenue 互不影响。当前官方文档把 Saved Object 的 namespaceType 归为四类:singlemultiple-isolatedmultipleagnostic。其中 config(全局配置)和 space 自身属于 agnostic,不受 Space 隔离。

RBAC:Elasticsearch 原生安全的延伸

Kibana 的 RBAC 不是自建的权限系统,而是 Elasticsearch 安全机制(原 X-Pack Security,7.x 起进入 Basic 许可)在 Kibana 层的投射。一个 Elasticsearch 角色定义包含三组权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
role: sre_viewer
cluster_privileges: [monitor]
index_privileges:
- indices: [logs-*, metrics-*]
privileges: [read]
kibana_privileges:
- spaces: [team-sre]
feature:
discover: [read]
dashboard: [read]
maps: [all]
- spaces: [*]
feature:
stackMonitoring: [read]

kibana_privileges 是 Kibana 特有的扩展,由 Kibana 的 Security 插件注册到 Elasticsearch。它表达的语义是:这个角色在 team-sre 这个 Space 里对 Discover 和 Dashboard 有只读权限,对 Maps 有完全权限;在所有 Space 里对 Stack Monitoring 有只读权限。

权限粒度三级递进:Space → Feature → 操作(read / all)。all 包含 read、write、create、delete 的语义。部分 Feature 还支持子特权(sub-feature privileges),在 8.x 中由插件通过 registerKibanaFeature 声明。

认证流程:用户登录时 Kibana 向 ES 发 _security/_authenticate,拿到用户的角色列表。后续每个请求经过 Kibana 的 Authorization Service,根据请求目标 Space + Feature + 操作类型做权限裁决。裁决结果缓存在会话中,不会逐请求查询 ES。

Feature Controls:Space 级别的功能开关

Feature Controls 在 7.2 引入,解决的问题是:即使角色允许访问某个 Space,管理员可能希望这个 Space 里根本不出现某些功能入口。典型场景是给业务团队创建一个"干净"的 Space,只开放 Dashboard 和 Discover,隐藏 Dev Tools、Stack Management 等运维功能。

Feature Controls 是 Space 维度的配置,存储在 Space 的 Saved Object 中:

1
2
3
4
5
6
7
8
{
"type": "space",
"id": "business-analytics",
"attributes": {
"name": "Business Analytics",
"disabledFeatures": ["dev_tools", "advancedSettings", "indexPatternManagement"]
}
}

被禁用的 Feature 在该 Space 中完全不渲染:侧边栏不显示入口,直接访问 URL 返回 404。Feature Controls 与 RBAC 是正交的——RBAC 决定"你有没有权限",Feature Controls 决定"这个 Space 有没有这个功能"。两者取交集:一个功能必须在 Space 中启用且用户角色拥有对应权限,才能实际访问。

多租户模型的组合

把三层叠在一起,Kibana 的多租户模型是:

控制维度 配置位置
Spaces 哪些 Saved Object 可见 Space 定义(管理员 UI 或 API)
Feature Controls 哪些功能入口存在 Space 的 disabledFeatures
RBAC 谁能做什么 ES 角色定义

一个典型多租户部署:每个产品线一个 Space,每个 Space 只开放该产品线需要的 Feature,角色按照职能(开发、运维、产品)分配不同 Space 的不同权限。

实现细节:Authorization Service

Kibana 的 Security 插件在 server 端提供 AuthorizationService,核心方法是 checkPrivilegesAtSpacecheckPrivilegesGlobally。插件在处理 HTTP 请求时调用它做权限裁决:

1
2
3
4
5
请求进入
→ 解析目标 Space(从 URL 中的 /s/{id} 或 Default Space)
→ 解析目标 Feature + 操作(从路由注册的 access tag)
→ AuthorizationService.checkPrivilegesAtSpace(spaceId, actions)
→ 返回 authorized / unauthorized

路由注册时通过 options.tags 声明所需权限:

1
2
3
4
router.get(
path: '/api/my-plugin/data',
options: { tags: ['access:myPlugin-read'] }
)

Security 插件根据 tag 前缀映射到对应的 Kibana privilege,再查用户角色是否持有该 privilege。

实验:验证 Space、Feature 与角色的交集

在测试环境创建两个 Space,只给其中一个 Space 开放 Dashboard。随后为同一用户分别授予两个 Space 的只读和完全权限,观察侧边栏入口、Dashboard 列表以及写入操作的差异。最后交换角色授权,不修改 Space 配置,再重复访问。这个实验能把“对象属于哪个命名空间”“功能是否启用”“用户是否有权操作”三种状态拆开观察。

模式提炼

Spaces 的设计可以抽象成三道独立闸门:命名空间决定对象集合,功能注册决定能力集合,授权服务决定主体可以执行的动作。三者分别建模以后,权限变化不需要搬迁对象,功能裁剪也不需要改角色定义。

工程迁移表

Kibana 机制 可迁移的工程模式 常见应用
Saved Object namespace 资源归属与逻辑分区 多租户后台、低代码工作区
Feature Controls 租户级能力开关 套餐差异、灰度开放
RBAC privilege 主体对资源的动作授权 企业权限中心、管理平台
路由 access tag 在入口声明访问要求 API 网关、服务端路由

练习

  1. 创建两个同名 Dashboard,分别保存在不同 Space,比较它们的对象 ID 与 namespace。
  2. 在 Space 中隐藏一个 Feature,再直接访问对应 URL,记录界面与接口行为。
  3. 为同一角色配置两个 Space 的不同权限,验证 read 与 all 对编辑操作的影响。

版本演进

版本 变化
6.5 Spaces 引入,命名空间隔离 Saved Object
7.0 RBAC 正式可用,Security 功能进入 Basic 许可
7.2 Feature Controls 引入,Space 级功能开关
7.x-8.x Saved Object sharing 体系成熟,namespaceType 细分为 single / multiple-isolated / multiple / agnostic
8.0 旧平台移除,Security 插件完全迁入 platform 架构
8.x Sub-feature privileges,更细粒度的操作级权限声明

常见误解

Space 不等于安全边界。没有开启 Elasticsearch Security 的集群,Space 只是视觉分区——任何人可以切换到任何 Space。安全隔离的前提是启用 Security 并配置 RBAC。

Feature Controls 不替代 RBAC。禁用某个 Feature 只是隐藏 UI 入口,不阻止 API 级别的访问(如果用户有对应角色权限,仍可通过 API 操作数据)。真正的权限屏障来自 RBAC 的 privilege 检查。

小结

Spaces 把 Saved Object 按 namespace 分区,RBAC 在 Elasticsearch 层统一管理"谁能在哪个 Space 做什么",Feature Controls 在 Space 维度裁剪功能入口。三层正交叠加,构成 Kibana 的访问控制体系。

下一篇进入 Kibana 的插件体系——platform 的 setup/start 生命周期如何解决旧平台的循环依赖和类型安全问题。


系列导航

篇目 主题
00 导读:Kibana 的状态存在 Elasticsearch 里
01 架构:浏览器、Node.js server 与 New Platform
02 Saved Object:一切状态的统一模型
03 Data View:查询之前的字段抽象
04 Search Source 与查询翻译
05 Discover:交互式检索的执行模型
06 聚合式可视化:Visualize 与 bucket/metric
07 Lens:拖拽背后的自动聚合推断
08 TSVB、Timelion 与 Vega
09 Dashboard 与 Embeddable
10 Alerting:Rule、Connector 与 Action
11 Reporting:从 Dashboard 到 PDF/PNG
12 Task Manager:分布式任务调度
13 Spaces 与安全:RBAC、Feature Controls 与多租户
14 插件体系:setup/start 生命周期
15 性能模型:bundle、bootstrap 与异步搜索会话
16 Kibana vs Grafana:两种平台的设计取舍
17 演进:从纯前端到 Platform 再到 Serverless

参考资料