A postinstall hook runs on a CI runner holding a production deploy role - what is the blast radius?
answer
- the hook is the job
- environment secrets, cloud role, clone token
- install runs before tests and gates
- masking hides logs, not the environment
- it can deploy without touching the artifact
basics
~20 sEverything the job can reach: injected secrets in the environment, the short-lived credentials behind the deploy role, the source checkout, caches it writes and outbound network. The hook runs before any test, so production access is available to it from the start.
solid answer
~50 sAssume the hook has whatever the job has. That is the environment block with every injected secret, any short-lived cloud credential minted for the deploy role, the token used to clone, the checked-out source, whatever caches or workspaces the job writes, and outbound network access. It also has timing on its side: dependency installation is the first substantial step, so it runs before the tests, the scanners and the approval gates people imagine are protecting them. The sharpest consequence is that a hook holding a deploy role does not need to tamper with the artifact at all - it can just deploy, or mint further credentials, and the artifact you later sign will look perfect. The structural conclusion is that the step which installs untrusted dependencies must not be the step that holds a production identity: separate resolve-and-build from the privileged push, so the credential is simply absent while third-party code is executing.
go deeper
Know that an install hook runs with the build job's own access, so any secret the job was given is a secret the hook can read.
Enumerate the reach concretely - environment secrets, workload credentials, clone token, checkout, caches, network - and place installation before tests and scans in the pipeline order.
Demonstrate the leap: with a deploy role available, the artifact is optional, and every artifact-integrity control still passes. Then propose separating the install step from the step holding production identity.
Own the policy that privilege is scoped per step across the estate, and be ready to justify the friction that splitting build from deploy imposes on hundreds of pipelines.
## Start from the job, not from the package The useful way to answer a blast-radius question is to stop reasoning about the malicious package and enumerate what the job itself can reach, because the hook inherits all of it. On a typical build runner that is: - **The environment block.** Every secret the pipeline injected as a variable. Note that log masking is redaction of output, not access control - a masked secret is still readable in the process environment. - **Workload credentials.** A short-lived token minted for the job's cloud role, or a long-lived key on a persistent host. If the job is allowed to deploy, so is the hook. - **The repository token** used to clone, which frequently carries more than read access. - **The source checkout**, including anything the job wrote before installation, and any build configuration the hook can amend to affect later steps. - **Caches and workspaces** the job may write, which is a route to influencing something after this job ends. - **Outbound network**, unless something outside the package manager constrains it. - **Registry credentials**, if the job is also the job that publishes. Everything in that list is available at the moment the hook starts. ## Ordering is the multiplier Dependency installation happens first, because everything downstream needs a resolved tree. That means the hook precedes unit tests, integration tests, the dependency scan, the artifact scan, the signing step and any human approval. Every control people cite as their defence is downstream of the event. Worse, a hook that is careful can leave the rest of the pipeline completely green: it does its work, exits zero, and the build proceeds normally. ## The insight most candidates miss: the artifact is optional Interviewers probe this deliberately. If the hook can reach a deploy role, it does not need to poison the artifact. It can deploy directly, or create a new identity, or attach a policy, and skip the build entirely. That matters because it defeats the artifact-centric controls by construction: - An **SBOM** says what is inside the artifact. It says nothing about what a process on the build host did with a cloud credential. - **Provenance** says how the artifact came to be. If the build was compromised, provenance faithfully attests a compromised build - it records the process honestly, it does not judge it. - A **signature** says who vouches for the artifact. Your pipeline still vouches; nothing about the signature is wrong. All three are working as designed. None of them is a statement about the build host's credentials, which is what was actually taken. ## What actually reduces it Within the scope of the install step, the lever is the credential, not the package. The install of third-party dependencies should happen in a step, and ideally a job, that holds no production identity: resolve and build with nothing but read access to a package source, publish the result, and let a separate step with the deploy role consume that result. Then a hook runs in a context where there is no deploy credential to steal, and the privileged step never executes untrusted install code. The same reasoning applies to registry publishing credentials and to repository tokens with write scope. The complementary questions - how the runner itself is contained between jobs, what egress it is permitted, and what you do once you believe hooks have already run - are their own disciplines and their own decisions. What belongs to this analysis is the simple, uncomfortable statement of reach: on an unmodified runner, an install hook is the job. ## Detection Because the hook can be silent and the pipeline stays green, detection rarely comes from the build. It comes from the far side: an audit trail showing the deploy role acting at a time that does not correspond to a deploy, a principal creating credentials, a token used from an unexpected place, or the deployed revision not matching what the pipeline recorded. Being able to say where you would look - and that you would look at the credential's audit trail rather than at test results - is most of the answer to the follow-up. ## How to say it in an interview Enumerate reach, state the ordering, then deliver the two sentences that show seniority: the attacker does not need your artifact if they have your deploy role, and the artifact-integrity controls will all pass while it happens. Then give the structural fix - the step that runs untrusted install code and the step that holds production identity are not the same step.
- The hook exfiltrates nothing and simply deploys. How would you ever notice?Not from the build, which stays green, and not from artifact integrity, which is intact. You notice from the credential's own audit trail: the deploy role acting at a moment with no corresponding pipeline stage, an unexpected principal or source address, a new identity created, or the running revision disagreeing with what the pipeline recorded as deployed.
- Would signing the artifact and publishing provenance have prevented this?No, and the reason matters. A signature says who vouches for the artifact and provenance says how it was produced; both would be issued correctly here. Provenance describing a compromised build is accurate provenance. Neither is a statement about what a process on the build host did with a deploy credential.
- Why does moving the dependency scan earlier not fix the ordering?Because the scan needs a resolved tree, and producing that tree is what runs the hooks. To inspect before execution you have to resolve or fetch without installing, or gate on the name and version before the install runs at all. Reordering steps that all depend on installation does not change what came first.
- Secrets are masked in this pipeline's logs. Does that limit the hook?Not at all. Masking is post-processing on output text so that a secret is not printed. The variable is still present in the process environment the hook inherits, and the hook is free to use it directly or encode it before printing. Masking is a hygiene measure against accidental disclosure, not a boundary.
saying these in an interview costs you the question
- Says the tests or code review would have caught it
- Assumes the hook can only affect the artifact it built
- Claims artifact signing prevents credential theft on the runner
- Thinks masked secrets are hidden from the install process
- Assumes damage requires the hook to phone home