# SPDX-License-Identifier: CC-BY-NC-SA-4.0 # # The S3 interface, as a Spectral ruleset. # # GENERATED by scripts/build-ruleset.py from the measured profile. Do not hand-edit. # # READ THE COHORT BEFORE THE RULES. 58 providers claim S3 compatibility and # 12 publish a spec declaring an S3 operation. That is the denominator, and it is # the thinnest evidence base of any profile in this programme. These rules encode what those # 12 declare, which is a signal rather than a census. # # WHAT THIS DOES NOT CHECK # - Anything beyond the core tier. OpenAPI cannot express the query subresource that # identifies 99 of S3's 116 operations, so ?acl, ?cors, ?versioning and the rest are # graded in profile.yml and invisible to any linter working on an OpenAPI. # - Whether the endpoint serves what its document claims. For S3 that cannot be tested # anonymously at all: the server validates the signature before routing the operation, # so an unauthenticated caller gets AccessDenied for a supported operation and an # unsupported one alike. # - Request signing, addressing style, or region behaviour. SigV4, virtual-host versus # path-style addressing and endpoint resolution are real compatibility questions and # none of them is visible in a path. # # Built-in functions only, so it runs unchanged in the browser validator. formats: [oas3] rules: s3-core-list-buckets: description: >- `ListBuckets` is core: 10 of 12 providers that publish a readable spec declare it (83.3%). It is `GET /` — the service root. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No GET on the service root — `ListBuckets` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/$" s3-core-list-objects: description: >- `ListObjects` is core: 10 of 12 providers that publish a readable spec declare it (83.3%). It is `GET /{Bucket}` — a bucket-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No GET on a bucket-level path — `ListObjects` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/?$" s3-core-delete-bucket: description: >- `DeleteBucket` is core: 9 of 12 providers that publish a readable spec declare it (75.0%). It is `DELETE /{Bucket}` — a bucket-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No DELETE on a bucket-level path — `DeleteBucket` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/?$" s3-core-delete-object: description: >- `DeleteObject` is core: 9 of 12 providers that publish a readable spec declare it (75.0%). It is `DELETE /{Bucket}/{Key+}` — an object-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No DELETE on an object-level path — `DeleteObject` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/\\{[^/}]+\\}/?$" s3-core-get-object: description: >- `GetObject` is core: 9 of 12 providers that publish a readable spec declare it (75.0%). It is `GET /{Bucket}/{Key+}` — an object-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No GET on an object-level path — `GetObject` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/\\{[^/}]+\\}/?$" s3-core-create-bucket: description: >- `CreateBucket` is core: 8 of 12 providers that publish a readable spec declare it (66.7%). It is `PUT /{Bucket}` — a bucket-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No PUT on a bucket-level path — `CreateBucket` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/?$" s3-core-head-object: description: >- `HeadObject` is core: 7 of 12 providers that publish a readable spec declare it (58.3%). It is `HEAD /{Bucket}/{Key+}` — an object-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No HEAD on an object-level path — `HeadObject` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/\\{[^/}]+\\}/?$" s3-core-put-object: description: >- `PutObject` is core: 7 of 12 providers that publish a readable spec declare it (58.3%). It is `PUT /{Bucket}/{Key+}` — an object-level path. Parameter names vary between vendors, so this matches the shape of the path rather than its spelling. message: "No PUT on an object-level path — `PutObject` is not described." severity: error documentationUrl: https://apicommons.org/standards/storage/#core given: "$" then: field: paths function: schema functionOptions: schema: type: object minProperties: 1 not: propertyNames: not: pattern: "^/\\{[^/}]+\\}/\\{[^/}]+\\}/?$" s3-is-not-json: description: >- S3 is rest-xml. A document describing an S3-compatible API whose operations declare only `application/json` responses is describing something else, and a client built from it will not parse what the server returns. message: "This response declares JSON only. S3 responses are XML." severity: warn documentationUrl: https://apicommons.org/standards/storage/ given: "$.paths[*][*].responses[*].content" then: function: schema functionOptions: schema: type: object not: allOf: - required: ["application/json"] - maxProperties: 1