Look at what your build can do.
It can read the whole repository.
It can reach the registry.
It can sign things.
It can talk to production
without being asked twice.
No person on the team
has that much reach.
The most privileged identity
you own
is not a person at all.
It is a machine that runs
whatever the configuration file says,
in a container you have never opened,
on a schedule you forgot you set.
And it is usually the least guarded
thing you have.
Think about how a change
gets into it.
Someone edits a file
in the repository.
That is it.
The pipeline definition is code,
but it is often code
nobody reviews with the care
they give a login screen,
even though it holds keys
the login screen never sees.
Think about what it pulls in.
An action pinned to a moving tag.
A container tagged latest.
A script fetched at run time
from a URL that belongs
to someone you will never meet.
Each of those is a stranger
with your credentials.
Not in theory.
At the moment the job runs.
So treat the build like production,
because it is upstream of production,
which makes it worse.
Pin things to something
that cannot change under you.
Keep the secrets that deploy
away from the jobs
that run untrusted code,
and pull requests from outside
are untrusted code.
Give the job the narrowest token
that still lets it finish,
scoped to one thing,
short lived,
and replaceable without a meeting.
Keep the logs,
and read them once
while nothing is wrong,
so you know what normal looks like.
And ask the question
nobody likes asking.
If an attacker had your pipeline
for one hour,
what could they ship,
and would anybody notice
before the customers did?
The honest answer
is your real security posture.
Everything else is the part
you put on the slide.
– Serguey Asael Shinder
Top comments (0)