Adopt or build: a single-maintainer crate would sign payment settlements through an HSM?
answer
- ask what it can do if it turns hostile
- bus factor one means no second review
- how much of it do you actually use
- building a parser is its own risk
- put the control below the dependency
basics
~20 sDecide on blast radius and on what compromising that maintainer would later buy an attacker. This code sits on the path that authorises money movement, so either fund real review and vendor it, or write only the narrow part you need.
solid answer
~50 sI would not treat this as a matter of taste — I would ask what the dependency can do on the day its maintainer is compromised. A crate that talks to the HSM sits inside the settlement-signing path, so a malicious update could sign an instruction we never issued or exfiltrate material it handles. A bus factor of one means such an update ships with no second pair of eyes. That does not automatically mean build: cryptographic plumbing written badly is its own vulnerability. So the decision turns on how much of the crate we actually use. If it is a thin wrapper over a documented interface, writing or vendoring the narrow subset we need is realistic and reviewable. If it is thousands of lines of protocol handling, adopt but fund it: pin to a reviewed revision, diff every upgrade, and make the HSM's own per-key authorisation and limits mean a compromised library still cannot sign arbitrarily.
go deeper
Know that adopting a dependency is a trust decision, not just a convenience one, and that the first questions are how much of the library you need and what it will be allowed to touch.
Explain concretely what a bus factor of one changes — no second review before a release ships, and one person as the whole fix pipeline — without treating it as automatic disqualification.
Reason from blast radius, name the cases where writing it yourself is worse than adopting, and place compensating controls beneath the dependency so they still hold if the dependency is the attacker.
Own the standard: which categories of dependency your organisation will never accept from a single publisher without funded review, what you will pay to reduce that exposure, and how the decision gets revisited.
## Framing the decision correctly "Build or adopt" is usually argued as a productivity question. For a dependency on the settlement-signing path it is a trust question, and the right frame is: *what does this code let someone do if it turns hostile, and which choice leaves me with a smaller, more reviewable problem?* The asset here is not customer data. It is signing authority over money movement, plus the integrity of an audit trail that says who authorised what. The threat actor to model is not an anonymous internet attacker — it is the dependency itself becoming hostile, whether through a compromised maintainer account, a coerced maintainer, or a transfer of the project to someone new. ## What a bus factor of one actually costs you One maintainer means one review path: whatever that person publishes is what you receive, with no second signature on the change. It also means one point of failure for fixes — if they are unavailable when a flaw is reported, nothing ships. Neither fact makes the code bad today. Enormous amounts of infrastructure sit on single-maintainer packages, and treating that as automatic disqualification would leave you unable to build anything. What it does mean is that the *future risk position* changes: you are accepting that the safety of your signing path depends on one person's account hygiene and continued goodwill, indefinitely, and that a bad release would arrive with no internal signal. ## Why "just write it ourselves" is not automatically safer The naive move is to rewrite. That is right sometimes and badly wrong other times. It is right when the library is a thin translation layer over a well-documented interface, when you use a small fraction of it, and when the code you would write is small enough to review in full and test against real hardware. Then building removes an entire trust relationship and replaces it with code you own, in exchange for a modest amount of work. It is wrong when the domain is hostile-input parsing or unforgiving cryptographic detail. Writing your own parser for a complex document or protocol format means creating fresh flaws that nobody has ever fuzzed, without the ecosystem's fix pipeline, and typically with less scrutiny than the library you rejected. Owning a decade of somebody else's disclosed parser bugs is unpleasant; owning an undisclosed set of your own is worse. The honest answer in that class is *adopt and contain*: keep the library, but run it where its compromise is bounded — an isolated process, no outbound network, least privilege, resource limits. ## The decision path 1. **How much of it do we use?** If one entry point out of forty, the surface you need may be small enough to write or to vendor as a trimmed copy you review once. 2. **How hard is the thing it does?** A documented request/response interface is writable. Protocol state machines, key derivation and parsing of attacker-controlled bytes are not, casually. 3. **What can it reach at runtime?** Keys, network, filesystem, the audit log. Reduce these before deciding, because a bounded dependency is a cheaper dependency. 4. **What compensating controls survive its compromise?** This is the most senior part of the answer. If the HSM enforces per-key authorisation policy, transaction limits and its own tamper-evident audit log, then a hostile library cannot mint arbitrary settlement instructions — it can only attempt what the policy already permits, and the attempt is visible. Controls that live *below* the dependency are the ones that still work when the dependency is the attacker. 5. **What is our upgrade discipline afterwards?** Pinning to an exact reviewed revision means a hostile release does not reach you automatically — but only until someone upgrades. So the pin has to come with a rule: this dependency's upgrades get a diff read and a second approver, not a routine bump. ## Recording the decision Whichever way it goes, write down what you assessed, what you assumed, which compensating controls the decision depends on, and what would invalidate it — the maintainer changing, ownership transferring, the crate growing well past the narrow job you adopted it for, or the hardware policy being relaxed. Give it an owner and a date to revisit. A vetting decision with no recorded assumptions cannot be re-evaluated later; it can only be re-argued from scratch, usually during an incident. ## The answer an interviewer is listening for Not "reject single-maintainer packages" and not "never reinvent the wheel". They want to hear you reason from blast radius, name what building actually costs, and put the durable control below the dependency rather than inside it.
- Give a case where building it yourself is clearly the riskier choice.A document-rendering library for a signing product. Adopting means inheriting years of disclosed parser flaws in code that handles hostile input — but writing your own parser means creating fresh ones that nobody has fuzzed, with no ecosystem fix pipeline behind them. When the job is parsing attacker-controlled formats, the right move is adopt and contain: keep the library, isolate the process, drop its privileges, and cap what it can consume.
- You adopt it. Which compensating controls make a maintainer compromise survivable?Pin to a specific reviewed revision and require a diff read plus a second approver for any upgrade of that dependency. Run the signing path in an isolated process with no outbound network. Push authorisation into the hardware — per-key policy, transaction limits, a tamper-evident log — so a hostile library cannot exceed what policy already allows. Alert on unexpected signing volume, and keep a tested way back.
- How do you write this decision down so it can be revisited rather than re-argued?Record what you assessed, the assumptions it rests on — thin wrapper, one maintainer, hardware enforces limits — the compensating controls it depends on, and the events that invalidate it: maintainer change, ownership transfer, the crate expanding beyond its original scope, or the hardware policy being loosened. Attach an owner and a review date.
saying these in an interview costs you the question
- Rejects any single-maintainer dependency on principle
- Assumes writing it in-house is automatically safer
- Judges by download count rather than by what the code can reach
- Never asks how much of the library is actually used
- Thinks pinning removes the risk, forgetting upgrades still happen
- Puts every control inside the dependency it does not trust