Skip to content

fix: resolve root security during join#2827

Open
Daryna-del wants to merge 10 commits into
mainfrom
fix/resolve-root-security-in-join
Open

fix: resolve root security during join#2827
Daryna-del wants to merge 10 commits into
mainfrom
fix/resolve-root-security-in-join

Conversation

@Daryna-del
Copy link
Copy Markdown
Contributor

@Daryna-del Daryna-del commented May 20, 2026

What/Why/How?

Fixes a bug where root-level security from joined API descriptions was silently dropped in the output.

Previously, the join command ignored the security field defined at the root of each input spec. According to OpenAPI semantics, root-level security serves as a default for all operations that don't declare their own security. Simply merging root securities into the joined output would incorrectly apply one API's security to another API's operations.

Reference

Closes #1409

Testing

Screenshots (optional)

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

Note

Medium Risk
Changes how merged OpenAPI documents express authentication defaults; wrong behavior could mis-document which schemes apply to operations, though scope is limited to the join command and covered by new e2e snapshots.

Overview
Fixes join so root-level security from each input OpenAPI document is no longer dropped. Operations without their own security now get that spec’s root default (with component prefixing), including when another joined file only defines root security and no paths.

Operation-level rules are unchanged: explicit security on an operation wins; security: [] stays public and is not overridden by root defaults. New e2e cases cover both specs with root security, root-only on a paths-empty file, and operation vs root precedence.

Reviewed by Cursor Bugbot for commit 1ecab94. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

🦋 Changeset detected

Latest commit: 1ecab94

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@redocly/cli Patch
@redocly/openapi-core Patch
@redocly/respect-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

CLI Version Mean Time ± Std Dev (s) Relative Performance (Lower is Faster)
cli-latest 1.745s ± 0.022s ▓ 1.00x (Fastest)
cli-next 1.760s ± 0.028s ▓ 1.01x

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 81% (🎯 80%) 7279 / 8986
🔵 Statements 80.35% (🎯 80%) 7563 / 9412
🔵 Functions 83.96% (🎯 83%) 1456 / 1734
🔵 Branches 72.51% (🎯 72%) 4932 / 6801
File CoverageNo changed files found.
Generated in workflow #9946 for commit 1ecab94 by the Vitest Coverage Report Action

@Daryna-del
Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread packages/cli/src/commands/join/utils/get-effective-components-prefix.ts Outdated
Comment thread packages/cli/src/commands/join/utils/get-effective-components-prefix.ts Outdated
@Daryna-del
Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread tests/e2e/join/merged-root-security-from-other-apis/snapshot.txt
Comment thread packages/cli/src/commands/join/index.ts Outdated
@Daryna-del
Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread packages/cli/src/commands/join/utils/get-effective-components-prefix.ts Outdated
@Daryna-del Daryna-del force-pushed the fix/resolve-root-security-in-join branch from 5bc9605 to ecc35f1 Compare May 20, 2026 11:29
@Daryna-del Daryna-del marked this pull request as ready for review May 20, 2026 11:40
@Daryna-del Daryna-del requested review from a team as code owners May 20, 2026 11:40
Comment thread .changeset/curvy-ghosts-listen.md Outdated
Comment thread packages/cli/src/commands/join/utils/resolve-operation-security.ts Outdated
Comment thread packages/cli/src/commands/join/utils/get-effective-components-prefix.ts Outdated
Comment thread packages/cli/src/commands/join/index.ts Outdated
Copy link
Copy Markdown
Collaborator

@tatomyr tatomyr left a comment

Choose a reason for hiding this comment

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

Please also address the bugbot comments.

Comment thread packages/cli/src/commands/join/index.ts Outdated
} from '../../utils/miscellaneous.js';
import type { CommandArgs } from '../../wrapper.js';
import { COMPONENTS } from '../split/constants.js';
// import { COMPONENTS } from '../split/constants.js';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's remove comments.

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.

Fixed

},
});
}
if (!security && openapi.hasOwnProperty('security')) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why the previous solution was not working? I see it refers to the root security already.

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.

Yeah, good point. Previous solution was working for each case, except when we have paths: {} and security on root level. Simplified the solution to cover this case, please, review one more time.

Comment thread packages/cli/src/commands/join/index.ts Outdated
Comment thread packages/cli/src/commands/join/utils/collect-paths.ts Outdated
Comment thread packages/cli/src/commands/join/utils/resolve-operation-security.ts Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fc563a9. Configure here.

Comment thread packages/cli/src/commands/join/utils/collect-paths.ts Outdated
@Daryna-del Daryna-del force-pushed the fix/resolve-root-security-in-join branch from 11a4935 to 09e577e Compare May 25, 2026 11:51
200:
description: OK
400:
description: Bad request No newline at end of file
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
description: Bad request
description: Bad request

Let's add a newline on file endings.

info:
title: "spec1"
version: 1.0.0
servers:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's add only essential fields and remove others.

servers:
- url: https://api.example.com
paths:
/post:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It's bad practice to use verbs in paths (especially mixing post and get), so I'm against using it in our examples.

description: Bad request
tags:
- bar_other
security:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If I'm getting it correctly, this path comes from an API description that doesn't have security defined on it; so how it got the security requirement from another description?

authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes: {}
oauth1:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These names are hard to follow. Please use something more meaningful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

join command does not join root security

3 participants