The specification and JSON Schema for OpenLint rulesets: the Spectral ruleset format, specified on its own.
A ruleset says where to look in a JSON or YAML document and what must hold there. Organizations publish their API style guides, security baselines and design standards as rulesets, then run them in CI against every OpenAPI, AsyncAPI, Arazzo and JSON Schema document they ship.
The format has never been specified. It existed only as configuration for one linter, versioned with that tool. This repository treats the ruleset as an artifact in its own right: an independently versioned specification with a portable JSON Schema, so rules can be written, validated, shared and run by any tool.
| Specification | SPECIFICATION.md |
| JSON Schema | schema/v1/ruleset.schema.json (draft 2020-12). Canonical $id: https://spec.openlint.org/schema/v1/ruleset.schema.json, not served yet |
| Reference implementation | openlint/openlint |
| Website | openlint.org/spec |
| Published releases | spec.openlint.org, proposed in #13 and not set up yet |
Status: draft. The document describes the format as implemented today, faithfully and without extension. It is not yet a formal specification: it will be rewritten to the principles below. The
v1schema identity is stable: see Versioning.
Proposed by Joost Farla in discussion #13 and not yet agreed:
- BCP 14 keywords. MUST, SHOULD, MAY and the others have their RFC 2119 meaning only in capitals (RFC 8174), with the same boilerplate as OpenAPI, Arazzo and Overlay. Examples are informative.
- Defined terms. A glossary of the terms requirements depend on, such as document, ruleset, rule, match, result and linter. Where a normative reference already defines a term, link to it.
- Exact normative references. Every reference names an exact version, especially JSONPath, regular expressions, JSON Schema and YAML.
- One conformance target per requirement. Each requirement applies to a ruleset or to a linter, never both.
- A permanent ID for every requirement, such as
/req/given/no-match, never reused. Removed requirements stay listed as removed. - Conformance tests for every requirement, listed in the spec and implemented by the conformance suite.
- A defined result model, adopting the fields of Spectral's JSON output (
code,path,severity,message,range,source) as normative. - Immutable releases. Each release lives at its own URL, such as
spec.openlint.org/1.0.0/, and never changes. Work in progress lives atspec.openlint.org/draft/.
Open questions: whether to group requirements into conformance classes, whether path-style IDs work for everyone, and what to publish with (Respec, Bikeshed or something else).
npx ajv-cli validate --spec=draft2020 \
-s schema/v1/ruleset.schema.json \
-d .spectral.yamlEditor setup is in Using the schema.
Governing structured documents, not only OpenAPI. A rule selects nodes in a JSON or YAML document with a path expression and asserts something about them. Nothing in that is specific to APIs, and the format is already used on CI workflows, Kubernetes manifests and other configuration. Support for documents that aren't API descriptions is a goal, and a change that's correct only for API descriptions is a defect. Which document types to support is being discussed in #5.
When the format ships only as part of one linter, it stops moving when the linter does. A team's governance rules usually outlast the CLI, the vendor, and often the API itself. So the rules stand on their own: specified, versioned independently, and implementable by anyone. The reference implementation follows this document, and other engines, such as vacuum, are welcome to implement it too. A written specification with a public conformance suite is what lets several engines agree.
| Topic | Discussion |
|---|---|
| Formalizing the specification: the principles above | #13 |
| Backwards compatibility: what we promise, and to whom | #12 |
| Document types ("formats") | #5 |
| Aliases | #2 |
| Rules testing | #7 |
| What | Where |
|---|---|
| Problems with the format, the schema or this document | openlint/spec issues |
| Problems with the linter | openlint/openlint issues |
| Ideas, direction and questions | OpenLint discussions |
The most useful contribution is a ruleset that behaves differently from what this document says. That's a bug in the specification.
The format originates in Spectral by Stoplight, licensed Apache-2.0. The specification and schema were derived from Spectral's internal validation meta-schemas and guides, first drafted by the OpenLint community, before it took its name, in api-commons, and moved here.
Licensed Apache-2.0. Everyone taking part follows the OpenLint Code of Conduct.