kibana/packages/kbn-eslint-plugin-eslint
Kibana Machine 15348c0f28
[9.0] [Hardening] Kibana Feature API Privileges Names (#208067) (#209315)
# Backport

This will backport the following commits from `main` to `9.0`:
- [[Hardening] Kibana Feature API Privileges Names
(#208067)](https://github.com/elastic/kibana/pull/208067)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Elena
Shostak","email":"165678770+elena-shostak@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-02-03T14:22:29Z","message":"[Hardening]
Kibana Feature API Privileges Names (#208067)\n\n## Summary\r\n\r\nAs
part of our effort to harden API action definitions and
enforce\r\nstandards this PR adds an utility `ApiPrivileges`
class.\r\nIt is supposed to be used for both feature registration and
API route\r\ndefinition to construct the privilege
name.\r\n```ts\r\nplugins.features.registerKibanaFeature({\r\n
privileges: {\r\n all: {\r\n app: [...],\r\n catalogue: [...],\r\n api:
[ApiPrivileges.manage('subject_name')],\r\n ...\r\n },\r\n read: {\r\n
...\r\n api: [ApiPrivileges.read('subject_name')],\r\n ...\r\n },\r\n
},\r\n})\r\n....\r\n\r\n// route definition\r\nrouter.get(\r\n {\r\n
path: 'api_path',\r\n security: {\r\n authz: {\r\n requiredPrivileges:
[ApiPrivileges.manage('subject_name')],\r\n },\r\n },\r\n },\r\n async
(ctx, req, res) =>
{}\r\n);\r\n```\r\n\r\n`require_kibana_feature_privileges_naming` eslint
rule has been added to\r\nshow warning if the API privilege name doesn't
satisfy the naming\r\nconvention.\r\n\r\n### Naming convention\r\n\r\n-
API privilege should start with valid `ApiOperation`:
`manage`,\r\n`read`, `update`, `delete`, `create`\r\n- API privilege
should use `_` as separator\r\n\r\n `read-entity-a`\r\n
`delete_entity-a`\r\n `entity_manage`\r\n `read_entity_a`\r\n
`delete_entity_a`\r\n `manage_entity`\r\n\r\n> [!IMPORTANT] \r\n>
Serverless ZDT update scenario:\r\n>\r\n> - version N has an endpoint
protected with the `old_privilege_read`.\r\n> - version N+1 has the same
endpoint protected with a new\r\n`read_privilege`.\r\n> \r\n> There
might be a short period between the time the UI pod N+1 passes\r\nSO
migrations and updates privileges and the time it's marked
as\r\nready-to-handle-requests by k8s, and when UI pod N is
terminated.\r\n>\r\n> After discussion with @legrego and @azasypkin we
decided to ignore it\r\ndue to the perceived risk-to-cost ratio:\r\n> 1.
The time window users might be affected is very narrow because
we\r\nregister privileges late in the Kibana startup flow (e.g., after
SO\r\nmigrations).\r\n> 2. The transient 403 errors users might get
won't result in session\r\ntermination and shouldn't lead to data
loss.\r\n> 3. The roll-out will be performed in batches over the course
of\r\nmultiple weeks and implemented by different teams. This means the
impact\r\nper release shouldn't be significant.\r\n\r\n###
Checklist\r\n\r\n-
[x]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n__Relates:
https://github.com/elastic/kibana/issues/198716__\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"504510b92b0e92cbc173f0de517c506d2f54d536","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Security","release_note:skip","Feature:Hardening","backport:prev-minor","Team:Obs
AI Assistant","v9.1.0"],"title":"[Hardening] Kibana Feature API
Privileges
Names","number":208067,"url":"https://github.com/elastic/kibana/pull/208067","mergeCommit":{"message":"[Hardening]
Kibana Feature API Privileges Names (#208067)\n\n## Summary\r\n\r\nAs
part of our effort to harden API action definitions and
enforce\r\nstandards this PR adds an utility `ApiPrivileges`
class.\r\nIt is supposed to be used for both feature registration and
API route\r\ndefinition to construct the privilege
name.\r\n```ts\r\nplugins.features.registerKibanaFeature({\r\n
privileges: {\r\n all: {\r\n app: [...],\r\n catalogue: [...],\r\n api:
[ApiPrivileges.manage('subject_name')],\r\n ...\r\n },\r\n read: {\r\n
...\r\n api: [ApiPrivileges.read('subject_name')],\r\n ...\r\n },\r\n
},\r\n})\r\n....\r\n\r\n// route definition\r\nrouter.get(\r\n {\r\n
path: 'api_path',\r\n security: {\r\n authz: {\r\n requiredPrivileges:
[ApiPrivileges.manage('subject_name')],\r\n },\r\n },\r\n },\r\n async
(ctx, req, res) =>
{}\r\n);\r\n```\r\n\r\n`require_kibana_feature_privileges_naming` eslint
rule has been added to\r\nshow warning if the API privilege name doesn't
satisfy the naming\r\nconvention.\r\n\r\n### Naming convention\r\n\r\n-
API privilege should start with valid `ApiOperation`:
`manage`,\r\n`read`, `update`, `delete`, `create`\r\n- API privilege
should use `_` as separator\r\n\r\n `read-entity-a`\r\n
`delete_entity-a`\r\n `entity_manage`\r\n `read_entity_a`\r\n
`delete_entity_a`\r\n `manage_entity`\r\n\r\n> [!IMPORTANT] \r\n>
Serverless ZDT update scenario:\r\n>\r\n> - version N has an endpoint
protected with the `old_privilege_read`.\r\n> - version N+1 has the same
endpoint protected with a new\r\n`read_privilege`.\r\n> \r\n> There
might be a short period between the time the UI pod N+1 passes\r\nSO
migrations and updates privileges and the time it's marked
as\r\nready-to-handle-requests by k8s, and when UI pod N is
terminated.\r\n>\r\n> After discussion with @legrego and @azasypkin we
decided to ignore it\r\ndue to the perceived risk-to-cost ratio:\r\n> 1.
The time window users might be affected is very narrow because
we\r\nregister privileges late in the Kibana startup flow (e.g., after
SO\r\nmigrations).\r\n> 2. The transient 403 errors users might get
won't result in session\r\ntermination and shouldn't lead to data
loss.\r\n> 3. The roll-out will be performed in batches over the course
of\r\nmultiple weeks and implemented by different teams. This means the
impact\r\nper release shouldn't be significant.\r\n\r\n###
Checklist\r\n\r\n-
[x]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n__Relates:
https://github.com/elastic/kibana/issues/198716__\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"504510b92b0e92cbc173f0de517c506d2f54d536"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208067","number":208067,"mergeCommit":{"message":"[Hardening]
Kibana Feature API Privileges Names (#208067)\n\n## Summary\r\n\r\nAs
part of our effort to harden API action definitions and
enforce\r\nstandards this PR adds an utility `ApiPrivileges`
class.\r\nIt is supposed to be used for both feature registration and
API route\r\ndefinition to construct the privilege
name.\r\n```ts\r\nplugins.features.registerKibanaFeature({\r\n
privileges: {\r\n all: {\r\n app: [...],\r\n catalogue: [...],\r\n api:
[ApiPrivileges.manage('subject_name')],\r\n ...\r\n },\r\n read: {\r\n
...\r\n api: [ApiPrivileges.read('subject_name')],\r\n ...\r\n },\r\n
},\r\n})\r\n....\r\n\r\n// route definition\r\nrouter.get(\r\n {\r\n
path: 'api_path',\r\n security: {\r\n authz: {\r\n requiredPrivileges:
[ApiPrivileges.manage('subject_name')],\r\n },\r\n },\r\n },\r\n async
(ctx, req, res) =>
{}\r\n);\r\n```\r\n\r\n`require_kibana_feature_privileges_naming` eslint
rule has been added to\r\nshow warning if the API privilege name doesn't
satisfy the naming\r\nconvention.\r\n\r\n### Naming convention\r\n\r\n-
API privilege should start with valid `ApiOperation`:
`manage`,\r\n`read`, `update`, `delete`, `create`\r\n- API privilege
should use `_` as separator\r\n\r\n `read-entity-a`\r\n
`delete_entity-a`\r\n `entity_manage`\r\n `read_entity_a`\r\n
`delete_entity_a`\r\n `manage_entity`\r\n\r\n> [!IMPORTANT] \r\n>
Serverless ZDT update scenario:\r\n>\r\n> - version N has an endpoint
protected with the `old_privilege_read`.\r\n> - version N+1 has the same
endpoint protected with a new\r\n`read_privilege`.\r\n> \r\n> There
might be a short period between the time the UI pod N+1 passes\r\nSO
migrations and updates privileges and the time it's marked
as\r\nready-to-handle-requests by k8s, and when UI pod N is
terminated.\r\n>\r\n> After discussion with @legrego and @azasypkin we
decided to ignore it\r\ndue to the perceived risk-to-cost ratio:\r\n> 1.
The time window users might be affected is very narrow because
we\r\nregister privileges late in the Kibana startup flow (e.g., after
SO\r\nmigrations).\r\n> 2. The transient 403 errors users might get
won't result in session\r\ntermination and shouldn't lead to data
loss.\r\n> 3. The roll-out will be performed in batches over the course
of\r\nmultiple weeks and implemented by different teams. This means the
impact\r\nper release shouldn't be significant.\r\n\r\n###
Checklist\r\n\r\n-
[x]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n__Relates:
https://github.com/elastic/kibana/issues/198716__\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"504510b92b0e92cbc173f0de517c506d2f54d536"}}]}]
BACKPORT-->

Co-authored-by: Elena Shostak <165678770+elena-shostak@users.noreply.github.com>
2025-02-03 18:59:40 +01:00
..
__fixtures__ Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
helpers Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
rules [9.0] [Hardening] Kibana Feature API Privileges Names (#208067) (#209315) 2025-02-03 18:59:40 +01:00
index.js [9.0] [Hardening] Kibana Feature API Privileges Names (#208067) (#209315) 2025-02-03 18:59:40 +01:00
jest.config.js Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
kibana.jsonc Transpile packages on demand, validate all TS projects (#146212) 2022-12-22 19:00:29 -06:00
lib.js Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
package.json Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
README.mdx Harden console functions (#171367) 2024-02-09 09:13:52 -05:00

---
id: kibDevDocsOpsEslintPluginEslint
slug: /kibana-dev-docs/ops/eslint-plugin-eslint
title: "@kbn/eslint-plugin-eslint"
description: A package holding an eslint plugin with custom rules used on Kibana
date: 2022-05-17
tags: ['kibana', 'dev', 'contributor', 'operations', 'eslint', 'plugin']
---

An ESLint plugin exposing custom rules used and built specifically for development within Kibana. 
Next you can find information on each on.

## disallow-license-headers

Disallows a given group of license header texts on a group of files.

```javascript
module.exports = {
  overrides: [
    {    
      files: ['**/*.{js,mjs,ts,tsx}'],
      rules: {
        '@kbn/eslint/disallow-license-headers': [
          'error',
          {
            licenses: [
              "LICENSE_TEXT"
            ],
          },
        ],
      }
    }
  ]    
}
```

## module_migration

Offers a way to force a migration from a given node module into another as an alternative.

```javascript
module.exports = {
  overrides: [
    {    
      files: ['**/*.{js,mjs,ts,tsx}'],
      rules: {
        '@kbn/eslint/module_migration': [
          'error',
          [
            {
              from: 'expect.js',
              to: '@kbn/expect',
            }
          ],
        ],
      }
    }
  ]    
}
```

## no_async_foreach

Disallows passing an async function to .forEach which will avoid promise rejections from being handled. asyncForEach() or a similar helper from "@kbn/std" should be used instead.

## no_async_promise_body

Disallows the usage of an async function as a constructor for a Promise function without a try catch in place.

## no_constructor_args_in_property_initializers

Disallows the usage of constructor arguments into class property initializers.

## no_export_all

Disables the usage of `export *`.

## no_this_in_property_initializers

Disallows the usage of `this` into class property initializers and enforce to define the property value into the constructor.

## no_trailing_import_slash

Disables the usage of a trailing slash in a node module import.

## require-license-header

Requires a given license header text on a group of files.

```javascript
module.exports = {
  overrides: [
    {    
      files: ['**/*.{js,mjs,ts,tsx}'],
      rules: {
        '@kbn/eslint/require-license-header': [
          'error',
          {
            license: "LICENSE_TEXT"
          },
        ],
      }
    }
  ]    
}
```

## no_unsafe_console

Disables the usage of kbn-security-hardening/console/unsafeConsole.