.agents/skills/kibana-privilege-deprecation/references/reference.md
KibanaFeatureConfig.deprecatedLocated 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.replacedByLocated 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:
all/minimal_all (or read/minimal_read). Only correct when the deprecated feature has no sub-features.{ default, minimal } form: Required when the deprecated feature has sub-features. This is because:
all = minimal_all + all sub-feature privileges with includeIn: 'all'minimal_all = only the top-level privilege, no sub-feature privilegesIf 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.replacedByLocated in x-pack/platform/plugins/shared/features/common/sub_feature.ts:
// For sub-feature privileges - only simple array form
replacedBy?: readonly FeatureKibanaPrivilegesReference[];
FeatureKibanaPrivilegesReferenceLocated 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[];
}
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 |
In elasticsearch_role.ts -> deserializeKibanaFeaturePrivileges():
replaceDeprecatedKibanaPrivileges: true (used by role management UI):
replacedBy targetsfalse (default for APIs):
In privileges.ts -> privilege computation:
capabilities.feature_beta.ui_all)In spaces_client.ts:
feature.deprecated.replacedBy (feature-level) controls which features appearsecurity.authz.requiredPrivileges continue to work with deprecated privilegesapi array to match replacement feature's entriessecurity.authz.requiredPrivileges to authorize access, covering both deprecated and replacement privilege holders