feat(core): add asyncapi-operation-security-defined lint rule#2759
feat(core): add asyncapi-operation-security-defined lint rule#2759harshit078 wants to merge 37 commits into
Conversation
🦋 Changeset detectedLatest commit: 59e91b6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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 |
vadyvas
left a comment
There was a problem hiding this comment.
I would suggest a slightly different approach:
- keep the AsyncAPI logic separate and do not reuse shared logic from the OAS rule
- use the same rule name,
security-defined, for AsyncAPI as well, and register the AsyncAPI implementation in the AsyncAPI ruleset - 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
vadyvas
left a comment
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Please add support for AsyncAPI 3 as well. Right now the rule only applies to AsyncAPI2
There was a problem hiding this comment.
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 | |||
There was a problem hiding this comment.
Please don’t add this rule to the v1 docs
| return { | ||
| ref: { | ||
| leave(node, { type, location, report }, resolved) { | ||
| if (type.name !== 'SecurityScheme') return; |
There was a problem hiding this comment.
Please, follow our visitors pattern as you did in rule for async2
| if (scheme.defined) continue; | ||
| for (const reportedFromLocation of scheme.from) { | ||
| report({ | ||
| message: `There is no \`${name}\` security scheme defined.`, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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.
| if (!isRef(item)) continue; | ||
| const itemLocation = location.child([i]); | ||
| const ref = item.$ref; | ||
| if (!ref.startsWith(COMPONENT_SCHEME_PREFIX)) { |
There was a problem hiding this comment.
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.
| "@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`. |
There was a problem hiding this comment.
Please, add in changeset AsyncAPI 3.x support.
|
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. |
|
Hey @AlbinaBlazhko17 , post your comment I understood the mistake I did for that check in the |
| if (!list) return; | ||
| for (let i = 0; i < list.length; i++) { | ||
| const item = list[i]; | ||
| if (!isRef(item)) continue; |
There was a problem hiding this comment.
Could you explain why are you skipping not refs? And the purpose of this statement item.$ref.split('/').pop()?
There was a problem hiding this comment.
-
my intent behind the skipping not refs in the logic is that since every security item can be either be a
$refor an inline object. Since inline objects are complete in itself hence there's nothing to check or cross check againstcomponents.securitySchemeshence 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 !
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>
Co-authored-by: Jacek Łękawa <164185257+JLekawa@users.noreply.github.com>

What/Why/How?
asyncapi-operation-security-definedrule for AsyncAPI 2.x which reports when a security scheme referenced from an operation or serversecurityarray is not defined in ``components.securitySchemes.Reference
#2667
Testing
Screenshots (optional)
Check yourself
Security
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 missingcomponents.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.