Skip to content

LicenseExceptions

Recorded, attributed exceptions to the licence policy: a licence exempted everywhere (blanket) or one package exempted, each with who approved it, why. Fields, YAML, HCL and CLI samples, and how apply treats it.

Checked against config-schemas@v1.15.0, terraform-provider-resolve@82cb23c, cli@v4.9.1

Recorded, attributed exceptions to the licence policy: a licence exempted everywhere (blanket) or one package exempted, each with who approved it, why, and until when. An exempted finding is kept and badged, never dropped, and an expired exception stops applying and says so; the expiry date is inclusive. Two forms are valid. The repository file .vulnetix/license-exceptions.yaml, read by vulnetix license and scan –evaluate-licenses, keeps blanket and packages at the top level with no metadata. The config form puts them under spec, with metadata. The server does not store exceptions yet: the CLI validates the document and plan notes it, but apply sends nothing.

blanket exceptions are checked first and the first unexpired match wins; packages are checked after them. See Licence policy and Licence evaluation.

apiVersion vulnetix.com/v1
kind LicenseExceptions
Group Scanners and gates
Status Validate only. The server stores nothing for it: validate and plan check a document, and apply sends nothing.
Objects per tenant one (metadata.name: default)
Token and role None. The server stores nothing for this kind; validating needs no credential.
Terraform resource None: the server stores nothing for this kind
CLI vulnetix config validate reads it (CLI v3.165.1 and later); plan and apply note it and send nothing.
Pinned schema v1.15.0/LicenseExceptions.schema.json
Newest schema latest/LicenseExceptions.schema.json
First released in v1.3.0
Print the built-in copy vulnetix config schema LicenseExceptions

Minimal

Only the fields the kind requires. From examples/LicenseExceptions/minimal.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/LicenseExceptions.schema.json
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
metadata:
  name: default
spec: {}

HCL

There is no Terraform resource. The server stores nothing for this kind, so there is nothing for Terraform to manage. The file stays in the repository; see Which files are Platform IaC documents.

CLI (validates it)

vulnetix config validate -f - <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/LicenseExceptions.schema.json
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
metadata:
  name: default
spec: {}
EOF

Advanced

Every field the kind supports, with a when expression where it takes one. From examples/LicenseExceptions/advanced.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/LicenseExceptions.schema.json
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
metadata:
  name: default
  labels:
    team: legal
  annotations:
    ticket: https://tracker.example.com/LEGAL-102
