A service's database password can be resolved by a host helper, a companion process, or the service's own code — what differs?
answer
- same value, three different callers
- who holds the store's address
- identity granularity follows the fetcher
- one machine against one workload
- changing stores: one component or many
basics
~10 sThe credential that arrives is identical; what differs is which component holds the store's address and client, which identity the store authenticates, and how far a compromise of that fetcher reaches.
solid answer
~50 sAll three paths end with the same value in the same process, so the choice is not about the secrecy of the value — it is about where the store dependency lives. A **helper on the host** is installed once per machine and serves every workload on it, so the store sees a machine-shaped identity and application code never learns that a store exists. A **companion process beside the workload** is deployed with that one workload, so the identity is workload-shaped and the application still holds no store client. **The application fetching for itself** couples that service's code to one store's client and address, but it is the only path where the process itself decides which value it wants and when. Where the value rests afterwards, and what the caller presented to be accepted, are separate questions from who made the call.
code
pseudocode · 13 lines// path A - a helper on the host, one per machine
hostHelper.authenticateAs(machineIdentity)
value = hostHelper.fetch("search/db-password")
putWhereTheProcessReadsIt(value)
// path B - a companion process beside this workload
companion.authenticateAs(workloadIdentity)
value = companion.fetch("search/db-password")
handToWorkload(value)
// path C - the service itself; address and client live in the service
store = connect(STORE_ADDRESS, workloadIdentity)
value = store.read("search/db-password")go deeper
Recall that one credential can reach a process by three different routes — a helper on the host, a companion beside the workload, or the service's own code — and that the value itself is the same either way.
Explain which component holds the store's address and client in each path, and which identity the store therefore authenticates. Name a concrete cost: a store migration touches one component per host, or every service.
Judge the path against the estate you actually run — host uniformity, how many teams would carry a client library, how far one compromised fetcher reaches. Be able to state what the path does not decide.
Weigh who owns the fetcher for years. A shared helper is a platform dependency your team is paged for; a client in every service pushes the cost onto teams and turns the next change into a programme.
## Three paths, one value A customer-facing search service needs the password for its database. The store already holds that value and has already agreed to release it to a caller it accepts. What is left is a design question that estates answer three different ways: **which component actually makes the call**. - **A helper on the host.** A long-running process installed once per machine, outside any single workload. It resolves values and puts them where the workloads on that machine will read them. - **A companion process beside the workload.** Deployed and retired with the workload it serves, one instance per workload instance, doing nothing else. - **The application fetching for itself.** The service's own code opens a connection to the store at start-up and reads the names it needs. The credential that arrives is the same in all three cases. Its scope, its validity and what it unlocks downstream were fixed when it was stored or issued, and no fetcher changes them. What moves between the three is **coupling**, the **identity the store authenticates**, and the **reach of the fetcher itself**. ## What actually differs | | Helper on the host | Companion process | The application itself | |---|---|---|---| | Deployed by | the platform, once per machine | the workload's own deployment | the service's own build | | Identity the store authenticates | machine-shaped | workload-shaped | workload-shaped | | Where the store's address lives | in the helper | in the companion | in the service | | Store client in application code | none | none | yes, plus a dependency to keep current | | Serves | every workload on that host | one workload | itself | | Moving to another store | change one component per host | change the companion's deployment | change every service | | Can ask for a name chosen at run time | no, not without being told in advance | no, not without being told in advance | yes | ## Why the fetcher's reach is the interesting number A helper that serves twenty workloads on a machine needs a grant at the store that is the **union** of what those twenty need. That union is the ceiling on what anyone who can reach the helper's local interface can obtain, unless the helper distinguishes its local callers and asks only for their names — and the store can scope the release accordingly. A companion serving one workload has one workload's set as its ceiling. A self-fetching service usually has the narrowest grant of the three, because the grant was written for that one service, and pays for it by leaving a working client and a valid identity inside the process. Note which way round that runs. Proving **who** is calling and deciding **what** that caller may read are separate steps. A path that authenticates crisply and then authorises with a broad grant is the common real defect, and it is the fetcher's grant — not the elegance of the path — that sets the reach. ## What the choice does not decide 1. **Not what the value is worth.** The same credential opens the same database whoever collected it. 2. **Not where it rests afterwards.** A rendered file on disk, an inherited environment value, a block of process memory — any fetcher can lead to any of them, and that resting place is its own subject with its own leak paths. 3. **Not what the caller presented.** How a fetcher proves it is entitled to be answered, and what the store hands back once it is accepted, are a different question again. 4. **Not what happens when the store does not answer.** Whether a restarting workload refuses to start or comes up on a value it already had is a decision about the consumer, not about who fetches. ## Choosing in a real estate - **A uniform fleet you own** favours a host helper: one component to operate, nothing in anyone's code, one place to change when the store changes. - **Workloads with very different entitlements on the same machine** favour a companion, because it stops one grant having to cover all of them. - **A service that only knows at run time which name it needs** — per tenant, per request, per job — has no real alternative to fetching for itself, because no outside fetcher can resolve a name it has not been told. - **Many teams on many release cadences** argues against a client in every service, because the next store or address change becomes a migration across all of them rather than a rollout. The answer an interviewer is listening for is not a favourite. It is that the value is identical, that the coupling and the identity are what actually move, and that you can name which component you would have to change to move stores.
- If the estate moves to a different secret store, what changes under each of the three paths?Under a host helper, the helper changes on each machine and no service is touched. Under a companion, the companion's deployment changes wherever it runs. Under self-fetch, every service's code and dependencies change, on every team's own release cadence — which is why that migration is counted in quarters rather than deployments.
- Does the fetch path change what the credential is worth to whoever ends up holding it?No. Its scope and what it unlocks downstream were set when the store issued or stored it, not by who collected it. What the path changes is which identity could have asked for it, what else that identity may ask for, and which component you have to trust.
- Which path leaves application code unaware that a secret store exists at all?Both the host helper and the companion: each resolves the value and puts it where the process already expects to find an input, so the code reads a plain configuration value. That is also the trade — neither can resolve a name the service only chooses at run time.
Three ways a parcel reaches a desk: a mailroom serving the whole building, a courier assigned to one office, or the recipient walking to the depot. The parcel is the same; who holds the depot's address is not.
saying these in an interview costs you the question
- Says the application must fetch its own secrets to be secure
- Thinks a host-wide helper gives each workload a separate identity
- Treats all three paths as equally coupled to the store
- Believes a helper makes the fetched value itself safer
- Says moving stores is a code change whichever path you chose