Skip to content

[Fleet] Add UI for integration namespace customization#269141

Merged
jillguyonnet merged 11 commits into
elastic:mainfrom
jillguyonnet:fleet/264065-integration-namespace-ui
May 19, 2026
Merged

[Fleet] Add UI for integration namespace customization#269141
jillguyonnet merged 11 commits into
elastic:mainfrom
jillguyonnet:fleet/264065-integration-namespace-ui

Conversation

@jillguyonnet
Copy link
Copy Markdown
Member

@jillguyonnet jillguyonnet commented May 13, 2026

Summary

Closes #264065

This PR adds the following UI:

  • Input for managing namespaces enabled for customization for a given package in the package's Settings tab
  • Toggle for enabling/disabling a namespace for customization when creating/editing a package policy

Note: release notes are included in #262568

Testing

  1. Set up some allowed namespace prefixes for the space, e.g.:
    PUT kbn:/api/fleet/space_settings
    {
        "allowed_namespace_prefixes": ["prod", "qa"]
    }
    
  2. Integration detail Settings tab
    • Pick an integration (e.g. System)
    • Check that the "Namespace customization" section is not rendered
    • Install the integration
    • The "Namespace customization" section should be rendered
    • Try to add a namespace that doesn't match the allowed prefixes (e.g. staging): it should be rejected
    • Add a namespace that matches the allowed prefixes (e.g. prod1): it should be allowed and a toast notification should confirm
    • Check that the namespace was correctly opted in via API (GET /api/fleet/epm/packages/<pkg>, installationInfo.namespace_customization_enabled_for)
    • Also test namespace opt out
  3. Package policy editor (create flow)
    • Create a package policy (add the integration)
    • Open "Advanced options": there should be a toggle labelled "Enable namespace-level customization" that defaults to disabled
    • Add a namespace that matches the allowed prefixes and is not already opted in (e.g. prod2), enable the toggle: after saving the policy, this namespace should be added to the list of opted in namespaces for this package
    • Create another package policy with the same namespace (prod2), but this time leave the toggle disabled: there should be a warning that doing this will opt out the namespace, affecting the previously created package policy
    • Create another package policy with a namespace that is not opted in (e.g. prod3), leave the toggle disabled
    • Create another package policy with the same namespace (prod3) and enable the toggle: there should be a warning that doing this will opt in the namespace, affecting the previously created package policy
  4. Package policy editor (edit flow)
    • For integration packages, it should be possible to change the namespace and whether it is opted in for the package
    • For input packages, the namespace cannot be changed after creation but it should be possible to change whether it is opted in for the package

Screenshots

Screenshot 2026-05-13 at 15 52 26 Screenshot 2026-05-13 at 15 53 19 Screenshot 2026-05-13 at 15 55 11 Screenshot 2026-05-13 at 15 55 36 Screenshot 2026-05-13 at 15 56 02

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

Identify risks

Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss.

Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging.

@jillguyonnet jillguyonnet self-assigned this May 13, 2026
@jillguyonnet jillguyonnet added Team:Fleet Team label for Observability Data Collection Fleet team release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting labels May 13, 2026
@jillguyonnet jillguyonnet marked this pull request as ready for review May 13, 2026 15:51
@jillguyonnet jillguyonnet requested a review from a team as a code owner May 13, 2026 15:51
@infra-vault-gh-plugin-prod
Copy link
Copy Markdown

Pinging @elastic/fleet (Team:Fleet)

