Skip to content

[dashboards as code] only validate id on PUT route when creating new dashboard#264161

Merged
nreese merged 9 commits intoelastic:mainfrom
nreese:issue_264135
Apr 18, 2026
Merged

[dashboards as code] only validate id on PUT route when creating new dashboard#264161
nreese merged 9 commits intoelastic:mainfrom
nreese:issue_264135

Conversation

@nreese
Copy link
Copy Markdown
Contributor

@nreese nreese commented Apr 17, 2026

Closes #264135

Resolves issue by moving "as code" id validation from route to handler. Id is only validated for "create" requests. Added integration tests to verify both update and create case.

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

1 similar comment
@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 17, 2026

🟢 Good practices in this PR

Nice additions to the test coverage:

  • The new tests for invalid "as code" id behavior (both update and create paths) validate both status code and response body — following Validate the response body.
  • Proper use of minimal permissions (editor for writes, viewer for the 403 path) rather than defaulting to admin — following Test with minimal permissions.
  • Good reuse of shared fixtures (COMMON_HEADERS, KBN_ARCHIVES, apiClient) from the existing fixtures/ directory — following Use constants for shared test values.
  • Archive fixture for the (my)dashboard saved object is added to the shared archive, keeping test data declarative.

Just remove the two .only calls and this is ready to go.

Posted via Macroscope — Scout Test Review

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 17, 2026

Catch flakiness early (recommended)

Recommended before merge: run the flaky test runner against this PR to catch flakiness early.

Trigger a run with the Flaky Test Runner UI or post this comment on the PR:

/flaky scoutConfig:src/platform/plugins/shared/dashboard/test/scout/api/playwright.config.ts:30 ftrConfig:src/platform/test/api_integration/config.js:30

This check is experimental. Share your feedback in the #appex-qa channel.

Posted via Macroscope — Flaky Test Runner nudge

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

Comment thread src/platform/plugins/shared/dashboard/server/api/update/update.ts
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 17, 2026

🟡 Dropped test coverage — validation - returns 400 if panels is not an array

The previous version of this file (update_dashboard.spec.ts) included a test verifying that panels: {} (an object instead of an array) returns 400. This test was removed in the rename/restructure but not replaced.

Old test (removed):

apiTest('validation - returns 400 if panels is not an array', async ({ apiClient }) => {
  const response = await apiClient.put(`${DASHBOARD_API_PATH}/${TEST_DASHBOARD_ID}`, {
    headers: { ...COMMON_HEADERS, ...editorCredentials.apiKeyHeader },
    body: { title: 'foo', panels: {} },
    responseType: 'json',
  });
  expect(response).toHaveStatusCode(400);
});

This validated the API's schema enforcement for panels. If the removal is intentional (e.g. schema validation changed), please confirm. Otherwise, consider adding it back to upsert_dashboard.spec.ts to preserve coverage.

Ref: Validate the response body

Posted via Macroscope — Scout Test Review

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 17, 2026

🔵 Minor — Dropped validation test reduces coverage

The previous version of upsert_dashboard.spec.ts included validation - returns 400 if panels is not an array (testing panels: {} against the update endpoint). This test was removed during the reorganization but doesn't appear to be replaced by any of the new tests.

If the removal was intentional (e.g. panels validation is covered elsewhere or is no longer relevant), no action needed — but please confirm. Otherwise, consider re-adding it:

apiTest('validation - returns 400 if panels is not an array', async ({ apiClient }) => {
  const response = await apiClient.put(`${DASHBOARD_API_PATH}/${TEST_DASHBOARD_ID}`, {
    headers: {
      ...COMMON_HEADERS,
      ...editorCredentials.apiKeyHeader,
    },
    body: {
      title: 'foo',
      panels: {},
    },
    responseType: 'json',
  });

  expect(response).toHaveStatusCode(400);
});

See Validate the response body — while the original test only checked the status code, the assertion still provided valuable input-validation coverage.

Posted via Macroscope — Scout Test Review

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

If the removal was intentional (e.g. panels validation is covered elsewhere or is no longer relevant), no action needed — but please confirm. Otherwise, consider re-adding it:

Dropped "panels validation is covered elsewhere or is no longer relevant" test because it was the same as "'validation - returns 400 when body is not valid dashboard shape". We do not need a test for everything key in the dashboard schema. We need just one test that dashboard schema validates request body shape.

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Apr 17, 2026

/ci

@nreese nreese marked this pull request as ready for review April 17, 2026 21:25
@nreese nreese requested review from a team as code owners April 17, 2026 21:25
@nreese nreese added Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas t// release_note:skip Skip the PR/issue when compiling release notes labels Apr 17, 2026
@nreese nreese added backport:version Backport to applied version labels v9.4.0 v9.5.0 labels Apr 17, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