spec:
  blanket:
    - license: MPL-2.0
      id: LEX-001
      reason: File-level copyleft; we ship MPL files unmodified and publish their source.
      scope: unmodified
      approver: legal@acme.com
      approvedDate: "2026-03-02"
      expires: "2027-03-01"
      projects: ["*"]
  packages:
    - purl: pkg:golang/github.com/hashicorp/*
      license: BUSL-1.1
      id: LEX-002
      reason: Internal tooling only; not offered as a competing hosted service.
      scope: dynamically linked
      approver: legal@acme.com
      approvedDate: "2026-04-15"
      expires: "2026-12-31"
      projects: [infra-tools]
    - name: ghostscript
      license: AGPL-3.0-only
      id: LEX-003
      reason: Used in the batch PDF renderer, which is never exposed over a network.
      scope: vendored
      approver: cto@acme.com
      approvedDate: "2026-05-20"
      projects: [pdf-batch]
---
# The repository file form, .vulnetix/license-exceptions.yaml: blanket and packages at the top level, no metadata.
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
blanket:
  - license: EPL-2.0
    reason: Eclipse libraries are used unmodified as build-time dependencies.
packages:
  - purl: pkg:npm/%40acme/internal-fonts
    reason: Proprietary fonts licensed to ACME under contract C-2291.

HCL

There is no Terraform resource. The server stores nothing for this kind, so there is nothing for Terraform to manage. The file stays in the repository; see Which files are Platform IaC documents.

CLI (validates it)

vulnetix config validate -f - <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/LicenseExceptions.schema.json
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
metadata:
  name: default
  labels:
    team: legal
  annotations:
    ticket: https://tracker.example.com/LEGAL-102
spec:
  blanket:
    - license: MPL-2.0
      id: LEX-001
      reason: File-level copyleft; we ship MPL files unmodified and publish their source.
      scope: unmodified
      approver: legal@acme.com
      approvedDate: "2026-03-02"
      expires: "2027-03-01"
      projects: ["*"]
  packages:
    - purl: pkg:golang/github.com/hashicorp/*
      license: BUSL-1.1
      id: LEX-002
      reason: Internal tooling only; not offered as a competing hosted service.
      scope: dynamically linked
      approver: legal@acme.com
      approvedDate: "2026-04-15"
      expires: "2026-12-31"
      projects: [infra-tools]
    - name: ghostscript
      license: AGPL-3.0-only
      id: LEX-003
      reason: Used in the batch PDF renderer, which is never exposed over a network.
      scope: vendored
      approver: cto@acme.com
      approvedDate: "2026-05-20"
      projects: [pdf-batch]
---
# The repository file form, .vulnetix/license-exceptions.yaml: blanket and packages at the top level, no metadata.
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
blanket:
  - license: EPL-2.0
    reason: Eclipse libraries are used unmodified as build-time dependencies.
packages:
  - purl: pkg:npm/%40acme/internal-fonts
    reason: Proprietary fonts licensed to ACME under contract C-2291.
EOF

Fields

Paths use dots for nesting and [] for the items of a list. Required means required whenever the parent object is present. A default is what the server uses when the field is left out.

Field Type Required Default Allowed values Description
apiVersion string yes exactly vulnetix.com/v1 The document format version. Every kind in this release is vulnetix.com/v1.
kind string yes exactly LicenseExceptions Always LicenseExceptions.
metadata object no no other keys Metadata for a singleton kind whose documents predate metadata.name. Both metadata and its name may be left out; a name, when given, must be default.
metadata.name string no exactly default
metadata.org string no format uuid The tenant (organization UUID) the document belongs to. When set, plan and apply refuse to run against any other tenant.
metadata.labels object no map of string to string (length 0 to 256); keys match ^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$ Free key/value labels. Stored with the object, never interpreted by the server.
metadata.annotations object no map of string to string (length 0 to 4096) Free key/value notes for people and tools, such as a ticket link.
spec object no no other keys
spec.blanket array of object no Licences exempted wherever they appear. The first unexpired match wins.
spec.blanket[].license string yes length 1 to any The SPDX licence id. Matching is by prefix, so MPL-2.0 also covers MPL-2.0-no-copyleft-exception.
spec.blanket[].id string no length 1 to any A stable id to refer to the exception by in reports.
spec.blanket[].reason string yes pattern \S Why the exception exists. Required: an exception nobody can explain cannot be told apart from a mistake.
spec.blanket[].scope string no What the claim is limited to, such as vendored, unmodified, dynamically linked.
spec.blanket[].approver string no Who signed the exception off.
spec.blanket[].approvedDate string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ When it was approved, as YYYY-MM-DD.
spec.blanket[].expires string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ The last day the exception applies, as YYYY-MM-DD. Left out, it never expires.
spec.blanket[].projects array of string no each item: length 1 to any Only these projects, matched without case; * is every project. Left out, every project.
spec.packages array of object no Packages exempted, optionally under one licence. Checked after blanket exceptions.
spec.packages[].purl string no pattern ^pkg:[a-zA-Z.+-]+/; length 5 to any The package, as a purl with * as a wildcard segment, such as pkg:golang/github.com/hashicorp/*.
spec.packages[].name string no length 1 to any The package name, matched as a substring, for ecosystems where the short name and the full module path are both in use.
spec.packages[].license string no length 1 to any Exempt the package only under this SPDX licence. Left out, the package is exempt whatever licence it carries, which is the broader claim.
spec.packages[].id string no length 1 to any A stable id to refer to the exception by in reports.
spec.packages[].reason string yes pattern \S Why the exception exists. Required: an exception nobody can explain cannot be told apart from a mistake.
spec.packages[].scope string no What the claim is limited to, such as vendored, unmodified, dynamically linked.
spec.packages[].approver string no Who signed the exception off.
spec.packages[].approvedDate string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ When it was approved, as YYYY-MM-DD.
spec.packages[].expires string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ The last day the exception applies, as YYYY-MM-DD. Left out, it never expires.
spec.packages[].projects array of string no each item: length 1 to any Only these projects, matched without case; * is every project. Left out, every project.
blanket array of object no Licences exempted wherever they appear. The first unexpired match wins.
blanket[].license string yes length 1 to any The SPDX licence id. Matching is by prefix, so MPL-2.0 also covers MPL-2.0-no-copyleft-exception.
blanket[].id string no length 1 to any A stable id to refer to the exception by in reports.
blanket[].reason string yes pattern \S Why the exception exists. Required: an exception nobody can explain cannot be told apart from a mistake.
blanket[].scope string no What the claim is limited to, such as vendored, unmodified, dynamically linked.
blanket[].approver string no Who signed the exception off.
blanket[].approvedDate string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ When it was approved, as YYYY-MM-DD.
blanket[].expires string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ The last day the exception applies, as YYYY-MM-DD. Left out, it never expires.
blanket[].projects array of string no each item: length 1 to any Only these projects, matched without case; * is every project. Left out, every project.
packages array of object no Packages exempted, optionally under one licence. Checked after blanket exceptions.
packages[].purl string no pattern ^pkg:[a-zA-Z.+-]+/; length 5 to any The package, as a purl with * as a wildcard segment, such as pkg:golang/github.com/hashicorp/*.
packages[].name string no length 1 to any The package name, matched as a substring, for ecosystems where the short name and the full module path are both in use.
packages[].license string no length 1 to any Exempt the package only under this SPDX licence. Left out, the package is exempt whatever licence it carries, which is the broader claim.
packages[].id string no length 1 to any A stable id to refer to the exception by in reports.
packages[].reason string yes pattern \S Why the exception exists. Required: an exception nobody can explain cannot be told apart from a mistake.
packages[].scope string no What the claim is limited to, such as vendored, unmodified, dynamically linked.
packages[].approver string no Who signed the exception off.
packages[].approvedDate string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ When it was approved, as YYYY-MM-DD.
packages[].expires string no pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T00:00:00Z)?$ The last day the exception applies, as YYYY-MM-DD. Left out, it never expires.
packages[].projects array of string no each item: length 1 to any Only these projects, matched without case; * is every project. Left out, every project.

Rules

Conditions the schema enforces beyond each field’s own type. vulnetix config validate and the engine’s plan report a document that breaks one.

On Rule
the document Exactly one of these holds: (1) The config form: metadata is required, spec is required, blanket is not allowed and packages is not allowed; (2) The repository file form: spec is not allowed.
spec.packages[] At least one of purl or name is set.
packages[] At least one of purl or name is set.

Applying this kind

  • Not stored. The engine registers the kind so that validate and plan check a document. A plan that includes one shows the warning not_stored, and apply sends nothing for it.

Two forms

Both are valid, and a document is exactly one of them.

Form Where Shape
Repository file .vulnetix/license-exceptions.yaml blanket and packages at the top level. metadata is optional.
Config A document under .vulnetix/config metadata and spec are required, and blanket and packages sit under spec

The fields in the table are the same in both. A licence file written before documents carried apiVersion and kind is read as this kind from its well-known path, so an older repository keeps working. vulnetix license and vulnetix scan --evaluate-licenses read the file, or the document under .vulnetix/config, unless --exceptions-file names one. Defining it in both places, or twice, is an error. See Which files are Platform IaC documents. In GitHub Actions the license action reads the same files.

# The repository file form, .vulnetix/license-exceptions.yaml
apiVersion: vulnetix.com/v1
kind: LicenseExceptions
blanket:
  - license: EPL-2.0
    reason: Eclipse libraries are used unmodified as build-time dependencies.
packages:
  - purl: pkg:npm/%40acme/internal-fonts
    reason: Proprietary fonts licensed to ACME under contract C-2291.

Where it takes effect

Like LicensePolicy, the server stores nothing for this kind. The engine registers it so that validate and plan check a document, and a plan that includes one shows the warning not_stored. The CLI reads the repository file on the machine running the scan.

Terraform and OpenTofu

There is no Terraform resource. The server stores nothing for this kind, so there is nothing for Terraform to manage. The file stays in the repository; see Which files are Platform IaC documents.

Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.

Edit this pageSources: config-schemas/schemas/LicenseExceptions.schema.json, config-schemas/schemas/common.schema.json, config-schemas/examples/LicenseExceptions/minimal.yaml, config-schemas/examples/LicenseExceptions/advanced.yaml, vdb-site/docs/platform-iac-engine.md, vdb-site/api/internal/handler/config_engine_kinds.go, cli/internal/platformiac/discover.go, cli/internal/license/exceptions.go, cli/docs/platform-iac.md, vdb-site/api/internal/config/licenseexceptions.go
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.