diff --git a/catalyst-gateway/.spectral.yml b/catalyst-gateway/.spectral.yml new file mode 100644 index 00000000000..8a8c366e86b --- /dev/null +++ b/catalyst-gateway/.spectral.yml @@ -0,0 +1,122 @@ +# References to the rules +# OpenAPI: https://docs.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules#openapi-rules +# OWASP Top 10: https://github.com/stoplightio/spectral-owasp-ruleset/blob/v1.4.3/src/ruleset.ts +# Documentations: https://github.com/stoplightio/spectral-documentation/blob/v1.3.1/src/ruleset.ts + +# cspell: words OWASP owasp Baction Baccount + +# Use CDN hosted version for spectral-documentation and spectral-owasp +extends: +- 'spectral:oas' +- 'https://unpkg.com/@stoplight/spectral-documentation@1.3.1/dist/ruleset.mjs' +- 'https://unpkg.com/@stoplight/spectral-owasp-ruleset@1.4.3/dist/ruleset.mjs' + +aliases: + PathItem: + - $.paths[*] + OperationObject: + - $.paths[*][get,put,post,delete,options,head,patch,trace] + DescribableObjects: + - $.info + - $.tags[*] + - '#OperationObject' + - '#OperationObject.responses[*]' + - '#PathItem.parameters[?(@ && @.in)]' + - '#OperationObject.parameters[?(@ && @.in)]' + +overrides: +- files: ['*'] + rules: + # Override document description rule + # - No limitations on the characters that can start or end a sentence. + # - Length should be >= 20 characters + # Ref: https://github.com/stoplightio/spectral-documentation/blob/a34ca1b49cbd1ac5a75cfcb93c69d1d77bde341e/src/ruleset.ts#L173 + docs-description: + given: '#DescribableObjects' + then: + - field: 'description' + function: 'truthy' + - field: 'description' + function: 'length' + functionOptions: + min: 20 + - field: 'description' + function: 'pattern' + functionOptions: + # Matches any character that is #, *, uppercase or lowercase letters from A to Z, or digits from 0 to 9 at the beginning of the string. + # with zero or more occurrences of any character except newline. + match: '^[#*A-Za-z0-9].*' + + # Severity + # warn: Should be implemented, but is blocked by a technical issue. + # info: Good to be implemented. + + # Rate limit + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L436 + owasp:api4:2019-rate-limit: warn + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L484 + owasp:api4:2019-rate-limit-responses-429: warn + # Public API + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L305 + owasp:api2:2019-protection-global-safe: info + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L269 + owasp:api2:2019-protection-global-unsafe: info + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L287 + owasp:api2:2019-protection-global-unsafe-strict: info + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L376 + owasp:api3:2019-define-error-responses-401: warn + + # UUID rules for name containing "id" is ignored + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L102 + owasp:api1:2019-no-numeric-ids: off + +- files: + - '**#/paths/~1api~1health~1live/get/responses' + - '**#/paths/~1api~1health~1started/get/responses' + - '**#/paths/~1api~1health~1ready/get/responses' + - '**#/paths/~1api~1test~1test~1%7Bid%7D~1test~1%7Baction%7D/post/responses' + - '**#/paths/~1api~1test~1test~1%7Bid%7D~1test~1%7Baction%7D/get/responses' + # Recheck this, already apply validator but does not work "FragmentId" + - '**#/paths/~1api~1v1~1fragments~1statuses/get/parameters/0/schema' + # Recheck this, already apply validator but does not work "AccountId" + - '**#/paths/~1api~1v1~1votes~1plan~1account-votes~1%7Baccount_id%7D/get/parameters/0/schema' + rules: + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L551 + owasp:api4:2019-string-restricted: off + +- files: + - '**#/paths/~1api~1health~1live/get/responses' + - '**#/paths/~1api~1health~1started/get/responses' + - '**#/paths/~1api~1health~1ready/get/responses' + - '**#/paths/~1api~1v0~1message/post/requestBody/content' + - '**#/paths/~1api~1test~1test~1%7Bid%7D~1test~1%7Baction%7D/post/responses' + - '**#/paths/~1api~1test~1test~1%7Bid%7D~1test~1%7Baction%7D/get/responses' + - '**#/components/schemas/ServerErrorPayload/properties/id' + - '**#/components/schemas/VoterRegistration/properties/as_at' + - '**#/components/schemas/VoterRegistration/properties/last_updated' + # Recheck this, already apply validator but does not work "FragmentId" + - '**#/paths/~1api~1v1~1fragments~1statuses/get/parameters/0/schema' + # Recheck this, already apply validator but does not work "AccountId" + - '**#/paths/~1api~1v1~1votes~1plan~1account-votes~1%7Baccount_id%7D/get/parameters/0/schema' + rules: + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L521 + owasp:api4:2019-string-limit: off + +- files: + - '**#/paths/~1api~1v0~1vote~1active~1plans/get/responses' + - '**#/paths/~1api~1v1~1votes~1plan~1account-votes~1%7Baccount_id%7D/get/responses' + rules: + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L506 + owasp:api4:2019-array-limit: off + +- files: + - '**#/components/schemas/FragmentStatus' + rules: + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L678 + owasp:api6:2019-no-additionalProperties: off + +- files: + - '**#/paths/~1api~1v1~1fragments~1statuses/get/responses' + rules: + # Ref: https://github.com/stoplightio/spectral-owasp-ruleset/blob/2fd49c377794222352ff10dee99ed2a106c35199/src/ruleset.ts#L698 + owasp:api6:2019-constrained-additionalProperties: off diff --git a/catalyst-gateway/Earthfile b/catalyst-gateway/Earthfile index 09033797aa2..872e1d103a8 100644 --- a/catalyst-gateway/Earthfile +++ b/catalyst-gateway/Earthfile @@ -46,6 +46,16 @@ build: all-hosts-build: BUILD --platform=linux/amd64 --platform=linux/arm64 +build + +# test-lint-openapi - OpenAPI linting from an artifact +# testing whether the OpenAPI generated during build stage follows good practice. +test-lint-openapi: + FROM github.com/input-output-hk/catalyst-ci/earthly/spectral:v2.4.0+spectral-base + # Copy the doc artifact. + COPY +build/doc ./doc + # Scan the doc directory where type of file is JSON. + DO github.com/input-output-hk/catalyst-ci/earthly/spectral:v2.4.0+BUILD_SPECTRAL --dir=./doc --file_type="json" + # Publish packages if all integration tests have passed. (Failure to pass tests will prevent packages being published.) # publish: # FROM scratch @@ -58,3 +68,4 @@ local-ci-run: BUILD +build # BUILD +package # BUILD +publish +