Skip to content

Simplify OAS schema for GET /api/spaces/space query params#260831

Merged
TinaHeiligers merged 12 commits intoelastic:mainfrom
TinaHeiligers:fix/oas-spaces-include-authorized-purposes
Apr 14, 2026
Merged

Simplify OAS schema for GET /api/spaces/space query params#260831
TinaHeiligers merged 12 commits intoelastic:mainfrom
TinaHeiligers:fix/oas-spaces-include-authorized-purposes

Conversation

@TinaHeiligers
Copy link
Copy Markdown
Contributor

@TinaHeiligers TinaHeiligers commented Apr 1, 2026

Summary

The GET /api/spaces/space include_authorized_purposes schema.conditional falls back to anyOf(array, boolean, number, object, string) and is hard for API consumers to interpret that it accepts a boolean.

This PR siplifies the schema.conditional to schema.maybe(schema.boolean()), generating a clean { type: "boolean" } in the OAS.

The runtime cross-field constraint (include_authorized_purposes can only be false when purpose is set) is preserved by using a new object-level validate function.

Schema change, not a behavior change — same valid/invalid requests, same HTTP status codes, clearer error message. Also removes the need for fixGetSpacesParams in terraform-provider-elasticstack.

Relates to #228077.

Details

  • spaces code changed is get_all.ts (route definition) and get_all.test.ts (updated error message assertion)
  • schema.conditional used Joi's when to conditionally restrict include_authorized_purposes to false when purpose is set. The object-level validate function preserves this exact constraint.
  • allowlist entry is only for the change to the OAS. There's no runtime behavior change — the same requests that were valid before are still valid, and the same ones that were rejected are still rejected (just with a clearer error message)
  • The terraform-provider-elasticstack fixGetSpacesParams transform (which just deletes the degenerate anyOf) becomes a no-op after this change
How to test this
  1. Run unit tests:

    node scripts/jest x-pack/platform/plugins/shared/spaces/server/routes/api/external/get_all.test.ts
    

    All 13 tests should pass, including the cross-field validation test (purpose + include_authorized_purposes=true → error).

  2. Run full spaces unit suite:

    yarn test:jest --config x-pack/platform/plugins/shared/spaces/jest.config.js
    

    All 642 tests pass.

  3. Verify OAS output: regenerate the snapshot with node scripts/capture_oas_snapshot --include-path /api/spaces, then check include_authorized_purposes in oas_docs/bundle.json — should be {type: "boolean", required: false} with no anyOf/oneOf.

  4. Run spaces API integration tests:

    node scripts/functional_tests_server --config x-pack/platform/test/spaces_api_integration/deployment_agnostic/spaces_only/config.ts
    node scripts/functional_test_runner --config x-pack/platform/test/spaces_api_integration/deployment_agnostic/spaces_only/config.ts
    

    115 passing. Then for security_and_spaces:

    node scripts/functional_tests_server --config x-pack/platform/test/spaces_api_integration/deployment_agnostic/security_and_spaces/stateful.config_basic.ts
    node scripts/functional_test_runner --config x-pack/platform/test/spaces_api_integration/deployment_agnostic/security_and_spaces/stateful.config_basic.ts
    

    611 passing. Cross-field validation still works end-to-end.

Checklist

  • Unit or functional tests were updated or added to match the most common scenarios
  • Documentation was added for features that require explanation or tutorials
  • 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.
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines

Identify risks

This is a low-risk change scoped to OAS output improvement — no runtime behavior change, no API contract change, no data model change.

Risk Severity Likelihood Mitigation
Cross-field validation semantics change Low None The object-level validate preserves the exact same constraint: when purpose is set, include_authorized_purposes can only be false. Verified via unit tests and API integration tests (726 tests total).
Error message text change Low Low The error message changed from [include_authorized_purposes]: expected value to equal [false] to include_authorized_purposes can only be false when purpose is specified. HTTP status (400) is unchanged. Downstream consumers checking exact error text would need updating, but this is an improvement in clarity.
Downstream codegen breakage (TF provider) Low None observed The fixGetSpacesParams transform already deletes the anyOf — removing the anyOf at source means the transform becomes a no-op. No negative impact.

Co-Authored-By: Claude Opus 4.6

