How do you stop your set of accepted signing identities from becoming an unreviewable allowlist?
answer
- additions are urgent, removals never are
- a standing authorisation to ship
- acquisitions and migrations add entries
- dormant names can be re-registered
- owner, reason, scope, expiry per entry
basics
~20 sGive every accepted identity an owner, a justification, a scope and an expiry, then reconcile the list against what has actually signed anything recently. Additions are always urgent and removals never are, so the set ratchets unless expiry is the default.
solid answer
~50 sThe set drifts in one direction because the incentives are asymmetric: adding an identity unblocks a release today, while removing one risks breaking something nobody can name. An acquisition brings a second CI issuer for an internal package index, a platform migration adds a parallel entry, a one-off vendor build adds a third, and two years later nobody can say which entries still correspond to a live build system. Each stale entry is a standing authorisation to ship into production, and a dormant one is worse than untidy: if the repository or account it names is deleted, that name can often be re-registered by someone else, and the dead entry becomes a live signing path. Treat the list as an inventory with owner, reason, scope and expiry per entry; reconcile it on a schedule against usage; and make removal cheap and reversible so pruning is routine rather than an act of courage.
go deeper
Know that the list of accepted signers is itself a thing that has to be maintained, and that an entry nobody uses is not automatically harmless.
Be able to explain why entries accumulate — acquisitions, migrations, one-off vendor builds — and what metadata an entry needs so it can later be reviewed.
Show the reconciliation mechanics: usage signals from verification, existence checks on repositories and issuers, and a removal path cheap enough that pruning actually happens.
Own the incentive asymmetry and the fix. Be ready to argue for mandatory expiry, name who owns the set, and defend the spend to leadership in terms of being able to state truthfully who may ship into production.
## Why the set only grows The accepted-identity list is governed by an asymmetry that no amount of good intent survives. Adding an entry has an urgent, visible, named beneficiary: a release is blocked, a team is waiting, the change takes five minutes. Removing an entry has no beneficiary today, an unknown blast radius, and a plausible worst case where someone's release breaks and you are the reason. Under those incentives every list ratchets. The entries arrive from ordinary, defensible events: - **an acquisition** — the acquired company keeps its own CI issuer for its internal Python wheel index, and cutting it over is a quarter of work nobody has scheduled - **a migration** — the new platform's identity is added while the old one stays for the rollback that never happens - **a one-off** — a vendor or a partner needs to ship one build, and the entry outlives the engagement - **an experiment** — a proof of concept whose identity was added by someone who has since changed teams Each one is reasonable. The sum is not. ## What each entry actually is Reframing is the useful move here, and it is the sentence to say in an interview: **an accepted signing identity is a standing authorisation to place code into production.** It is not a configuration value. It belongs in the same mental category as a production credential or a role grant, and it should inherit the same disciplines — an owner, a stated purpose, a scope, a review, an end. That reframing also explains why a dormant entry is dangerous rather than merely messy. Identities in this world are names in someone else's namespace: a repository path, an account, an issuer URL. Namespaces reclaim names. If the repository or organisation an entry points at is deleted, the name may become registrable by a stranger; if a decommissioned self-hosted issuer's domain lapses, whoever picks it up inherits the ability to assert the identity you still accept. The entry that 'does nothing' is the one nobody is watching. The deeper cost is to audit truth. When a regulator, a customer, or your own incident commander asks 'who is currently authorised to ship into production?', the honest answer has to be an enumerable list of live identities with named owners. A list that has only ever grown cannot produce that answer, and discovering it mid-incident is expensive. ## The disciplines that hold **Every entry carries metadata.** Owner (a team, never an individual who may leave), justification in one sentence, the artifacts it is allowed to sign, and an expiry date. Entries without all four do not get merged. **Expiry is the default, not the exception.** A time-boxed entry converts the asymmetry: renewal becomes the action that needs a beneficiary to show up, which is exactly the person who knows whether it is still needed. Nobody has to prove a negative. **Reconcile against usage.** Verification produces a signal every time it accepts something, and that signal names the identity. Aggregate it: an identity that has not been accepted in a release cycle is a removal candidate. Pair it with an existence check — does the repository still exist, does the issuer still resolve, does the owning team still exist — and require the owner to re-attest rather than asking the security team to prove the entry is dead. **Make removal cheap and reversible.** If taking an entry out is a change that can be reverted in minutes, pruning becomes routine maintenance. If it requires a change-advisory board, it will not happen. Some teams remove in two steps — stop accepting, observe the failure signal, keep the entry restorable for a short window — which lowers the perceived cost of being wrong without leaving the authorisation in place indefinitely. **Say yes with an end date.** The acquisition case is the test. The right answer is not to refuse the acquired company's issuer; it is to add it narrowly — their specific repositories and workflows, not their whole organisation — with a named owner, the migration cost written down, and a review date that is a real deadline rather than a reminder. The mistake is never the exception itself; it is an exception with no owner and no expiry. ## Measuring it Two numbers make the drift visible to people who will not read the list: the count of accepted identities that have not been used in the last release cycle, and the count of entries past their review date. Both should trend to zero, and both are reportable without exposing anything sensitive. A third, harder number is worth attempting once a year: the number of distinct humans who could, today, cause an artifact to be accepted by any entry in the set. Teams are usually surprised by it, and the surprise is what funds the pruning. ## The organisational call Somebody owns the list, and it should be the platform or product-security function rather than each requesting team, because the value of the set is a property of the whole set and no individual requester can see it. What that owner cannot do is be the only brake: if every addition needs their review and every removal needs their courage, the queue becomes the reason people widen an existing entry instead of adding a narrow one. The workable division is that the central owner sets the rules — metadata required, expiry mandatory, scope minimal, generated where possible — and the teams live inside them.
- What signal tells you an accepted signing identity is dead?Usage. Every successful verification names the identity it accepted, so aggregate that and treat anything unused for a release cycle as a removal candidate. Pair it with an existence check — does the repository resolve, does the issuer still exist, does the owning team — and put the burden on the owner to re-attest rather than on security to prove a negative.
- An acquisition needs its own CI issuer accepted next week. How do you say yes?Say yes with an end date. Add the acquired issuer narrowly — their specific repositories and workflows, not their whole organisation — record a team owner and the cost of migrating to your issuer, and set a review date that is a real deadline with someone accountable for it. The exception is not the mistake; an exception with no owner and no expiry is.
- How do you justify spending engineering time pruning a list that has caused no incident?Frame it as the ability to answer one question truthfully: who can ship into production today. Report two numbers — identities unused for a release cycle, and entries past their review date — and note that a dormant identity whose repository or issuer name can be re-registered is a live path, not a dead one. Pruning is cheap now and forensic archaeology later.
It is the office key cabinet after ten years: everyone remembers who asked for a key, nobody remembers which doors still exist.
saying these in an interview costs you the question
- Adds identities on request and never removes any
- Treats removal as too risky to ever attempt
- Cannot enumerate which identities are accepted today
- Keeps a decommissioned build system's identity just in case
- Assumes an unused accepted identity is harmless