
Kibana Privilege Deprecation
- 4 installs
- 21.2k repo stars
- Updated August 5, 2026
- elastic/kibana
kibana-privilege-deprecation skill documents Implement and review Kibana feature privilege deprecations.
About
kibana-privilege-deprecation skill documents Implement and review Kibana feature privilege deprecations. Use when deprecating features, renaming features, splitting features, consolidating features, moving privilege capabilities, reviewing deprecation PRs, or working with the replacedBy mapping system.. name: kibana-privilege-deprecation description: Implement and review Kibana feature privilege deprecations. Use when deprecating features, renaming features, splitting features, consolidating features, moving privilege capabilities, reviewing deprecation PRs, or working with the replacedBy mapping system.
- Implement and review Kibana feature privilege deprecations.
- Platform-specific setup patterns for kibana-privilege-deprecation.
- Evidence-backed steps from upstream SKILL.md.
- When-to-use criteria for kibana-privilege-deprecation versus alternatives.
Kibana Privilege Deprecation by the numbers
- 4 all-time installs (skills.sh)
- Ranked #1,742 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
kibana-privilege-deprecation capabilities & compatibility
- Capabilities
- kibana privilege deprecation quick start · kibana privilege deprecation when to use guidanc · kibana privilege deprecation integration pattern
- Works with
- elasticsearch
- Use cases
- security audit
What kibana-privilege-deprecation says it does
Guides implementing and reviewing backward-compatible Kibana feature privilege deprecations using the deprecated privilege mapping framework.
Renaming a feature (e.g. `alpha` -> `beta`)
npx skills add https://github.com/elastic/kibana --skill kibana-privilege-deprecationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 21.2k |
| Last updated | August 5, 2026 |
| Repository | elastic/kibana ↗ |
How do I use kibana-privilege-deprecation correctly?
Implement and review Kibana feature privilege deprecations. Use when deprecating features, renaming features, splitting features, consolidating features, moving privilege capabilities, reviewing depre
Who is it for?
Teams implementing kibana-privilege-deprecation workflows from the catalog.
Skip if: Skip when requirements clearly match a different specialized stack.
When should I use this skill?
User asks about kibana-privilege-deprecation, implement and review kibana feature privilege deprecations. use when deprecating features,.
What you get
Working kibana-privilege-deprecation setup with validated configuration and next steps.
Files
Kibana Privilege Deprecation
Guides implementing and reviewing backward-compatible Kibana feature privilege deprecations using the deprecated privilege mapping framework.
When to Use
- Renaming a feature (e.g.
alpha->beta) - Splitting a feature into multiple features
- Consolidating multiple features into one
- Moving capabilities between feature/sub-feature privileges
- Reviewing PRs that deprecate features or change privilege mappings
Key Concepts
- Deprecated feature: A feature marked with
deprecatedproperty that is frozen for backward compatibility. Not shown in role management UI; privileges still registered in Elasticsearch. - `replacedBy` mapping: Links each deprecated privilege to equivalent non-deprecated privilege(s). Required on every privilege of a deprecated feature.
- Lazy migration: Roles are not auto-migrated. Deprecated privileges are replaced with current ones when an admin saves via UI.
- `kibana_system` cannot alter roles - this is a security constraint driving the entire design.
Implementation Steps
Step 1: Create new replacement feature(s)
Register new feature(s) with desired privileges using deps.features.registerKibanaFeature().
Step 2: Mark existing feature as deprecated
Add deprecated property with a user-facing notice string. Feature ID must stay unchanged.
deps.features.registerKibanaFeature({
deprecated: {
notice: i18n.translate('xpack.yourPlugin.featureDeprecationNotice', {
defaultMessage: 'Feature X is deprecated. Use Feature Y instead. See {link}.',
values: { link: 'https://...' },
}),
// Optional: override which features conceptually replace this one (for Spaces UI).
// By default derived from privilege-level replacedBy. Only needed when replacedBy
// references multiple features but you want the Spaces UI to show a subset.
replacedBy: ['feature_y'],
},
id: 'feature_x', // Must stay the same
name: 'Feature X (DEPRECATED)',
privileges: { /* keep original privileges unchanged, add replacedBy */ },
});Step 3: Define replacedBy on every privilege
Every all, read, and sub-feature privilege must have replacedBy.
Simple form -- use when the deprecated feature has NO sub-features:
privileges: {
all: {
...originalAllPrivilege,
replacedBy: [
{ feature: 'feature_y', privileges: ['all'] },
],
},
read: {
...originalReadPrivilege,
replacedBy: [
{ feature: 'feature_y', privileges: ['read'] },
],
},
}Extended `{ default, minimal }` form -- use when the deprecated feature HAS sub-features:
When a deprecated feature has sub-features, the top-level all privilege implicitly includes all sub-feature privileges granted via includeIn: 'all', while minimal_all does not. These two paths must map differently to preserve the distinction. The same applies to read / minimal_read.
privileges: {
all: {
...originalAllPrivilege,
replacedBy: {
// `default` maps `all` (= minimal_all + auto-granted sub-feature privileges)
default: [
{ feature: 'feature_y', privileges: ['all', 'sub_feature_priv_id'] },
],
// `minimal` maps `minimal_all` (= top-level only, no sub-features)
minimal: [
{ feature: 'feature_y', privileges: ['minimal_all'] },
],
},
},
read: {
...originalReadPrivilege,
replacedBy: {
default: [
{ feature: 'feature_y', privileges: ['read', 'sub_feature_priv_id'] },
],
minimal: [
{ feature: 'feature_y', privileges: ['minimal_read'] },
],
},
},
}
// Each sub-feature privilege also needs its own replacedBy (simple array form):
// replacedBy: [{ feature: 'feature_y', privileges: ['sub_feature_priv_id'] }]Rule of thumb: If the deprecated feature defines subFeatures, always use the { default, minimal } form on its top-level privileges. The simple array form is only correct when there are no sub-features (it applies the same mapping to both default and minimal).
Step 4: Update code to use new features
- API privileges: Replacement privileges must provide all API privileges from deprecated privileges. Routes use
security.authz.requiredPrivilegesfor authorization. Ensure deprecated feature'sapiarray is updated so that both deprecated and replacement privilege holders can access the same endpoints. - UI capabilities: Update client code to check
capabilities.new_feature.capabilityinstead ofcapabilities.old_feature.capability. The framework auto-maps deprecated capabilities to replacement ones. - Alerting consumers: New features must register deprecated feature ID as additional consumer so rules created under old feature remain accessible.
- Cases owners: Follow same pattern as alerting for case ownership continuity.
Validation Rules (Enforced at Startup)
Kibana will refuse to start if any of these are violated:
1. Deprecated features must define replacedBy on every privilege 2. Non-deprecated features must not define replacedBy 3. Referenced replacement features must exist and not be deprecated 4. Referenced replacement privileges must exist 5. Enabled privileges cannot be replaced with disabled ones 6. feature.deprecated.replacedBy feature IDs (if set) must be a subset of features used in privilege-level replacedBy
PR Review Checklist
When reviewing deprecation PRs, focus on what startup validation does NOT catch:
- [ ] Deprecated feature ID is unchanged from original
- [ ]
deprecated.noticeis localized (i18n.translate) with a link to docs or PR - [ ] If deprecated feature has sub-features: top-level
replacedByuses{ default, minimal }form, not simple array - [ ] Replacement privileges cover all SO types,
apientries,uicapabilities,app,catalogue, andmanagementfrom the deprecated ones - [ ] If replacement grants MORE access than deprecated, it is intentional and justified
- [ ] New features register deprecated feature ID as additional alerting consumer and cases owner
- [ ] Routes use
security.authz.requiredPrivileges; deprecated feature'sapiarray matches replacement's - [ ] Client code uses new feature ID for capability checks (e.g.
capabilities.new_feature.ui_all) - [ ] Integration tests updated; Spaces feature visibility verified
- [ ] No privilege escalation or reduction; ZDT and rollback safe
Examples
For concrete code covering all deprecation scenarios (rename, split, sub-feature extraction, consolidation, alerting/cases), read the test plugin:
x-pack/platform/test/security_api_integration/plugins/features_provider/server/index.ts
For real-world deprecations (discover, dashboard, visualize, maps):
x-pack/platform/plugins/shared/features/server/oss_features.ts
Test Files
| File | Purpose |
|---|---|
x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts | Integration tests for deprecated features |
x-pack/platform/plugins/shared/features/server/feature_registry.test.ts | Unit tests for validation |
x-pack/platform/plugins/shared/security/server/authorization/roles/elasticsearch_role.test.ts | Role deserialization tests |
Additional Resources
- For detailed type definitions and validation rules, see references/reference.md
- PoC PR: #kibana/186800
- API authorization guide:
dev_docs/key_concepts/api_authorization.mdx
Privilege Deprecation Reference
Type Definitions
KibanaFeatureConfig.deprecated
Located in x-pack/platform/plugins/shared/features/common/kibana_feature.ts:
readonly deprecated?: Readonly<{
// Mandatory, localizable, user-facing notice explaining why the feature is deprecated
// and what should be used instead. Can include links to documentation.
notice: string;
// Optional list of feature IDs that conceptually replace this deprecated feature.
// Used in Spaces feature visibility UI. By default derived from privilege-level replacedBy.
// Override when privilege replacedBy references multiple features but only a subset
// should appear in Spaces UI.
replacedBy?: readonly string[];
}>;FeatureKibanaPrivileges.replacedBy
Located in x-pack/platform/plugins/shared/features/common/feature_kibana_privileges.ts:
// For top-level privileges (all, read) - supports separate default/minimal mappings
replacedBy?:
| readonly FeatureKibanaPrivilegesReference[]
| {
default: readonly FeatureKibanaPrivilegesReference[];
minimal: readonly FeatureKibanaPrivilegesReference[];
};Two forms explained:
- Simple array form: Applies the same replacement mapping to both
all/minimal_all(orread/minimal_read). Only correct when the deprecated feature has no sub-features. - Extended `{ default, minimal }` form: Required when the deprecated feature has sub-features. This is because:
all=minimal_all+ all sub-feature privileges withincludeIn: 'all'minimal_all= only the top-level privilege, no sub-feature privileges- These two must map to different sets of replacement privileges to preserve the distinction.
If a deprecated feature has sub-features and you use the simple array form, the minimal_all mapping will incorrectly include sub-feature replacements, granting more access than intended.
SubFeaturePrivilegeConfig.replacedBy
Located in x-pack/platform/plugins/shared/features/common/sub_feature.ts:
// For sub-feature privileges - only simple array form
replacedBy?: readonly FeatureKibanaPrivilegesReference[];FeatureKibanaPrivilegesReference
Located in x-pack/platform/plugins/shared/features/common/feature_kibana_privileges_reference.ts:
export interface FeatureKibanaPrivilegesReference {
// The ID of the target (non-deprecated) feature
feature: string;
// IDs of feature or sub-feature privileges from that feature
privileges: readonly string[];
}Validation Rules
Enforced in feature_registry.ts -> validateFeatures() after all features are registered:
| Rule | Error if violated |
|---|---|
Deprecated feature must define replacedBy on every privilege | Feature "X" is deprecated and must define a "replacedBy" property for privilege "Y" |
Non-deprecated feature must NOT define replacedBy | Feature "X" is not deprecated and must not define a "replacedBy" property for privilege "Y" |
| Referenced replacement feature must exist | Cannot replace privilege "Y" of deprecated feature "X" with privileges of feature "Z" since such feature is not registered |
| Referenced replacement feature must not be deprecated | ...since the referenced feature is deprecated |
| Referenced replacement privileges must exist | ...since such privilege is not registered |
| Cannot replace enabled privilege with disabled one | Cannot replace privilege "Y" of deprecated feature "X" with disabled privilege "Z" of feature "W" |
feature.deprecated.replacedBy must be non-empty if set | ...must have at least one feature ID |
feature.deprecated.replacedBy IDs must be used in privilege replacedBy | ...aren't used to replace feature privileges |
How Deprecated Privileges Work at Runtime
Elasticsearch Registration
- Deprecated features' privileges are still registered as Elasticsearch application privileges
- Users with roles referencing deprecated privileges continue to pass authorization checks
- No automatic role migration occurs
Role Deserialization (UI)
In elasticsearch_role.ts -> deserializeKibanaFeaturePrivileges(): 1. When replaceDeprecatedKibanaPrivileges: true (used by role management UI):
- Deprecated privileges are resolved to their
replacedBytargets - Only replacement privileges appear in the deserialized role
2. When false (default for APIs):
- Deprecated privileges remain as-is in the role
UI Capabilities
In privileges.ts -> privilege computation:
- Deprecated privileges generate UI actions from both the deprecated feature and its replacement features
- Client code should check replacement feature capabilities (e.g.
capabilities.feature_beta.ui_all) - Works for users with either deprecated or replacement privileges
Spaces Feature Visibility
In spaces_client.ts:
- Deprecated features are excluded from enabled/disabled feature lists
- Replacement features are shown instead
feature.deprecated.replacedBy(feature-level) controls which features appear
API Authorization
- Routes using
security.authz.requiredPrivilegescontinue to work with deprecated privileges - API privileges from deprecated features remain valid in Elasticsearch
- When changing privilege names: update deprecated feature's
apiarray to match replacement feature's entries - Routes must use
security.authz.requiredPrivilegesto authorize access, covering both deprecated and replacement privilege holders
Role Management APIs
- Deprecated privileges are still accepted in create/update role API requests
- This maintains backward compatibility for automation built around role APIs
- Deprecation warnings may be surfaced in future API responses
Related skills
FAQ
What does kibana-privilege-deprecation do?
kibana-privilege-deprecation skill documents Implement and review Kibana feature privilege deprecations.
When should I use kibana-privilege-deprecation?
User asks about kibana-privilege-deprecation, implement and review kibana feature privilege deprecations. use when deprecating features,.
Is this skill safe to install?
Review the Security Audits panel on this page before installing in production.