Copy link
Copy Markdown
Contributor

@Heenawter Heenawter left a comment

Choose a reason for hiding this comment

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

LGTM 👍 Changes make sense

Copy link
Copy Markdown
Contributor

@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.

left a comment about moving validation from the path to the handler that you may want to keep in mind for debugging sluggish requests.

params: schema.object({
id: asCodeIdSchema,
// Can not validate id at route level
// existing dashboards may have invalid "as code" ids
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.

FMI, what makes an "as code" id invalid? Is it not pure string type?

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.

src/platform/packages/shared/as-code/shared-schemas/src/schemas/id/id.ts

ID must contain only lowercase letters, numbers, hyphens, and underscores.


// Validate id at handler level for create requests
if (isCreateRequest) {
asCodeIdSchema.validate(id);
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.

Moving the object ID validation from the route into the handler shifts this from “fail fast at the edge” to application logic. That means invalid IDs will be rejected slightly later (a bit more server work/latency per bad request), while HTTP traffic/payload size stays the same—though high volumes of invalid/malicious requests could cost a bit more CPU. The upside is the handler can support richer, context-aware checks (e.g., authorization/ownership), not just format validation.

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.

Really no other way. At the route level, there is no way to know if the PUT request is an update or a create.

We can not have the route failing for update requests since this would make it impossible to update old dashboard with ids that are not valid for new schema. Saved object id schema allowed any character that did is allowed in a URL. We want to limit characters to only letters, numbers, hyphens, and underscores

@nreese nreese merged commit 504f0ba into elastic:main Apr 18, 2026
27 checks passed
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.4

https://github.com/elastic/kibana/actions/runs/24594190205

kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Apr 18, 2026
…dashboard (elastic#264161)

Closes elastic#264135

Resolves issue by moving "as code" id validation from route to handler.
Id is only validated for "create" requests. Added integration tests to
verify both update and create case.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 504f0ba)
kibanamachine added a commit that referenced this pull request Apr 18, 2026
…g new dashboard (#264161) (#264243)

# Backport

This will backport the following commits from `main` to `9.4`:
- [dashboards as code] only validate id on PUT route when creating new
dashboard (#264161) (504f0ba0)

<!--- Backport version: 9.6.6 -->

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

<!--BACKPORT [{"author":{"name":"Nathan
Reese","email":"reese.nathan@elastic.co"},"sourceCommit":{"committedDate":"2026-04-18T01:49:26Z","message":"[dashboards
as code] only validate id on PUT route when creating new dashboard
(#264161)\n\nCloses
https://github.com/elastic/kibana/issues/264135\n\nResolves issue by
moving \"as code\" id validation from route to handler.\nId is only
validated for \"create\" requests. Added integration tests to\nverify
both update and create case.\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"504f0ba036ff637a5ba72bd3753dbf3c13385858"},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[]}]
BACKPORT-->

Co-authored-by: Nathan Reese <reese.nathan@elastic.co>
kapral18 added a commit to kapral18/kibana that referenced this pull request Apr 19, 2026
* main: (114 commits)
  Fix observability_ai_assistant_tool_call EBT error when connector is an inference endpoint (elastic#263334)
  init on install (elastic#263732)
  [One Workflow] fail-fast TaskRecovery for interrupted runs (elastic#261275)
  [Entity Store] Reset state error after successful task run (elastic#263087)
  [api-docs] 2026-04-19 Daily api_docs build (elastic#264280)
  [UII] Fix integration card row height calculation (elastic#264212)
  [scout] migrate FTR logstash api tests (elastic#262953)
  [StorageIndexAdapter] Set auto_expand_replicas to fix yellow health on single-node ES clusters (elastic#263096)
  [api-docs] 2026-04-18 Daily api_docs build (elastic#264260)
  [Scout] Update test config manifests (elastic#264257)
  [Security Solution][Detection Engine] enables AI rule creation feature flag (elastic#264036)
  [dashboards as code] only validate id on PUT route when creating new dashboard (elastic#264161)
  chore(NA): bump version to 9.5.0 (elastic#262165)
  skip failing test suite (elastic#263649)
  skip failing test suite (elastic#264236)
  [Discover] Convert remaining Enzyme tests to RTL (elastic#259676)
  auto-implement: Labels in model endpoints table of the model details flyout look misaligned (elastic#263770)
  [ci] Promote ES docker image after verification (elastic#263890)
  [Observability:Onboarding] Remove suppress global announcements that was breaking ensemble tests (elastic#264169)
  [Cases][AttachmentV2] Migrate persistable state part 2 - ML and AIOps charts (elastic#262597)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels Project:Dashboards API release_note:skip Skip the PR/issue when compiling release notes Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas t// v9.4.0 v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[dashboards as code] only validate id on PUT route when creating new dashboard

5 participants