조언 자체는 Hugo답게 훌륭하지만, zizmor 유지보수자로서 현재 워크플로 잠금 파일의 몇 가지 한계를 짚고 싶음.
일반적인 액션 호출만 고정하므로, 재사용 가능한 다른 워크플로를 호출한다면 당분간 직접 해시로 고정해야 함.
복합 액션 자체는 고정되지 않고 이를 호출하는 워크플로를 통해 전이적으로 고정됨. 잠금 파일을 쓰는 호출자는 안전하지만, 현재 gh actions-lock의 기본 동작은 복합 액션 자체의 해시 고정을 제거하므로 안전하지 않음. 외부에서 그 액션을 호출하면 전이 의존성의 고정이 사라지기 때문임.
Docker 이미지 같은 다른 형태의 uses:도 아직 잠금 파일로 고정되지 않음. 액션 내부에서 npx ...를 실행하는 식의 가변성도 남아 있으며, 이런 동작은 GitHub가 막을 수 있는 범위 밖임. 따라서 Actions 구성을 전부 잠갔다고 해서 100% 불변이라고 가정할 수는 없음.
그 외에는 훌륭하고 오래 기다려 온 기능인 만큼, 이런 빈틈도 곧 해결되길 바람.
출처가 기억나지 않는 블로그의 표현을 빌리면, 저장소 소유자가 태그를 옮기지 않을 것이라는 신뢰를, 커밋 해시를 병합하는 사람이 그 해시가 엉뚱한 포크의 커밋이 아니라 원하는 저장소의 릴리스인지 확인했으리라는 신뢰로 바꾸는 셈임. GitHub에서는 모든 포크가 같은 저장소를 공유하므로, 업스트림 병합 여부와 관계없이 어떤 커밋이든 고정할 수 있음.
GitHub는 https://github.com/marketplace에 게시하려면 불변 태그를 반드시 사용하도록 해야 한다고 봄.
Actions 잠금 파일은 이를 막아 줌. 정상 커밋을 사칭하는 커밋은 잠글 수 없으며, 이것이 올바른 기본 동작임. 기존의 해시 고정 방식에는 이 문제가 있어서 추가 검증이 필요했음.
액션이 셸 스크립트를 실행하고, 그 스크립트가 docker pull abc:latest 를 실행하도록 만들 수도 있음. 액션을 사용하는 입장에서는 코드 전체를 뜯어보지 않는 한 이런 동작을 알아내기 매우 어려움.
피하는 것이 특별히 고통스럽지 않다면 GitHub Actions 자체를 피하는 것이 내 주된 조언임. 좋지 않은 전력이 너무 오래 쌓여 있음.
요즘은 원하는 빌드 오케스트레이터로 제대로 된 시스템을 구축하기가 꽤 쉽고 비용도 더 저렴함. 어차피 GitHub에 결과를 보고한다면, 사실상 잃는 것은 약간의 UI 편의성뿐임.
대신 무엇을 추천하나요?
액션을 가져오고 계속 업데이트해야 할 실질적인 필요가 있나요? 대개 Bash 명령 한 줄을 실행하는 것 아닌가요? 정체도 모르는 GitHub 사용자의 불투명한 스크립트를 가져오기보다는, 액션 코드를 설정에 복사해서 완전히 고정하고 직접 통제하겠음.
GitHub Actions는 그렇게 단순하지 않음. 실제로는 그와 거리가 아주 멂.
Bash 명령 하나면 될 것 같은 작업도 실제로는 수십 줄의 난해한 명령과 예외 처리가 필요해지곤 함. 특히 Microsoft를 두고 하는 얘기임. 이런 작업에는 액션이 도움이 됨.
그냥 커밋 SHA 고정을 사용하는 것보다 이 방식을 선호할 명확한 이유가 있나요?
아마 전이 의존성 때문일 것임. 액션 X를 고정해도 그 서드파티 액션이 액션 Y의 SHA를 제대로 고정하지 않았다면, 가변 태그가 악성 커밋으로 옮겨졌을 때 여전히 침해당할 수 있음.
잠금 파일은 직접 의존성과 간접 의존성을 모두 고정하는 것으로 추정함. 아직 확인하지는 않았지만, 그렇지 않다면 이 기능은 쓸모가 없을 것임.
더 깔끔하고 직관적으로 보이는 것은 이해하지만, 워크플로 내부나 선행 단계에서 잠금 파일을 검증하지 않으면 수동 실행이나 act를 통한 로컬 실행 등에서 악성 또는 침해된 액션을 실행할 위험이 여전히 남아 있음.
이상적으로는 러너가 플랫폼 차원에서 처리해야 할 일임. 이것도 SHA 고정과 마찬가지로 우회책에 불과함. 나는 GitHub 같은 공급업체의 공식 액션이나 우리 조직 내부의 포크만 사용함.
고정한 의존성이 자기 의존성은 고정하지 않아서, 악성 코드로 바뀐 태그를 가져오는 것까지 막아 주나요?
막아 주지 않음. foo/setup-latest-go 액션을 고정해도 여전히 최신 Go를 가져오며, 아마 그것이 기대한 동작일 것임.
GitHub는 대신 npm install을 해 주는 것이 아니라 액션의 진입점을 실행할 뿐임. 진입점은 작성된 코드에 따라 무엇이든 할 수 있음.