In a Kyverno verifyImages rule, how do you require signatures from two of three named attestors?
answer
- two nesting levels, two meanings
- the outer list is an AND
- the threshold lives on the set
- what does omitting count mean?
- one set, three entries, count: 2
basics
~20 sPut the three attestors as entries in one attestors set and give that set count: 2. Inside a set, count is a threshold over entries; omitting it requires all of them. Separate sets are ANDed.
solid answer
~40 s`attestors` is a list of *sets*, and each set holds `entries` plus an optional `count`. Inside one set, `count: 2` with three entries means any two of the three must verify — a threshold. Omit `count` and every entry in that set is required. The outer list is an AND: if you write two sets, both have to be satisfied independently. So "two of these three teams" is one set of three entries with `count: 2`, while "the vendor **and** our platform team" is two sets with one entry each. Getting this backwards is the usual mistake — people write three sets expecting a threshold and accidentally demand all three signatures, or write one set with no `count` and wonder why a single valid signature is rejected.
go deeper
Know that attestors names who must vouch for the image, and that the rule can demand more than one of them rather than just any single signature.
Explain the two levels precisely: count is a threshold over entries inside one set, sets in the outer list are ANDed, and omitting count requires every entry in that set.
Show the rotation and two-party-control uses — how a count:1 set lets you add and retire a signing identity without a flag-day, and why two identities in one pipeline are really one.
Own the trust-domain argument: which parties must be genuinely independent, who custodies each identity, and what you accept when a vendor cannot meet the shape you want.
## The two levels of the structure A Kyverno `verifyImages` rule expresses *who must vouch for this image* through `attestors`, and the shape has two nesting levels that carry different logic: ```yaml attestors: - count: 2 # set 1: any two of the three entries below entries: - keys: { ... } # team A - keys: { ... } # team B - keys: { ... } # team C - entries: # set 2: no count, so this single entry is required - keys: { ... } # the vendor ``` **Within a set**, `count` is a threshold over `entries`: satisfy that many and the set passes. **Across sets**, the semantics are AND: every set in the list must be satisfied for the image to verify. So the outer list is conjunction and the inner `count` is the only place where "any of" lives. The default is the strict one. If `count` is omitted, all entries in that set are required. This is a good default — a policy that silently degraded to "any one signature is fine" as you added identities would be a trap — but it means a set is not an OR unless you say so. ## Expressing the shapes teams actually want - **Any one of several accepted identities** (you accept images signed by any of four internal build systems): one set, four entries, `count: 1`. - **Threshold / two-person control** (a release must be endorsed by two of three release managers): one set, three entries, `count: 2`. - **Independent parties** (the vendor signs, and your own ingestion pipeline counter-signs after it re-scans): two sets, each with its own entry and no `count`. - **A party plus a choice** (the vendor, plus either of two internal teams): two sets — one with the vendor entry, one with two internal entries and `count: 1`. The fourth shape is the one that shows understanding, because it is only expressible if you have grasped that the two levels mean different things. ## Why thresholds exist at all A threshold is not primarily about redundancy of signing infrastructure; it is about **not letting one compromised or careless identity be sufficient**. If a single signing identity is enough, then whoever holds that identity — or whoever compromises the system that holds it — can put any image into the cluster. Requiring two independent identities means an attacker needs both, and the two identities should therefore live in genuinely different trust domains: different systems, different custodians, different blast radius. Two identities held by the same service, in the same namespace, in the same pipeline, give you the appearance of two-party control and the security of one. Thresholds also buy you operational slack in the honest direction. A `count: 1` over several accepted identities lets you rotate: add the new identity as an extra entry, let both be accepted during the overlap, remove the old one when nothing signs with it any more — with no window in which valid images are rejected. Doing the same with a single-entry set means a flag-day cutover where every image signed with the old identity is suddenly refused. ## What count does not mean A few precise limits worth stating: - `count` counts **entries that verified**, not signatures found on the image. Extra signatures from identities you did not list contribute nothing; they are neither counted nor a reason to reject. - The threshold is over the entries in **that set only**. It cannot reach across sets, so there is no way to say "any two of these five, drawn from either group" without flattening the groups into one set. - Nothing about `count` makes the parties independent. That is an organisational property of who controls the identities, and the policy file cannot check it — a reviewer has to. ## Reviewing someone else's rule When you read a `verifyImages` block in a pull request, the fast check is: how many list items are under `attestors`, and does each one carry a `count`? Three sets of one entry each is "all three required", which is often not what the author meant when they wrote a comment saying "any of our teams". One set with several entries and no `count` is the same over-strict mistake with the opposite layout. Because both mistakes fail *closed*, they show up as a blocked deploy rather than a security hole — annoying, not dangerous, but a good reason to get the shape right the first time.
- What happens if you omit count on a set that has three entries?All three are required. The default is strict, so a set is a conjunction unless you add a threshold. That default is deliberate — a policy that quietly weakened to "any one of these" as you appended identities would be a trap — but it means adding an accepted identity to a set without setting count makes the rule harder to satisfy, not easier.
- You need the vendor's signature plus either of two internal teams. How do you lay that out?Two sets. The first holds the vendor's single entry with no count, so it is mandatory. The second holds both internal entries with count: 1, so either satisfies it. Because the outer list is an AND, the image needs the vendor plus one internal signature.
- Does requiring two attestors actually give you two-party control?Only if the two identities are controlled by different people or systems. If both live in the same pipeline or are held by the same service account, an attacker who reaches that one place gets both, and you have the appearance of separation with the security of a single signer. The policy cannot check this; a reviewer has to.
saying these in an interview costs you the question
- Writes one attestor set per identity expecting an OR
- Thinks omitting count means any one entry suffices
- Believes count tallies signatures found rather than entries verified
- Assumes a threshold makes the signers independent
- Tries to express a threshold spanning two sets