# Scope of authority

Edition 2026-08-14.

An authority's remit, made machine-readable. This is the CVE Program's "scope of
authority" as data rather than as a paragraph on a web page.

A scope is a **set of rules**. Each rule matches on one dimension and carries its
own enforcement mode. Overlap between rules, and between authorities, is legal
and expected.

## Dimensions, in specificity order

The order is the specificity rank, most specific first.

| Dimension         | Matches on                                      |
| ----------------- | ----------------------------------------------- |
| `GADVISORY_SCOPE` | A scope in the issuing instance's own hierarchy |
| `VENDOR_PRODUCT`  | `vendor`, `product`, `cpe` — any subset         |
| `REPOSITORY`      | A repository pattern, normalised on both sides  |
| `PACKAGE`         | An ecosystem plus a package-name pattern        |
| `ECOSYSTEM`       | An ecosystem                                    |
| `LAST_RESORT`     | Everything                                      |

**The rank is fixed and not operator-tunable.** Ranking decides which authority
owns a subject, and a tunable rank is a value two implementations could hold
differently — at which point the same record routes to two different authorities
depending on who is asking.

Specificity is: dimension rank, then pattern narrowness, then the rule id. The
id tie-break exists so that a routing decision does not change the day somebody
adds an ordering to the query that loads the rules.

`VENDOR_PRODUCT` containment runs opposite to intuition, and it is worth
stating: a rule ANDs every field it constrains, so **more fields matches fewer
products**. A rule naming only `vendor` is broader than one naming `vendor` and
`product`.

## Modes

| Mode       | Behaviour                                                |
| ---------- | -------------------------------------------------------- |
| `HARD`     | The registry refuses a mint outside this claim.          |
| `SOFT`     | Allowed, flagged for secretariat review.                 |
| `ADVISORY` | Documentation only. Never enforced, in either direction. |

## Patterns

**`*` is the only metacharacter.** Everything else in a pattern is literal.

This is a security property, not a convenience. Compiled as a bare regular
expression, `org.acme.*` accepts `orgXacmeY`, so a rule written to hard-lock one
namespace admits a neighbouring one — and over-matching a `HARD` rule is
over-granting mint authority. Escape the pattern, then translate `*` to a
wildcard.

Corpus case: `star-is-the-only-metacharacter`.

## Two questions, one match primitive

`scope/` answers two different questions and they must not be conflated.

### Enforcement — may THIS authority mint for this subject?

Reads the modes. Answers allow, allow-and-flag, or refuse.

**Every affected product must pass.** A record is refused if **any** of its
products falls outside a hard claim, not merely if all of them do. The permissive
reading is the dangerous one: with any-match, a vendor hard-locked to its own
packages mints for a record naming one of its packages and four belonging to
somebody else, and the hard lock has laundered the other four. A genuinely mixed
record needs a `SOFT` rule or a second authority, and forcing that conversation
is the point.

Three rules decide a single product, and `ADVISORY` appears in none of them:

1. A **claim** (`HARD` or `SOFT`) matches. The most specific one decides:
   `SOFT` flags, `HARD` allows.
2. No claim matches and the set holds a `HARD` rule: **refuse**. Holding one
   hard claim at all makes the whole set a closed list, which is what "the
   registry refuses a mint outside this rule" has to mean once an authority
   holds more than one rule.
3. No claim matches and the set holds a `SOFT` rule: allow and flag. Only
   `ADVISORY` rules, or none at all: allow silently.

**`ADVISORY` rules are filtered out of the claim pool entirely.** "Never
enforced" has to hold in both directions: let an `ADVISORY` match satisfy the
closed list, and an authority nullifies its own hard lock by adding one
`ADVISORY: ecosystem *`. The lock then documents a constraint that enforces
nothing.

An **empty product list** is evaluated once against the record-level dimensions.
"Nothing to check" is deliberately not the same as "in scope": a caller
enforcing at mint must separately require that a record names what it affects,
or this returns allow for a record that asserts nothing.

### Routing — WHICH authority should own this subject?

**Ignores modes entirely.** Ranks every matching rule across every candidate
authority and returns the owner of the most specific.

**Any match routes the whole subject**, which is the opposite of enforcement's
all-must-pass and is right for the same reason: the question here is who the
natural owner is, and a record touching one of your packages is your business
even if it also touches somebody else's. With all-must-pass routing, a mixed
record would route nowhere.

An authority whose only matching rule is `ADVISORY` still routes, and then
refuses nothing — an `ADVISORY` rule is precisely a statement of remit.

Routing returns nothing only when nothing matches at all. In practice the
last-resort authority carries a `LAST_RESORT` rule, which matches
unconditionally, and that is what makes it the floor rather than a special case
in the routing algorithm.

## When each runs

**Enforcement runs at intake, not at allocation.** A mint carries no subject: a
reservation is a pre-minted identifier and nothing more, so there is nothing to
enforce against until the affected products are known. The consequence is
benign: a refusal at intake leaves the identifier reserved rather than burned,
so nothing is stranded.

Routing runs when a record needs an owner, and at draft time as a warning.

## Containment

A root tier's remit bounds what it may accredit, using the same rule type. One
rule set is contained in another when every rule in the first is entirely inside
some rule in the second.

Containment **refuses anything it cannot decide**. Over-matching there is
over-granting the power to accredit, which is one level worse than over-granting
the power to mint. Exactly two cross-dimension pairs are decidable and allowed:
`LAST_RESORT` contains anything, and an `ECOSYSTEM` rule contains a `PACKAGE`
rule in that ecosystem — a root claiming all of npm accrediting a participant
for `npm:@acme/*` is the ordinary case.

**Mode is ignored on both sides of a containment test**, or a child escapes its
parent's remit by filing the same claim as `ADVISORY`.

## Verifying your implementation

[`../conformance/scope.json`](../conformance/scope.json) carries enforcement and
routing cases separately, including the two that are most often got backwards:
`one-in-scope-product-does-not-launder-the-others` and
`any-match-routes-a-mixed-record`.