Comment on lines +36 to +48
@@ -42,7 +45,7 @@ export function isValidNamespace(
defaultMessage:
'Namespace should start with one of these prefixes {allowedNamespacePrefixes}',
values: {
allowedNamespacePrefixes: allowedNamespacePrefixes?.join(', ') ?? '',
allowedNamespacePrefixes: allowedNamespacePrefixes.join(', '),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be collapse into 1 token:

i18n.translate('xpack.fleet.namespaceValidation.notAllowedPrefixError', {
  defaultMessage:
    'Namespace should start with {count, plural, one {{allowedNamespacePrefixes}} other {one of these prefixes: {allowedNamespacePrefixes}}}',
  values: {
    count: allowedNamespacePrefixes.length,
    allowedNamespacePrefixes:
      allowedNamespacePrefixes.length === 1
        ? allowedNamespacePrefixes[0]
        : allowedNamespacePrefixes.join(', '),
  },
})

Comment on lines +258 to +259
// Case 3: toggle on + namespace not yet opted in → opting in may affect others
// Case 8: toggle off + namespace already opted in → opting out may affect others
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's "case 3" and "case 8"? (they are referenced in conditions further in this file too)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, forgot to clean those up! Thanks for flagging

@@ -204,6 +221,58 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{
// Output is also disabled when any parent agent policy is managed (e.g. Elastic Cloud Agent Policy).
const isOutputDisabled = isManaged || agentPolicies?.some((p) => p.is_managed) === true;

// Namespace-level customization toggle visibility/state.
const showNamespaceCustomizationToggle =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we are adding a good amount of state related to namespace customization (plus data fetching), i wonder if all of it could be extracted to a separate hook?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, done 👍

namespaceCustomizationEnabled={namespaceCustomizationEnabled}
onNamespaceCustomizationEnabledChange={setNamespaceCustomizationEnabled}
installedNamespaceCustomizationEnabledFor={installedNamespaceCustomizationEnabledFor}
allowedNamespacePrefixes={spaceSettings?.allowedNamespacePrefixes ?? []}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid passing 4 new props at this level? can all these be calculated in StepDefinePackagePolicy itself? (might be related to my hook comment earlier)

/>
</h4>
</EuiTitle>
<EuiSpacer size="s" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the spacing here could be tightened up (I think EuiTitle already enforce some bottom margin)

<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.integrations.settings.namespaceCustomization.description"
defaultMessage="Opt in namespaces to apply namespace-level customization for this integration. Fleet will create dedicated index templates for each opted-in namespace."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the phrasing "namespace-level customization" confusing on this page. @vishaangelova can probably help wordsmith this but here are some ideas:

title: Namespace index templates

input label: Namespaces with dedicated index templates

description: Select which namespaces get a dedicated index template for this integration. This enables independent customization of settings and mappings per namespace. Learn more.

learn more link would go to https://www.elastic.co/docs/reference/fleet/data-streams - we'll need to update the docs here (has a docs issue been filed?)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yes, you have a point. I remember I previously approved the "namespace-level customization” wording for the API docs, but I think this is more user-friendly. I’d go with your suggestions, with a tiny tweak for this sentence:

Select which namespaces use a dedicated index template for this integration.

<EuiText size="xs" color="subdued">
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.helpText"
defaultMessage="Allows applying customized settings to all data streams in that namespace."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to my other copy sugggestion, maybe something like this:

Creates a dedicated index template for this namespace, enabling independent settings and mappings from other namespaces.

cc @vishaangelova

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand this part:

enabling independent settings and mappings from other namespaces.

Might need to think a bit more on the wording here.

>
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.optInImpactDescription"
defaultMessage="Namespace-level customization is shared across all {packageTitle} integration policies targeting namespace {namespace}. Enabling it here will apply to all of them."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

related to previous copy suggestion:
The namespace index template is shared across all {packageTitle} policies targeting namespace {namespace}. Enabling it here will apply to all of them.

cc @vishaangelova

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To better link the toggle switch and the two sentences, perhaps:

The namespace index template is shared across all {packageTitle} integration policies targeting namespace {namespace}. Enabling the customization here will apply it to all of them.

By "apply it” I mean the namespace index template. Not sure if I’ve understood this correctly. (Do we need to explicitly say “it will apply the template”?)

>
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.optOutImpactDescription"
defaultMessage="Namespace-level customization is shared across all {packageTitle} integration policies targeting namespace {namespace}. Disabling it here will remove it from all of them."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

related to previous copy suggestion:
The namespace index template is shared across all {packageTitle} policies targeting namespace {namespace}. Disabling it here will remove it from all of them.

cc @vishaangelova

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To better link the toggle switch and the two sentences, perhaps:

The namespace index template is shared across all {packageTitle} integration policies targeting namespace {namespace}. Disabling the customization here will remove it from all of them.

By “remove it” I mean the namespace index template. Not sure if I’ve understood this correctly. (Do we need to explicitly say “will remove the template”?)

<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.integrations.settings.namespaceCustomization.description"
defaultMessage="Opt in namespaces to apply namespace-level customization for this integration. Fleet will create dedicated index templates for each opted-in namespace."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yes, you have a point. I remember I previously approved the "namespace-level customization” wording for the API docs, but I think this is more user-friendly. I’d go with your suggestions, with a tiny tweak for this sentence:

Select which namespaces use a dedicated index template for this integration.

<EuiFlexItem grow={false}>
<FormattedMessage
id="xpack.fleet.integrations.settings.namespaceCustomization.applying"
defaultMessage="Applying namespace customization changes…"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use Jen’s wording, maybe this could be Applying namespace index template changes…?

<EuiText size="xs" color="subdued">
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.helpText"
defaultMessage="Allows applying customized settings to all data streams in that namespace."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand this part:

enabling independent settings and mappings from other namespaces.

Might need to think a bit more on the wording here.

>
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.optOutImpactDescription"
defaultMessage="Namespace-level customization is shared across all {packageTitle} integration policies targeting namespace {namespace}. Disabling it here will remove it from all of them."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To better link the toggle switch and the two sentences, perhaps:

The namespace index template is shared across all {packageTitle} integration policies targeting namespace {namespace}. Disabling the customization here will remove it from all of them.

By “remove it” I mean the namespace index template. Not sure if I’ve understood this correctly. (Do we need to explicitly say “will remove the template”?)

>
<FormattedMessage
id="xpack.fleet.createPackagePolicy.namespaceCustomization.optInImpactDescription"
defaultMessage="Namespace-level customization is shared across all {packageTitle} integration policies targeting namespace {namespace}. Enabling it here will apply to all of them."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To better link the toggle switch and the two sentences, perhaps:

The namespace index template is shared across all {packageTitle} integration policies targeting namespace {namespace}. Enabling the customization here will apply it to all of them.

By "apply it” I mean the namespace index template. Not sure if I’ve understood this correctly. (Do we need to explicitly say “it will apply the template”?)

@jillguyonnet
Copy link
Copy Markdown
Member Author

Thank you @jen-huang and @vishaangelova for your review 🙏

Good point regarding the texts 👍 I pushed some changes, but it might need another round. Comments below to try to keep them centralized.

1. Integration settings:

  • I really like your suggestion for the help text (also fixed the formatting a bit), added as is.
  • I still like "Namespace customization" for the section title though, I feel like it conveys the general intent of the feature (that a user would seek). "Namespace index templates" is more precise, but that is already described in the help text. WDYT?
  • Body of the success notification: I don't have strong feelings about this one, added your suggestion.
Screenshot 2026-05-15 at 16 04 11

2. Package policy editor:

  • Toggle label: I noticed an inconsistency with the integration settings page: "namespace customization" vs. "namespace-level customization". I prefer the former. Thoughts?
  • Warning callout when existing package policies may be affected:
    • Title: same consideration as above, I like "namespace customization" for consistency
    • Body: I like your suggestion, added
  • Success notification
    • Title: left as "Namespace customization updated", let me know if that seems unclear
    • Body: updated per your suggestion
Screenshot 2026-05-15 at 16 00 41 Screenshot 2026-05-15 at 16 01 48 Screenshot 2026-05-15 at 16 05 38

3. "Learn more" link: I also thought that would be necessary, but I'm not sure we have a link yet? @vishaangelova maybe let's clarify this directly.

@jen-huang
Copy link
Copy Markdown
Contributor

I still like "Namespace customization" for the section title though, I feel like it conveys the general intent of the feature (that a user would seek). "Namespace index templates" is more precise, but that is already described in the help text. WDYT?

Toggle label: I noticed an inconsistency with the integration settings page: "namespace customization" vs. "namespace-level customization". I prefer the former. Thoughts?

We do not surface the concept of applying settings & mapping at different levels as "customization" anywhere in Fleet. We do already introduce users to the fact that @custom component templates are surfaced at different levels.

My point is that this feature ties in with how Fleet handles templating for integration data streams: we introduce another level, and customization from that point forward is implied.

Namespace customization is vague. To me, it reads as just being able to change the integration's namespace.

"Learn more" link: I also thought that would be necessary, but I'm not sure we have a link yet? @vishaangelova maybe let's clarify this directly.

It should link to https://www.elastic.co/docs/reference/fleet/data-streams which will need to be updated. This is the same docs page that the current Data retention settings info blurb links to:

image

We still have UX improvement to do on conveying to the user all the levels in which they can customize their data streams, but one step at a time.. 😉

@jillguyonnet
Copy link
Copy Markdown
Member Author

@elasticmachine merge upstream

@jillguyonnet
Copy link
Copy Markdown
Member Author

Thanks Jen for the added context, it makes sense 👍 I've updated the strings per screenshots below, please review.

Screenshot 2026-05-18 at 12 50 35 Screenshot 2026-05-18 at 12 50 47 Screenshot 2026-05-18 at 12 52 11 Screenshot 2026-05-18 at 12 52 47

@jillguyonnet
Copy link
Copy Markdown
Member Author

@vishaangelova FYI I opened elastic/docs-content#6545 to track the documentation change

Copy link
Copy Markdown
Member

@vishaangelova vishaangelova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jillguyonnet! Copy LGTM!

@kibanamachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
fleet 2141 2145 +4

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
fleet 2.7MB 2.8MB +12.1KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
fleet 204.7KB 204.8KB +13.0B

History

cc @jillguyonnet

@jen-huang jen-huang self-requested a review May 18, 2026 18:55
Copy link
Copy Markdown
Contributor

@jen-huang jen-huang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the discussion & changes! LGTM 🚀

@jillguyonnet jillguyonnet merged commit decba43 into elastic:main May 19, 2026
32 checks passed
@jillguyonnet jillguyonnet deleted the fleet/264065-integration-namespace-ui branch May 19, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Fleet Team label for Observability Data Collection Fleet team v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fleet] UI for integration namespace level customization

5 participants