基于 Corsair 的 Kibana 插件实战:API Key 认证与 62 个端点的风险分级接入指南
【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair
@corsair-dev/kibana是 Corsair 生态中面向 Kibana 的官方集成插件,将 Kibana 的 Alerting、Cases、Connectors、Dashboards、Data Views、Saved Objects、Fleet、安全检测(Security Detection)等能力封装为统一的 Corsair 端点,供你的 Agent 以最小权限模型(read / write / destructive)安全地替用户操作其 Kibana 实例。读完本文,你将掌握该插件的安装方式、插件工厂配置、API Key 认证机制、全部 62 个端点的操作 ID 与风险分级、底层 HTTP 传输与错误重试原理,以及如何用仓库内的测试验证集成可用性。
一、插件定位:把 Kibana 变成 Agent 可安全调用的"应用"
Corsair 是一套让 Agent 连接"用户的第三方应用"的集成框架。每个应用对应一个插件包,插件把应用官方的 HTTP API 声明式地组织成带类型、带输入输出 schema、带风险分级的端点集合,并交由 Corsair 核心统一处理多租户凭证(API Key / OAuth)、密钥存储、权限校验、错误处理与事件日志。
@corsair-dev/kibana正是这个框架中的 Kibana 实现,其包结构如下(仓库 packages/kibana):
- index.ts:插件工厂
kibana(),聚合端点、schema、元数据、错误处理与密钥构建逻辑; - client.ts:统一的 Kibana REST 请求传输层
makeKibanaRequest; - endpoints/:按功能模块拆分的端点实现(alerting、cases、connectors、dashboards、data-views、detection-engine、fleet、lists-osquery、ops-unverified、saved-objects、security、status);
- schema/:Corsair 数据库实体定义(Saved Object、Space、Data View);
- error-handlers.ts:针对 429 / 401 / 403 / 404 的匹配与重试策略;
- api.test.ts 与 client.test.ts:实时 API 测试与传输层单测。
从 endpoints/index.ts 可以看出,端点实现按领域拆分为 13 个命名空间模块,插件入口只做聚合,职责清晰。
二、安装
在项目根目录执行:
pnpm add @corsair-dev/kibana该包以corsair(>=0.1.0)与zod(^4.1.13)为 peerDependencies(见 package.json),需要与 Corsair 核心在同一工作区或项目中安装。包类型为 ESM,构建产物输出到dist,同时暴露index.ts作为开发期源码入口(dev-source导出)。
三、插件初始化与配置项
在 Corsair 中注册 Kibana 插件,直接调用kibana()工厂:
import { kibana } from '@corsair-dev/kibana'; const app = corsair({ plugins: [ kibana({ // 可选:显式指定基础地址,否则使用租户凭证中的 base_url // baseUrl: 'https://kibana.example.com', // 可选:显式指定 API Key(用于测试/自托管场景) // key: '...', // 可选:覆盖默认错误处理器 // errorHandlers: { ... }, }), ], });插件支持的全部配置项定义在 index.ts 的KibanaPluginOptions类型中:
| 配置项 | 类型 | 说明 |
|---|---|---|
authType | PickAuth<'api_key'> | 认证类型,默认且仅支持api_key |
key | string | 显式注入的 API Key;仅在端点调用时使用(source === 'endpoint') |
baseUrl | string | Kibana 实例的基础 URL;优先级高于租户凭证中的base_url |
elasticsearchBaseUrl | string | 预留的 Elasticsearch 基础地址,用于需要直连 ES 的端点(如节点指标) |
hooks | InternalKibanaPlugin['hooks'] | Corsair 生命周期钩子 |
errorHandlers | CorsairErrorHandler | 自定义错误处理器,会与插件默认处理器合并 |
permissions | PluginPermissionsConfig<...> | 按端点覆盖权限配置 |
租户凭证模型
插件的认证配置(index.ts)声明:使用 API Key 时,每个租户账户需要两个字段:
export const kibanaAuthConfig = { api_key: { account: ['base_url', 'tenant_external_id'] as const, }, } as const satisfies PluginAuthConfig;即首次使用时,Corsair 会向租户索要base_url(Kibana 实例地址)和tenant_external_id(租户外部标识),API Key 本身由 Corsair 的密钥系统加密保存,不会暴露给 Agent。
密钥解析优先级
插件工厂内置的keyBuilder(index.ts)按以下顺序解析请求密钥:
- 若在插件选项中显式传入
key,则直接使用; - 否则从 Corsair 密钥存储读取
get_api_key(); - 都没有则返回空字符串。
若未显式提供baseUrl,每个端点在调用时会回退到租户凭证的get_base_url()(见各端点实现中的baseUrlOf/ctx.options.baseUrl ?? (await ctx.keys.get_base_url()) ?? ''),例如 alerting.ts。
四、认证机制:API Key 与 kbn-xsrf
Kibana 插件采用 API Key 认证(见 README.md 的 Auth 一节:Auth: API key. Corsair prompts your tenant for credentials on first use.)。
传输层的认证细节在 client.ts 中实现:
const headers: Record<string, string> = { 'Content-Type': 'application/json', 'kbn-xsrf': 'true', // Required for many Kibana API endpoints }; // 带前缀的凭据原样透传,否则默认使用 ApiKey 方案 if ( apiKey.startsWith('Basic ') || apiKey.startsWith('ApiKey ') || apiKey.startsWith('Bearer ') ) { headers.Authorization = apiKey; } else { headers.Authorization = `ApiKey ${apiKey}`; }要点:
kbn-xsrf: true必须携带:Kibana 对写操作(POST/PUT/DELETE)强制要求 XSRF 头,代码中已固定写入;- 认证方案:默认使用 Kibana 的
ApiKey方案(Authorization: ApiKey <base64(id:api_key)>),也支持Basic与Bearer前缀凭据直接透传; - 不在共享 HTTP 层设置
TOKEN:代码注释明确说明,若设置 TOKEN,共享请求层会把 Authorization 改写成 Bearer,从而覆盖掉 ApiKey/Basic 方案,因此这里只通过HEADERS传递凭据; baseUrl末尾的斜杠会被去除(baseUrl.replace(/\/$/, '')),端点路径以相对形式拼接。
五、端点全景:62 个操作一览
插件共注册 62 个端点,覆盖 Kibana 的 13 个功能领域。每个端点都有稳定的 Operation ID(形如kibana.api.<group>.<action>),并被标记为read(只读)、write(写入)或destructive(破坏性)三种风险等级。
5.1 Alerting(告警规则)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
alerting.createRule | kibana.api.alerting.createRule | write | Create a new alerting rule in Kibana |
alerting.deleteRule | kibana.api.alerting.deleteRule | destructive | Delete an alerting rule by ID |
alerting.listRules | kibana.api.alerting.listRules | read | List alerting rules with pagination and filters |
alerting.listRuleTypes | kibana.api.alerting.listRuleTypes | read | List available alerting rule types |
源码中(alerting.ts)对应 Kibana REST 路径已逐一验证:POST/DELETE /api/alerting/rule/{id}、GET /api/alerting/rules/_find、GET /api/alerting/rule_types。规则正文因规则类型而异,输入采用z.record(z.string(), z.unknown())的开放结构,避免为每种规则类型编造固定形状;列表查询支持page、per_page、search、filter、sort_field、sort_order等 Kibana 原生分页/过滤参数。
5.2 Cases(案件)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
cases.create | kibana.api.cases.create | write | Create a new case in Kibana |
cases.list | kibana.api.cases.list | read | Find and list cases with filters |
5.3 Connectors(连接器/动作)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
connectors.create | kibana.api.connectors.create | write | Create a new connector in Kibana |
connectors.delete | kibana.api.connectors.delete | destructive | Delete a connector by ID |
connectors.get | kibana.api.connectors.get | read | Retrieve a connector by ID |
connectors.list | kibana.api.connectors.list | read | List all connectors in Kibana |
connectors.listTypes | kibana.api.connectors.listTypes | read | List available connector (action) types |
从实时测试(api.test.ts)可确认 Connectors 列表走GET /api/actions/connectors,返回数组负载。
5.4 Dashboards(仪表盘)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
dashboards.create | kibana.api.dashboards.create | write | Create a new dashboard in Kibana |
dashboards.delete | kibana.api.dashboards.delete | destructive | Delete a dashboard by ID |
dashboards.get | kibana.api.dashboards.get | read | Retrieve a dashboard by ID |
dashboards.search | kibana.api.dashboards.search | read | Search dashboards in Kibana |
dashboards.upsert | kibana.api.dashboards.upsert | write | Create or update a dashboard by ID |
测试验证GET /api/dashboards?page=&per_page=返回{ data, meta: { total } }结构(api.test.ts)。
5.5 Data Views(数据视图)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
dataViews.create | kibana.api.dataViews.create | write | Create a new data view in Kibana |
dataViews.get | kibana.api.dataViews.get | read | Retrieve data view details by ID |
dataViews.list | kibana.api.dataViews.list | read | List all data views in Kibana |
对应GET /api/data_views已在测试中验证(api.test.ts)。
5.6 Detection(安全检测)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
detection.findAlerts | kibana.api.detection.findAlerts | read | Find and aggregate detection alerts |
detection.findRules | kibana.api.detection.findRules | read | Find detection engine rules with filters |
5.7 Fleet(代理与 EPM 包管理,端点最多)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
fleet.agentPoliciesList | kibana.api.fleet.agentPoliciesList | read | List Fleet agent policies with pagination |
fleet.agentsSetup | kibana.api.fleet.agentsSetup | read | Check Fleet agents setup status |
fleet.agentsVersions | kibana.api.fleet.agentsVersions | read | List available Fleet agent versions |
fleet.checkPermissions | kibana.api.fleet.checkPermissions | read | Check permissions for the Fleet API |
fleet.enrollmentKeyGet | kibana.api.fleet.enrollmentKeyGet | read | Retrieve a Fleet enrollment API key by ID |
fleet.enrollmentKeysList | kibana.api.fleet.enrollmentKeysList | read | List Fleet enrollment API keys |
fleet.epmCategories | kibana.api.fleet.epmCategories | read | List Fleet EPM package categories |
fleet.epmDataStreams | kibana.api.fleet.epmDataStreams | read | List Fleet EPM data streams |
fleet.epmPackageDetails | kibana.api.fleet.epmPackageDetails | read | Retrieve details of a Fleet EPM package version |
fleet.epmPackageFile | kibana.api.fleet.epmPackageFile | read | Retrieve a file from a Fleet EPM package |
fleet.epmPackagesInstalled | kibana.api.fleet.epmPackagesInstalled | read | List installed Fleet EPM packages |
fleet.epmPackagesLimited | kibana.api.fleet.epmPackagesLimited | read | List Fleet EPM package names only |
fleet.epmPackagesList | kibana.api.fleet.epmPackagesList | read | List available Fleet EPM packages |
fleet.epmPackageStats | kibana.api.fleet.epmPackageStats | read | Retrieve usage statistics for a Fleet package |
fleet.outputDelete | kibana.api.fleet.outputDelete | destructive | Delete a Fleet output by ID |
fleet.packagePoliciesList | kibana.api.fleet.packagePoliciesList | read | List Fleet package policies with pagination |
fleet.proxyDelete | kibana.api.fleet.proxyDelete | destructive | Delete a Fleet proxy by ID |
fleet.serverHostGet | kibana.api.fleet.serverHostGet | read | Retrieve a Fleet Server host by ID |
fleet.serverHostsList | kibana.api.fleet.serverHostsList | read | List Fleet Server hosts |
Fleet 是覆盖面最广的模块,fleet.ts 中所有路径均在 Kibana OpenAPI 规范(kibana.json)中核验过,如GET /api/fleet/check-permissions、GET /api/fleet/agent_policies、GET /api/fleet/enrollment_api_keys、GET /api/fleet/epm/packages/{pkg}/{version}、DELETE /api/fleet/outputs/{id}、DELETE /api/fleet/proxies/{id}等。列表类端点支持统一的分页/过滤参数(page、perPage、kuery),并针对部分端点提供full、withAgentCount、showUpgradeable、fleetServerSetup、prerelease等 Kibana 特有参数;文件类端点epmPackageFile会对路径中的每一段做encodeURIComponent编码后再拼接(fleet.ts),避免嵌套路径注入。
5.8 Index(索引管理,非官方 OpenAPI)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
index.listIndices | kibana.api.index.listIndices | read | List indices via Index Management (not in the official OpenAPI spec; disabled on serverless, works where Index Management UI is enabled) |
注意:该端点不在 Kibana 官方 OpenAPI 规范中,在 Serverless 环境下不可用,仅在启用了 Index Management UI 的环境中可用。
5.9 Lists 与 Osquery
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
lists.delete | kibana.api.lists.delete | destructive | Delete a value list by ID |
osquery.deleteSavedQuery | kibana.api.osquery.deleteSavedQuery | destructive | Delete an Osquery saved query by ID |
5.10 Metrics(指标)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
metrics.get | kibana.api.metrics.get | read | Retrieve Elasticsearch node metrics |
5.11 Reporting(报表,仅 Stateful)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
reporting.listJobs | kibana.api.reporting.listJobs | read | List Kibana reporting jobs (legacy stateful-only API; not in the official OpenAPI spec, 404 on serverless) |
同样标注了限制:这是旧的 Stateful 专用 API,不在官方 OpenAPI 规范中,Serverless 环境会返回 404。
5.12 Saved Objects(保存对象)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
savedObjects.create | kibana.api.savedObjects.create | write | Create a new saved object in Kibana |
savedObjects.delete | kibana.api.savedObjects.delete | destructive | Delete a saved object by type and ID |
savedObjects.find | kibana.api.savedObjects.find | read | Find saved objects matching search query or type filters |
savedObjects.get | kibana.api.savedObjects.get | read | Retrieve a specific saved object by type and ID |
savedObjects.update | kibana.api.savedObjects.update | write | Update attributes of an existing saved object by type and ID |
saved-objects.ts 实现对应GET /api/saved_objects/_find与GET/POST/PUT/DELETE /api/saved_objects/{type}/{id}:find支持type(数组会自动 join 成逗号分隔)、search、page、per_page、sort_field;create可选择是否携带 ID、是否带overwrite查询参数,body 由attributes与可选references组成。
5.13 Security(安全实体)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
security.entitiesList | kibana.api.security.entitiesList | read | List Entity Store entities |
security.entityStoreEngines | kibana.api.security.entityStoreEngines | read | Retrieve Entity Store engines (derived from the entity-store status response; no separate engines endpoint exists in the spec) |
security.entityStoreStatus | kibana.api.security.entityStoreStatus | read | Retrieve Entity Store status |
security.listEndpointItems | kibana.api.security.listEndpointItems | read | List Endpoint exception list items |
5.14 Status(实例状态)
| Operation | Operation ID | Risk | Description |
|---|---|---|---|
status.get | kibana.api.status.get | read | Retrieve health and version status of the Kibana instance |
对应GET /api/status,实时测试确认其返回版本负载(api.test.ts),可作为连通性与健康检查的探测端点。
六、风险分级与权限模型
从 index.ts 的kibanaEndpointMeta可见,每个端点都声明了riskLevel:
read:只读查询,占绝大多数,适合 Agent 自由调用;write:创建或修改资源(如alerting.createRule、savedObjects.update、dashboards.upsert);destructive:删除资源(如alerting.deleteRule、savedObjects.delete、fleet.outputDelete、lists.delete、osquery.deleteSavedQuery)。
该风险分级会汇入 Corsair 的权限体系,开发者可通过插件配置的permissions选项(PluginPermissionsConfig<typeof kibanaEndpointsNested>)按端点收紧或放开权限,实现对 Agent 行为的最小授权约束。
七、底层传输原理
所有端点最终都收敛到 client.ts 的makeKibanaRequest:
export async function makeKibanaRequest<T>( endpoint: string, baseUrl: string, apiKey: string, options: { method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; body?: Record<string, unknown>; query?: Record<string, string | number | boolean | undefined>; } = {}, ): Promise<T>- 方法支持:GET / POST / PUT / DELETE / PATCH;
- 负载策略:仅 POST / PUT / PATCH 携带
body(负载已由各端点的 zod schema 在上游校验,传输层保持通用);query 参数仅保留undefined之外的值(部分端点用q()辅助函数过滤,见 fleet.ts); - 媒体类型:
application/json; charset=utf-8; - 错误封装:
corsair/http的ApiError原样上抛;其他Error被包装为KibanaAPIError(带MISSING_BASE_URL等错误码);baseUrl缺失时直接抛KibanaAPIError('Base URL is required', 'MISSING_BASE_URL')。
此外,每个端点调用成功后都会通过logEventFromContext(ctx, 'kibana.<group>.<action>', {...input}, 'completed')记录审计事件,方便追踪 Agent 对用户 Kibana 的每一次操作。
八、错误处理与自动重试
插件内置了一套面向 Kibana 常见故障的默认错误处理器(error-handlers.ts):
| 处理器 | 匹配条件 | 策略 |
|---|---|---|
RATE_LIMIT_ERROR | HTTP 429,或消息包含rate_limited/ratelimited/429 | 最多重试 5 次,优先采用响应头携带的retryAfter(毫秒) |
AUTH_ERROR | HTTP 401,或消息包含unauthorized/invalid_auth | 不重试(maxRetries: 0) |
PERMISSION_ERROR | HTTP 403,或消息包含forbidden/permission_denied/insufficient_permissions/access_denied | 不重试 |
NOT_FOUND_ERROR | HTTP 404,或消息包含not_found/404 | 不重试 |
DEFAULT | 兜底匹配 | 不重试 |
认证与权限类错误不重试是合理的——凭据或权限问题不会因重试而消失;限流类错误则利用Retry-After头做指数退避式重试。开发者可通过插件选项errorHandlers覆盖默认行为,合并逻辑见 index.ts:{ ...errorHandlers, ...options.errorHandlers }。
九、Webhooks
Kibana 插件不注册任何 Webhook(README 明确标注No webhooks)。在插件工厂中webhooks与webhookSchemas均定义为空对象(index.ts),因此它是纯"请求-响应"型集成,不涉及事件订阅或回调投递。
十、数据实体(Corsair 数据库 Schema)
插件声明了 Corsair 数据库 schema(schema/index.ts),版本1.0.0,包含三类实体(定义见 schema/database.ts):
savedObjects:id、type、attributes(开放记录,因不同 saved object 类型属性各异)、可选version/updated_at/created_at;spaces:id、name、可选description/disabledFeatures/initials/color;dataViews:id、title、可选name/timeFieldName/sourceFilters/fields。
由于 Kibana 的 saved object 与 data view 字段随类型不同而变化,仓库刻意用z.unknown()承载可变字段而非编造固定形状(代码注释亦明确说明),保证 schema 面向未来扩展依然安全。
十一、测试与验证
仓库为该插件提供了两层测试:
- 传输层单测(client.test.ts):验证
makeKibanaRequest的请求组装、Authorization 头与错误封装逻辑; - 环境门控的实时 API 测试(api.test.ts):通过环境变量
KIBANA_BASE_URL与KIBANA_API_KEY控制,只有当两者都非空时才实际运行(RUN_LIVE判定,否则整组describe.skip)。覆盖api/status、api/alerting/rules/_find(校验total与data数组)、api/actions/connectors(校验数组负载)、api/dashboards(校验data与meta.total)、api/data_views、api/fleet/check-permissions等路径,且每种响应都用对应的输出 schema 做解析校验。
这意味着你可以通过设置KIBANA_BASE_URL与KIBANA_API_KEY指向自己的 Kibana 实例,运行pnpm test对真实环境做端到端冒烟验证。测试还记录了一个重要兼容性事实:Serverless 环境下 Saved Objects API 会返回 400("not available with the current configuration"),因此在 Serverless Kibana 中应避免依赖savedObjects.*端点。
十二、许可证
@corsair-dev/kibana以Apache-2.0许可证发布。
至此,你已经掌握了 Corsair Kibana 插件的完整接入路径:安装 → 插件工厂配置 → 租户 API Key 凭证 → 按风险分级选用 62 个端点 → 理解底层传输与错误重试。若要进一步定制,可以从 packages/kibana 的endpoints/目录入手,参考现有端点的实现模式(schema 定义 +makeKibanaRequest调用 + 事件记录)为你的场景扩展新的 Kibana 操作。
【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考