Languages: English · 日本語
This document defines how policy/schema.json evolves across schema versions and how consumers upgrade their policies.
All policy files must declare version: 1 at the top level. Any other value is rejected at lint time.
The schema version in policy.version is not the npm package version. The two evolve independently:
- Additive changes (new optional keys, new enum members) — published in a minor npm release.
version: 1continues to lint and build. - Breaking changes (renaming a key, removing a field, tightening a validator in a way that would reject existing valid policies) — bump the schema to
version: 2and publish in a major npm release.
The schema bump and the npm major bump ship together.
| Change | Breaking? |
|---|---|
| Add a new optional key | No |
| Add a new value to an enum | No |
| Tighten an existing validator (e.g. lower a max) that could reject previously valid values | Yes |
| Rename a key | Yes |
| Remove a key | Yes |
| Change the semantic meaning of an existing key | Yes |
When a key is slated for removal:
- The release that introduces the replacement emits a
lint:policywarning (not error) naming the deprecated key and the replacement. - The deprecation warning ships in at least one minor release before the breaking change.
- The breaking change ships in the next major release, along with a
version: 2schema and a registered CLI migration (see below).
npx cdn-security migrate --policy policy/security.yml --to 2- Prints the current and target schema versions.
- If a registered migration exists, rewrites the policy in memory (and to disk with
--write) to the target version. - Exits non-zero and references this document if no migration path is registered in the installed CLI version.
The v1-only current build prints:
[INFO] Current schema version: 1
[INFO] Target schema version: 1
[OK] Already at target version — no migration needed.
Each migration step is a pure function (policy v_n) → (policy v_n+1) registered in bin/cli.js. Chaining is automatic: --to 3 on a v1 policy runs v1→v2 then v2→v3.
Migrations:
- Must not lose user configuration. Deprecated keys should be translated, not dropped silently.
- Must emit a one-line summary per transformation applied, so diff review is straightforward.
- Must include a matching unit test case in
scripts/compile-unit-tests.js.
Suppose a future release renames request.block.ua_contains to request.block.user_agent.contains and moves method allow-listing into request.methods.allow.
version: 1
request:
allow_methods: [GET, HEAD]
block:
ua_contains: [sqlmap, nikto]version: 2
request:
methods:
allow: [GET, HEAD]
block:
user_agent:
contains: [sqlmap, nikto]npx cdn-security migrate --policy policy/security.yml --to 2 --writeExpected log:
[INFO] Policy: policy/security.yml
[INFO] Current schema version: 1
[INFO] Target schema version: 2
[MIGRATE v1→v2] Renamed request.allow_methods → request.methods.allow
[MIGRATE v1→v2] Renamed request.block.ua_contains → request.block.user_agent.contains
[SUCCESS] Wrote migrated policy to policy/security.yml
If a v2 policy regresses in production:
- Pin your npm dependency to the last v1-compatible major version.
- Restore the pre-migration policy from git (the original file is the migration's source of truth).
- File an issue — a migration that loses information is a bug.
- The schema file:
policy/schema.json - The CLI validator:
scripts/policy-lint.js - The migration registry:
bin/cli.js(migratecommand) - The release changelog:
CHANGELOG.md
All four must be updated together when bumping schema versions.