Merge requests from a contracted partner's fork run on your internal-network CI runners. What do you change, and what do you accept?
answer
- trust the relationship, not the pipeline
- compromise, not intent, is the threat
- pick a tier: outside or inside
- swap network position for scoped staging
- contracts shift blame, not execution
basics
~20 sA contract is not a technical control. Run partner merge requests like any untrusted fork: no credentials, disposable runners, no internal network position. If they genuinely need internal access, bring them inside the repository where it can be scoped and audited.
solid answer
~50 sFirst, name the threat honestly: it is not that the partner is malicious, it is that their accounts and their own build chain can be compromised, and the contract does nothing to stop that. Then pick a coherent tier rather than drifting. Either they stay outside — merge-request pipelines run with no secrets on disposable runners with no route into internal networks and restricted egress — or you bring them inside, giving named individuals a branch in your repository with narrow rights, which converts an anonymous fork run into an attributable, revocable insider you can log. What you must not do is keep the internal network position and put an approval step in front of it, because that trades a technical boundary for human attention. If the partner's tests genuinely need an internal service, give them a scoped staging endpoint and a per-partner short-lived credential instead of network reachability. Accept that the residual risk is yours, not theirs.
go deeper
Understand that a known, paid partner is still an outside party as far as a pipeline is concerned, and that their code should not run where secrets or internal systems are reachable.
Explain why the threat is compromise rather than intent, and describe the credential-free, network-isolated shape a partner's merge-request pipeline should have.
Show the alternative to network access — scoped staging endpoint, per-partner short-lived credential, egress allowlist — and how you would find every pipeline in the estate that still has internal reachability from an outside trigger.
Own the trust-tier decision and its cost: choose deliberately between keeping the partner outside or bringing them inside as attributable identities, say who holds the residual risk, and refuse the middle option that swaps a network boundary for human attention.
## The situation An integration partner develops against your repository and contributes through merge requests from their own fork. Because their tests need to talk to an internal service, the merge-request pipelines were pointed at self-hosted runners that sit inside your network. Everyone is comfortable, because there is a signed contract and a named account manager. This is one of the most common ways an organisation ends up with anonymous-quality exposure at insider-quality trust. ## Separate the threat from the relationship The useful reframing is that the partner's *intent* is not the variable. The variables are: - **their account security** — a phished or credential-stuffed developer account at the partner is now a trigger for pipelines that run inside your network; - **their own supply chain** — a compromised dependency or build tool on their side reaches your runners through the code they propose; - **their offboarding hygiene** — a departed contractor whose access nobody revoked; - **your own configuration drift** — a runner tagged for partner work that also picks up a job with credentials. Against all four, the contract is a *reporting and remedy* instrument, not a control. It changes who pays afterwards. It does not change what executes. And note where the exposure lands: not customer data in a database, but **the internal network position of the build fleet** — service endpoints, metadata services, admin interfaces and lateral movement paths that were never designed to face an outsider's code. ## Choose a tier, and make it explicit The defensible designs are at the two ends; the muddle in the middle is what fails. **Option A — treat them as strangers.** Partner merge requests run exactly like anonymous fork contributions: no secrets, disposable single-use runners, no internal routes, egress restricted to what a build genuinely needs. The cost is that some of their integration tests cannot run, which you solve with data rather than with access (below). The gain is that the partner's security posture stops being part of your attack surface. **Option B — bring them inside.** Named individuals get accounts in your organisation and a branch in your repository, scoped to the paths they work on. This feels like more access, and in a narrow sense it is — but it converts an anonymous, unattributable fork run into an identified user whose actions are logged, whose access is revocable in one place, and whose sessions you can require multi-factor authentication for. You have traded an outsider you cannot see for an insider you can. For a long-running contracted relationship, that is very often the better trade, and it removes the pressure to build a special credentialed fork pipeline in the first place. **The muddle to reject:** keeping the internal runners and adding a maintainer approval in front of the pipeline. That substitutes human attention for a network boundary, at exactly the cadence — dozens of routine merge requests a week from a trusted-feeling partner — where attention is guaranteed to lapse. ## Replace network position with a scoped surface The reason the runners are inside is almost always one requirement: the tests need to reach an internal API. Solve that requirement directly. - Stand up a dedicated staging instance of that service with synthetic data, reachable from outside the internal network. - Issue a per-partner, short-lived credential to it, scoped to the operations the tests need, and revocable independently of everything else. - Restrict the runner's egress to that endpoint and the package sources the build needs. Now a compromise of the partner's pipeline yields a synthetic-data staging service, not a foothold on your internal network — and you can revoke it in one action without touching the repository relationship. ## What the contract should carry, and what it should not be asked to do Ask for things that improve your *detection and response*: mandatory multi-factor authentication for accounts touching your repository, a named contact and an obligation to notify you promptly of a compromise, a list of individuals with access reviewed on a schedule, and the right to revoke immediately without it being a commercial event. Do not write in clauses that pretend to be controls — "the partner shall not introduce malicious code" protects nobody. And be clear internally about risk ownership: if their compromise becomes your incident, the risk is yours to hold and yours to fund, whatever the indemnity says. ## What to measure One metric carries most of this: **the number of pipelines that can be triggered by a party outside your organisation and that hold either credentials or internal network reachability.** Drive it to zero, review it when a new partner is onboarded, and re-check it after every runner-pool change. A second, softer signal: how often someone requests an exception, which tells you whether the credential-free path is genuinely usable or whether you are pushing teams toward workarounds. ## Interview shape The answer that lands separates trust in a *relationship* from trust in a *pipeline*, picks a tier deliberately, offers the scoped-staging alternative to network access, and states plainly that the contract manages consequences rather than preventing execution. A candidate who says "they are a partner, so it is fine" — or who adds an approval step and keeps the internal runners — has missed both halves.
- Why can giving the partner accounts inside your organisation be safer than leaving them on forks?Because it makes them attributable and revocable. Named accounts carry authentication requirements, produce audit records, can be scoped to branches and paths, and can be cut off in one action. It also removes the temptation to build a special credentialed pipeline for fork contributions, which is where the real exposure usually comes from.
- The partner insists their tests must reach an internal API. What do you offer instead?A dedicated staging instance with synthetic data, reachable from outside, with a per-partner short-lived credential scoped to the operations the tests need, plus an egress allowlist on the runner. They get a working test; you get a blast radius that stops at a disposable environment you can revoke independently.
- What belongs in the contract, and what should never be treated as a control?Ask for multi-factor authentication on accounts touching your repository, prompt breach notification, a reviewed list of named individuals, and an unconditional right to revoke. Do not treat any clause as preventing execution — a promise not to introduce malicious code does nothing against a compromised account. Contracts allocate consequences; pipeline design decides what runs.
- How do you know the policy is holding six months later?Track one number: pipelines triggerable by someone outside your organisation that hold credentials or internal network reachability. Re-derive it from configuration rather than from memory, review it on partner onboarding and after runner-pool changes, and watch the exception request rate as a signal that the safe path has become unusable.
saying these in an interview costs you the question
- Treats a signed contract as a technical control
- Grants secrets because the partner is paid and known
- Assumes vendor compromise is the vendor's risk to own
- Keeps internal network position and adds an approval step
- Never states which trust tier the partner is in