@TinaHeiligers TinaHeiligers added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting Feature:OAS Work or issues related to Core-provided mechanisms for generating OAS Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t// Feature:Security/Spaces Platform Security - Spaces feature and removed Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// labels Apr 1, 2026
),
},
{
validate: (value) => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

preserves runtime validation

Comment thread x-pack/platform/plugins/shared/spaces/server/routes/api/external/get_all.ts Outdated
Copy link
Copy Markdown
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

self review

@TinaHeiligers TinaHeiligers marked this pull request as ready for review April 1, 2026 22:56
@TinaHeiligers TinaHeiligers requested a review from a team as a code owner April 1, 2026 22:56
@TinaHeiligers TinaHeiligers requested a review from azasypkin April 1, 2026 22:56
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-security (Team:Security)

@elastic-vault-github-plugin-prod elastic-vault-github-plugin-prod Bot requested a review from a team as a code owner April 1, 2026 23:23
@TinaHeiligers TinaHeiligers requested a review from a team as a code owner April 2, 2026 02:33
@TinaHeiligers TinaHeiligers changed the title Replace schema.conditional with schema.maybe(schema.boolean()) for spaces include_authorized_purposes Improve OAS schema for spaces Apr 2, 2026
@TinaHeiligers TinaHeiligers changed the title Improve OAS schema for spaces Simplify OAS schema for GET /api/spaces/space query params Apr 2, 2026
Copy link
Copy Markdown
Member

@florent-leborgne florent-leborgne left a comment

Choose a reason for hiding this comment

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

LGTM for docs

Comment thread x-pack/platform/plugins/shared/spaces/server/routes/api/external/get_all.ts Outdated
…al/get_all.ts

Co-authored-by: Florent LB <florent.leborgne@elastic.co>
Copy link
Copy Markdown
Contributor Author

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

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

fix typo

Comment thread x-pack/platform/plugins/shared/spaces/server/routes/api/external/get_all.ts Outdated
@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

meta: {
description:
'Specifies which authorization checks are applied to the API call. The default value is `any`.',
'When enabled, the API returns any spaces the user is authorized to access in any capacity, each including the purposes for which the user is authorized. This is useful for identifying spaces the user can read but is not authorized for a given purpose. Without the security plugin, this parameter has no effect, because no authorization checks are performed. This parameter cannot be used together with the `purpose` parameter.',
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.

optional nit: Maybe it's just me but "Without the security plugin" sounds a bit ambiguous comparing to the "If the security plugin is not enabled" we had before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The description comes directly from what it was before, I didn't add it. Once this PR lands, we can change it to whatever you like

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.

Am I misreading this?

before:

When enabled, the API returns any spaces that the user is authorized to access in any capacity and each space will contain the purposes for which the user is authorized. This can be useful to determine which spaces a user can read but not take a specific action in. If the security plugin is not enabled, this parameter has no effect, since no authorization checks take place. This parameter cannot be used in with the purpose parameter.

after:

When enabled, the API returns any spaces the user is authorized to access in any capacity, each including the purposes for which the user is authorized. This is useful for identifying spaces the user can read but is not authorized for a given purpose. Without the security plugin, this parameter has no effect, because no authorization checks are performed. This parameter cannot be used together with the purpose parameter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

nope, you're absolutely correct.

@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Apr 13, 2026

💔 Build Failed

Failed CI Steps

Metrics [docs]

✅ unchanged

History

@TinaHeiligers
Copy link
Copy Markdown
Contributor Author

@elasticmachine merge upstream

@TinaHeiligers TinaHeiligers merged commit 1222618 into elastic:main Apr 14, 2026
17 checks passed
mbondyra added a commit to mbondyra/kibana that referenced this pull request Apr 14, 2026
* commit '11ed3645c5ededae2a6e29f2a79b31f52208b441': (157 commits)
  remove sync register uiAction methods (elastic#254590)
  [performance] Apply minimal auth to the search route (elastic#257497)
  [ES|QL] Reports correctly the controls server side errors (elastic#263020)
  [SecuritySolution][Navigation] Enable classic nav updates (elastic#262358)
  [Inference] Use pretty name and logo on feature settings page (elastic#262531)
  [Security Solution] fix AT-AB cypress test (elastic#262991)
  [SigEvents] Seed sigevents env script (elastic#261172)
  Adjust conditions for validating no refetch for expanded row (elastic#262978)
  [Agent Builder] update copy for the announcement modal (elastic#263034)
  [Search] Hide index management links for users without privileges (elastic#262627)
  Simplify OAS schema for GET `/api/spaces/space` query params (elastic#260831)
  Fix fleet output OAS regressions: SSL type explosion and Kafka union wrappers (elastic#260842)
  [Dashboards in chat] fix agent confusing the axes in a horizontal chat (elastic#263064)
  [One Workflow] Add alert state checkbox UI for workflow connector (elastic#259770)
  [One Workflow] Deprecate legacy Cases step types in workflow authoring (elastic#262070)
  skip failing test suite (elastic#248090)
  fix flaky test: MonitorDetails filter apply button not enabled (elastic#260788)
  fix: propagate AbortSignal to executeAsReasoningAgent for task cancellation (elastic#262811)
  [Security Solution][Alert KPI] Fix white space bug in alert KPIs (elastic#260803)
  [Streams] Move helpers and format_size_unit to utils folder (elastic#262550)
  ...

# Conflicts:
#	x-pack/platform/plugins/shared/dashboard_agent/public/attachment_types/canvas_integration/dashboard_canvas_content.test.tsx
#	x-pack/platform/plugins/shared/dashboard_agent/public/attachment_types/canvas_integration/dashboard_canvas_content.tsx
#	x-pack/platform/plugins/shared/dashboard_agent/public/attachment_types/canvas_integration/use_register_canvas_action_buttons.ts
#	x-pack/platform/plugins/shared/dashboard_agent/public/attachment_types/index.test.tsx
#	x-pack/platform/plugins/shared/dashboard_agent/public/attachment_types/index.tsx
@TinaHeiligers TinaHeiligers self-assigned this Apr 24, 2026
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 Feature:OAS Work or issues related to Core-provided mechanisms for generating OAS Feature:Security/Spaces Platform Security - Spaces feature release_note:skip Skip the PR/issue when compiling release notes Team:Security Platform Security: Auth, Users, Roles, Spaces, Audit Logging, etc t// v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants