Ever needed to tweak an OpenAPI spec for different environments without maintaining multiple copies?
Maybe swap out server URLs between dev, staging, and production? Or perhaps strip out internal endpoints before publishing the API docs?
OpenAPI Overlays are the answer. They let us make non-destructive modifications to specs using JSONPath expressions to target exactly what we want to change.
Think of them as surgical strikes on our API specifications.
The apply-overlay command takes an overlay document and applies it to an OpenAPI spec, giving a modified version without
touching the original.
This is perfect for CI/CD pipelines where you need environment-specific variations of the same base spec.
Basic Usage
This reads openapi.yaml, applies the modifications from overlay.yaml, and writes the result to modified.yaml.
What is an OpenAPI Overlay?
An OpenAPI Overlay is a separate document that describes modifications to apply to a spec. It uses JSONPath expressions to target specific parts of your API definition, then either updates or removes those parts.
Here’s a simple overlay that changes the API title and adds a production server:
overlay: 1.0.0
info:
title: Add Production Server
version: 1.0.0
actions:
- target: $.info.title
update: "My API (Production)"
- target: $.servers
update:
- url: https://api.example.com/v1
description: Production server
The target field uses JSONPath to pinpoint what you want to change, and update provides the new value. You can also use remove: true to delete parts of the spec entirely.
Remote Overlays
You don’t have to keep overlay files locally. vacuum can fetch them from URLs:
This is brilliant for centralized overlay management. Keep your overlays in a CDN or repository and reference them from anywhere. Perfect for teams that need to apply the same modifications across multiple services.
stdin and stdout
For CI/CD pipelines, vacuum supports reading specs from stdin and writing results to stdout.
This means we can pipe specs through the apply-overlay command without creating intermediate files:
Or use it in a pipeline with other vacuum commands like bundle or any other tool:
The -i flag tells vacuum to read the spec from stdin, and -o writes the result to stdout instead of a file.
Handling Warnings
When vacuum applies an overlay, it might encounter warnings.
Things like JSONPath expressions that don’t match anything or actions that can’t be applied cleanly.
By default, vacuum shows these warnings but still completes successfully.
To enable strict mode where warnings are treated as errors (useful in CI/CD to catch issues early), use the --fail-on-warnings flag:
With this flag, vacuum exits with code 2 if any warnings occur, making your CI pipeline fail fast.
Available Flags
| Short | Full | Input | Description |
|---|---|---|---|
| -W | –fail-on-warnings | bool |
Treat overlay warnings as errors (exit code 2) |
| -q | –no-style | bool |
Disable styling and color output (useful for CI/CD) |
| -i | –stdin | bool |
Read spec from stdin instead of a file |
| -o | –stdout | bool |
Write output to stdout instead of a file |
Global flags like --remote, --cert-file, and --base also work with apply-overlay. Use vacuum apply-overlay --help to see all available options.
Real-World Examples
Environment-Specific Server URLs
Create different overlays for each environment:
dev-overlay.yaml:
overlay: 1.0.0
info:
title: Development Overlay
version: 1.0.0
actions:
- target: $.servers
update:
- url: https://dev.api.example.com
description: Development server
- target: $.info.title
update: "My API (Development)"
prod-overlay.yaml:
overlay: 1.0.0
info:
title: Production Overlay
version: 1.0.0
actions:
- target: $.servers
update:
- url: https://api.example.com
description: Production server
- target: $.info.title
update: "My API (Production)"
Then apply the right one for each deployment:
Removing Internal Endpoints
Strip out internal-only endpoints before publishing your public API docs:
public-overlay.yaml:
overlay: 1.0.0
info:
title: Public API Overlay
version: 1.0.0
actions:
- target: $.paths['/internal/*']
remove: true
- target: $.paths['/admin/*']
remove: true
- target: $.tags[?(@.name == 'internal')]
remove: true
Chaining Overlays
You can apply multiple overlays in sequence by piping them together:
Each overlay builds on the result of the previous one, giving us composable transformations.
Pro tip: Keep overlays small and focused on specific concerns (servers, security, metadata). This makes them reusable across different specs and easier to maintain.
