Linting Rules
Overview
A linting ruleset was created to support API Developers/Providers in achieving the standards described in the UKHSA API Guidelines, ensuring consistency, reliability, and security across all APIs developed within or on behalf of UKHSA.
As well as the rules described herein, the UKHSA ruleset extends Vacuum’s built-in OpenAPI recommended baseline (vacuum:oas). These common sense rules help ensure an OpenAPI definition adheres to the OpenAPI specification, and include documentation-focused checks that encourage high quality, rich API descriptions for the best possible APIM Developer Portal experience. See the Vacuum rule reference for details of built-in rules.
Where rules have been adopted from existing open source API rulesets, a link is supplied on the relevant rule page.
Migration from Spectral to Vacuum
The UKHSA ruleset previously supported Spectral-oriented consumption via @ukhsa-collaboration/spectral-rules.
Current releases are distributed for Vacuum consumption via @ukhsa-collaboration/openapi-linting-rules. This is a breaking tooling change for teams moving from the Spectral package.
@ukhsa-collaboration/spectral-rules should be treated as a legacy package and should not be used for new integrations.
Why we moved to Vacuum
- Faster linting in local development and CI pipelines.
- Improved handling of very large OpenAPI documents, including pygeoapi-generated specifications.
What existing Spectral users should do next
- Install Vacuum in your project (
npm install @quobix/vacuum --save-dev). - Uninstall the legacy Spectral package (
npm uninstall @ukhsa-collaboration/spectral-rules). - Install or update the Vacuum-first UKHSA ruleset package (
npm install @ukhsa-collaboration/openapi-linting-rules --save-dev). - Replace Spectral config with a
vacuum.conf.yamlfile that points toukhsa.oas.rules.ymlanddist/functions. - Replace Spectral lint commands in local scripts and CI jobs with
npx vacuum lint ...(Vacuum auto-discovers./vacuum.conf.yaml). - Optionally use
npx ukhsa-vacuum-lint lint ..., a thin wrapper that injects the default ruleset, custom functions directory, and ref-resolution flags so callers do not need avacuum.conf.yaml. - If your downstream tooling expects a Spectral-style JSON artifact, use
npx vacuum spectral-report <spec> <report.json>during transition.
Release story for this migration
This migration is treated as a MAJOR release event for the ruleset package because the integration contract changed from Spectral tooling to Vacuum tooling.
- Teams that still depend on Spectral should remain on the last pre-migration version until they can switch pipelines.
- Teams adopting the Vacuum integration should upgrade to the migration release and follow the steps above.
- Release notes should call out the version boundary and migration actions clearly.
How to use the rules
Install Vacuum
Vacuum is a fast OpenAPI linter for rulesets like this one. Install Vacuum globally or as a dev dependency.
npm install @quobix/vacuum --save-dev
Read the official Vacuum documentation for more installation options.
Run Vacuum against your OpenAPI definition
Run Vacuum against your OpenAPI definition, referencing the UKHSA ruleset.
You must install the ruleset via npm and then reference it; the UKHSA ruleset npm package is hosted on GitHub — see GitHub’s documentation Installing a GitHub npm package.
The simplest way to authenticate against the GitHub NPM registry locally is to use the npm login command (as described here) to authenticate with GitHub Packages, this adds the required credentials to your npm configuration file i.e. .npmrc.
$ npm login --scope=@ukhsa-collaboration --auth-type=legacy --registry=https://npm.pkg.github.com
Username: USERNAME #GITHUB USERNAME
Password: TOKEN #GITHUB PAT TOKEN
npm install @ukhsa-collaboration/openapi-linting-rules --save-dev
Create a local vacuum configuration file vacuum.conf.yaml to pre-configure the use of the UKHSA ruleset.
cat << 'EOF' > vacuum.conf.yaml
ruleset: ./node_modules/@ukhsa-collaboration/openapi-linting-rules/ukhsa.oas.rules.yml
functions: ./node_modules/@ukhsa-collaboration/openapi-linting-rules/dist/functions
resolve-all-refs: true
nested-refs-doc-context: true
EOF
Then run Vacuum against your OpenAPI definition. Vacuum auto-discovers ./vacuum.conf.yaml from the working directory, so no --config flag is needed.
npx vacuum lint ./path/to/openapi-definition.yml
Tip: Need a JSON report?
Use npx vacuum spectral-report <spec> <report.json> to generate a report you can post-process in existing tooling.
Review and fix any reported issues
Once the linter has highlighted any issues or errors, review and fix to ensure your OpenAPI definition remains compliant with the UKHSA guidelines.
Severity overrides
Some OpenAPI definitions produced by platforms like pygeoapi might struggle to meet every MUST requirement. This is often because these issues are outside the consuming team’s direct control, as fixes would require upstream contributions or maintaining a fork. To accommodate this, the ruleset ships paired -pygeoapi rule variants that fire at warn instead of error when an OpenAPI document declares info.x-api-type: pygeoapi. Selection is automatic — there is only one ruleset (ukhsa.oas.rules.yml).
See severity overrides for the full list of relaxed rules and how to opt into the relaxed severities.
CI/CD GitHub Actions
The following is a sample GitHub Actions job that can be used as an example of setting up linting as part of your CI/CD pipeline.
Commit a vacuum.conf.yaml to the root of your repository so it is reused by both local development and CI; Vacuum auto-discovers ./vacuum.conf.yaml from the working directory.
# vacuum.conf.yaml (commit this to the root of your repository)
ruleset: ./node_modules/@ukhsa-collaboration/openapi-linting-rules/ukhsa.oas.rules.yml
functions: ./node_modules/@ukhsa-collaboration/openapi-linting-rules/dist/functions
resolve-all-refs: true
nested-refs-doc-context: true
name: API Standards Checks
on:
pull_request:
branches: [main, master] # Example only - you would typically use either 'main' or 'master', not both
jobs:
lint-openapi:
name: Lint OpenAPI
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
checks: write
pull-requests: write
packages: read
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "22.x"
registry-url: "https://npm.pkg.github.com"
# Defaults to the user or organization that owns the workflow file
scope: "@ukhsa-collaboration"
- name: Install linting dependencies
run: npm install @quobix/vacuum @ukhsa-collaboration/openapi-linting-rules
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Lint OpenAPI specifications
run: |
# Uses the vacuum.conf.yaml committed to the repository root.
npx vacuum lint ./*.{json,yml,yaml}
# Example: Only lint OpenAPI files (requires bash extglob if uncommented)
# shopt -s extglob
# npx vacuum lint ./@(openapi|swagger|*api)*.{json,yml,yaml}
The unquoted shell pattern above relies on shell expansion to target JSON and YAML files in the current working directory before Vacuum runs.
The stricter example uses glob syntax to target only OpenAPI specification files.
The glob pattern ./@(openapi|swagger|*api)*.{json,yml,yaml} matches:
Tip: Matches
openapi.json
something.api.yaml
swagger.json
The glob pattern does not match:
Caution: Does Not Match
/node_modules/openapi.yaml
/.git/something.json
If you use that stricter example in bash, enable extended globbing first with shopt -s extglob.
Additional Recommended Tooling
| Tool | Description |
|---|---|
| Vacuum GitHub Action | Official Vacuum action for linting OpenAPI definitions in CI/CD workflows. |
| Vacuum VS Code Extension | VS Code extension for running Vacuum linting locally. |
Official GitHub Action Example
If you want the quickest GitHub Actions integration for a single OpenAPI file, use the official Vacuum action directly:
name: Lint OpenAPI spec with vacuum
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
pull-requests: write
jobs:
vacuum-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v6
with:
node-version: '22.x'
cache: npm
- name: Install dependencies
run: npm ci
- name: Build ruleset and Vacuum functions
run: npm run build
- name: Run official Vacuum action
uses: pb33f/vacuum-action@v2
with:
openapi_path: example/example.1.0.0.oas.yml
ruleset: ukhsa.oas.rules.yml
github_token: $
fail_on_error: true
print_logs: true
This path is operationally simple and posts a Markdown report comment on pull requests. It does not create inline file annotations in the GitHub diff view. The action expects a concrete file path; if you need to lint multiple files, run npx vacuum lint in a shell step instead so your shell can expand the file pattern before Vacuum starts.
Read the official Vacuum documentation for more development workflows.
Published: 2 July 2026
Last updated: 2 July 2026
Page Source