spectral Rulesets: Custom OpenAPI Rules in CI
A Spectral ruleset is a .spectral.yaml that extends a base set (like spectral:oas) and adds custom rules with given (JSONPath) and then (function) blocks.
The default OpenAPI rules are a starting point. Most teams add organization-specific rules (required tags, naming, versioned paths) in a custom ruleset that CI enforces.
What it does
A ruleset declares extends (one or more base rulesets) and a rules map. Each rule has a given JSONPath selecting nodes, a then referencing a built-in function (truthy, pattern, casing, length, schema, ...), and a severity. Spectral evaluates every rule against the document.
Common usage
# .spectral.yaml
# extends: ["spectral:oas"]
# rules:
# operation-tag-defined: error
# paths-kebab-case:
# description: Paths must be kebab-case
# given: $.paths[*]~
# severity: error
# then:
# function: pattern
# functionOptions:
# match: "^(/[a-z0-9-]+)+$"
spectral lint -r .spectral.yaml openapi.yamlFlags and options
| Ruleset key | What it does |
|---|---|
| extends | Base rulesets to inherit (e.g. spectral:oas, spectral:asyncapi) |
| rules.<name>.given | JSONPath selecting the nodes to check |
| rules.<name>.then.function | Built-in: truthy, pattern, casing, length, schema |
| rules.<name>.severity | error, warn, info, or hint |
| formats | Restrict a rule to oas3, oas2, asyncapi2, etc. |
| aliases | Reusable JSONPath targets referenced by rules |
In CI
Keep the ruleset in the repo so it versions with the spec, and run the same spectral lint -r .spectral.yaml locally and in CI for parity. Set new custom rules to warn first, then promote to error once the spec is clean to avoid blocking on day one.
Common errors in CI
"Error running Spectral! ... is not a valid ruleset" means a malformed ruleset (bad YAML or an unknown then.function). "Cannot find module ..." when extends points at an npm ruleset means it is not installed. A rule that never fires usually has a wrong given JSONPath; the ~ suffix selects property keys (used above to match path strings).