Skip to content

feat(core): add asyncapi-operation-security-defined lint rule#2759

Open
harshit078 wants to merge 37 commits into
Redocly:mainfrom
harshit078:add-asyncapi-rule
Open

feat(core): add asyncapi-operation-security-defined lint rule#2759
harshit078 wants to merge 37 commits into
Redocly:mainfrom
harshit078:add-asyncapi-rule

Conversation

@harshit078
Copy link
Copy Markdown
Contributor

@harshit078 harshit078 commented Apr 21, 2026

What/Why/How?

  • Added asyncapi-operation-security-defined rule for AsyncAPI 2.x which reports when a security scheme referenced from an operation or server security array is not defined in ``components.securitySchemes.

Reference

#2667

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
Adds a new built-in lint rule and enables it in default AsyncAPI rulesets, which can introduce new lint failures for existing AsyncAPI specs and affects core linting behavior.

Overview
Adds a new AsyncAPI built-in rule, security-defined, for both AsyncAPI 2.6 and AsyncAPI 3.0 to flag operations/servers that reference missing components.securitySchemes (and, for 3.0, $refs that don’t point into #/components/securitySchemes).

Wires the rule into the AsyncAPI rule registries and default configs (recommended, recommended-strict, minimal, all, spec), updates config resolver snapshots, and adds dedicated unit tests plus documentation/sidebars and a changeset bump.

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 21, 2026

🦋 Changeset detected

Latest commit: 59e91b6

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

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

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

@harshit078 harshit078 changed the title feat: Add asyncapi-operation-security-defined lint rule feat(core): Add asyncapi-operation-security-defined lint rule Apr 24, 2026
@harshit078 harshit078 marked this pull request as ready for review April 24, 2026 07:51
@harshit078 harshit078 requested review from a team as code owners April 24, 2026 07:51
@harshit078 harshit078 changed the title feat(core): Add asyncapi-operation-security-defined lint rule feat(core): add asyncapi-operation-security-defined lint rule Apr 24, 2026
Copy link
Copy Markdown
Contributor

@vadyvas vadyvas left a comment

Choose a reason for hiding this comment

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

I would suggest a slightly different approach:

  1. keep the AsyncAPI logic separate and do not reuse shared logic from the OAS rule
  2. use the same rule name, security-defined, for AsyncAPI as well, and register the AsyncAPI implementation in the AsyncAPI ruleset
  3. do not update the v1 docs in this PR

I think this would make the change smaller, clearer, and safer.

Thank you for the contribution, overall the PR looks good

Comment thread packages/core/src/rules/async2/asyncapi-operation-security-defined.ts Outdated
Comment thread packages/core/src/rules/common/security-scheme-references.ts Outdated
Comment thread packages/core/src/rules/async2/index.ts Outdated
Comment thread docs/@v1/guides/lint-asyncapi.md Outdated
Comment thread packages/core/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap Outdated
@harshit078 harshit078 requested a review from vadyvas April 30, 2026 12:45
Copy link
Copy Markdown
Contributor

@vadyvas vadyvas 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 few comments, could you take a look?

'info-contact': InfoContact as Async2Rule,
'info-license-strict': InfoLicenseStrict as Async2Rule,
'operation-operationId': OperationOperationId as Async2Rule,
'security-defined': SecurityDefined,
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.

Please add support for AsyncAPI 3 as well. Right now the rule only applies to AsyncAPI2

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.

okay sure !

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 code uses the rule name security-defined, but the docs still say asyncapi-operation-security-defined
Can you update related changes?

@@ -0,0 +1,83 @@
# asyncapi-operation-security-defined
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.

Please don’t add this rule to the v1 docs

Comment thread docs/@v1/v1.sidebars.yaml Outdated
Comment thread packages/core/src/rules/async2/index.ts
return {
ref: {
leave(node, { type, location, report }, resolved) {
if (type.name !== 'SecurityScheme') return;
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.

Please, follow our visitors pattern as you did in rule for async2

Comment thread .changeset/stupid-dryers-add.md Outdated
if (scheme.defined) continue;
for (const reportedFromLocation of scheme.from) {
report({
message: `There is no \`${name}\` security scheme defined.`,
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 think we should align these rules with the existing OpenAPI; in other words, we need to report if any operation doesn't have a security defined

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 1c4f368. Configure here.

Comment thread packages/core/src/rules/async3/security-defined.ts Outdated
if (!isRef(item)) continue;
const itemLocation = location.child([i]);
const ref = item.$ref;
if (!ref.startsWith(COMPONENT_SCHEME_PREFIX)) {
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.

Please, avoid using this type of check, because it will cause issues in future. e.g. other.yaml#/components/securitySchemes/jwt will be rejected. Try to track defined schemes by their location.absolutePointer and in SecuritySchemeList resolve each ref and compare absolute pointers.

Comment thread .changeset/stupid-dryers-add.md Outdated
"@redocly/openapi-core": minor
---

Added `security-defined` rule for AsyncAPI 2.x that reports when a security scheme referenced from an operation or server `security` array is not defined in `components.securitySchemes`.
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.

Please, add in changeset AsyncAPI 3.x support.

@AlbinaBlazhko17
Copy link
Copy Markdown
Contributor

Thanks @harshit078 for your patience. Almost there. My biggest concern is based on AsyncAPI v3 rule and manually checking ref locations, i left comment regarding it.

@harshit078
Copy link
Copy Markdown
Contributor Author

Hey @AlbinaBlazhko17 , post your comment I understood the mistake I did for that check in the async3 security defined. I have pushed a fix addressing it. Thanks !

if (!list) return;
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (!isRef(item)) continue;
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.

Could you explain why are you skipping not refs? And the purpose of this statement item.$ref.split('/').pop()?

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.

  • my intent behind the skipping not refs in the logic is that since every security item can be either be a $ref or an inline object. Since inline objects are complete in itself hence there's nothing to check or cross check against components.securitySchemes hence only $ref items can be tracked as references.

  • The purpose of tthis statement is that it basically just grabs the last pointer segment purely as a display name in the "There is no name security scheme defined." message which matches with the async2 wording.

I hope my explanation did a justice to what I was trying to say. If not, I'm happy to provide further explanation. Thanks !

Comment thread .changeset/stupid-dryers-add.md Outdated
harshit078 and others added 2 commits May 20, 2026 15:59
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Comment thread docs/@v2/rules/async/security-defined.md Outdated
Comment thread docs/@v2/rules/async/security-defined.md Outdated
harshit078 and others added 2 commits May 20, 2026 19:13
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Comment thread docs/@v2/rules/async/security-defined.md Outdated
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.

4 participants