검사를 초록불로 만들려고 서명 열쇠를 넣었다 — 올라오는 모든 코드가 그걸 만질 수 있었다

문제 해결··7분 읽기·

오늘 배울 것 자동으로 도는 작업에 비밀 열쇠를 주기 전에, 그 작업이 누가 올린 코드에서도 도는지 봅니다.

이 글은 이렇게 만들었습니다AI 활용 원칙

  • 나 출시할 만한 수준인지 먼저 묻고, 출시를 막는 것들을 목록으로 만들게 했어요. 두 달 밀린 변경은 쪼개지 않고 합치기로 정했습니다.

  • AI 화면과 설정 화면을 구현했어요. 검사를 통과시키려고 빌드 단계에 서명 열쇠를 넣었다가, 배경의 보안 검토가 그 구조를 지적해 열쇠를 전부 뺐습니다.

결과부터 — 초록불을 얻으려고 넣은 서명 열쇠를, 같은 날 전부 뺐어요

저는 PDF 프로그램을 만들고 있어요. 코드는 AI가 씁니다.

작업일지 2026년 8월 28일, 자동 검사가 처음으로 초록불로 끝났습니다. 저장소 기록상 첫 사례였어요. 윈도우용 설치 파일도 프로젝트 최초로 만들어졌습니다. 17.9MB였어요.

그 과정에 한 가지가 더 있었습니다. 검사를 초록불로 만들려고 빌드 단계에 자동 업데이트 서명 열쇠를 넣었던 거예요. 같은 작업 묶음에서 그 열쇠를 다시 전부 뺐습니다.

지금 그 검사는 서명 없는 설치 파일만 만듭니다. 실제 서명은 버전 꼬리표를 붙일 때만 도는 별도 작업으로 떼기로 했어요. 그건 아직 만들지 않았고, 원칙만 문서에 적어 두었습니다.

무엇이 문제였나 — 설치 파일을 다 만든 뒤에 멈췄어요

이 프로그램에는 자동 업데이트 기능이 코드에 들어가 있습니다. 새 버전 꾸러미에 도장을 찍어 보내는 구조예요. 그 도장이 서명이고, 찍으려면 비밀 열쇠가 필요합니다.

빌드 설정에는 "업데이트 꾸러미도 함께 만들라"가 켜져 있었어요. 그래서 검사는 설치 파일을 다 만든 뒤에 마지막 서명 단계에서 실패했습니다.

그래서 검사를 초록불로 만들려고 빌드 단계에 그 열쇠를 넣었습니다.

검사가 끝까지 돈 것은 열쇠 덕분이 아니었어요. 설정을 "서명 열쇠가 없으면 서명 없이 설치 파일만 만든다"로 바꿔 두고, 다시 돌려 통과시킨 것이었습니다.

문제는 그 검사가 도는 조건이었습니다.

on:
  push:
    branches: [main]        # 내 코드가 본줄기에 올라갈 때
  pull_request:
    branches: [main]        # 그리고 "합쳐 달라"는 요청이 올 때마다

뒤쪽 두 줄이 핵심이에요. 이 검사는 본줄기로 보내는 모든 코드 변경에서 돕니다.

열쇠를 공용 작업실 선반에 올려 둔 것과 비슷합니다. 그 작업실에는 누가 보낸 부품이든 들어오고, 들어온 부품은 자기 조립 설명서를 실행해요.

정확한 뜻은 이래요. 빌드 단계는 바깥에서 받아 온 부품 전체에 딸려 온 스크립트까지 함께 실행합니다. 부품을 프로그램으로 만들 때 같이 도는 스크립트예요. 일지에 적힌 말은 "브랜치에 올라온 코드가 서명키에 접근할 수 있는 위험한 상태"였어요.

비유가 어긋나는 데도 적을게요. 누가 그 열쇠를 가져갔다는 기록은 없습니다. 남은 것은 가져갈 수 있는 자리였다는 구조뿐이에요.

사람들이 끝없이 드나드는 큰 문과, 꼬리표가 붙을 때만 열리는 작은 문. 열쇠는 작은 문 안쪽에 있다
AI로 생성한 설명용 이미지입니다. 실제 화면이 아닙니다.

왜 못 알아봤나 — 초록불을 안전으로 읽었어요

저는 그때 다른 갈림길을 보고 있었습니다. 두 달 밀린 변경을 쪼개서 올릴지, 그대로 합칠지였어요. 쪼개는 실익이 없다는 추천을 받고 그대로 합쳤습니다.

이 구조를 지적한 것은 제가 아니에요. 배경에서 돌던 보안 검토였습니다. 그게 사람이었는지 도구였는지는 기록에 없어요.

"검사가 통과했다"와 "안전하다"는 다른 말입니다. 초록불은 정해 둔 검사와 빌드가 끝까지 돌았다는 뜻이에요. 그 검사 항목에 "비밀 열쇠를 어디에 두었나"는 없습니다.

어떻게 바꿨나 — 네 단계

  1. 검사 설정에서 열쇠 참조를 전부 지웁니다. 이렇게 보이면 성공이에요. 설정 파일 어디에도 비밀값을 꺼내 쓰는 줄이 없습니다.

  2. 조건을 아예 없앱니다. 열쇠가 있는지 없는지 보지 않고, 검사는 항상 서명 없이 설치 파일만 만들게 해요. 업데이트 꾸러미를 만드는 설정을 끈 채로 빌드합니다. 이렇게 보이면 성공입니다. 검사가 초록불인데, 결과물에 서명은 없어요.

  3. 실제 서명은 버전 꼬리표를 붙일 때만 도는 별도 작업으로 떼어 둡니다. 이건 원칙으로 적어 두었을 뿐, 아직 만들지 않았어요. 이렇게 보이면 성공입니다. 검사 설정이 든 폴더에는 지금도 설정 파일 하나만 있습니다.

  4. 문서에 이유까지 못 박습니다. "이 작업에는 서명 열쇠를 넣지 않는다"가 그 문장이에요. 모든 요청에서 돌고, 빌드 단계가 남의 부품에 딸려 온 스크립트를 실행하니까요. 이렇게 보이면 성공이에요. 설정 파일 주석과 안내 문서에도 같은 금지가 남아 있습니다.

자기 것에 쓸 질문은 하나예요. "이 작업은 내가 올린 코드에서만 도나, 올라오는 모든 코드에서 도나?" 뒤쪽이면 비밀 열쇠를 거기에 두지 않습니다.

설치 파일은 처음으로 만들어졌지만, 아직 아무도 그걸 실제로 설치해 보지 않았어요. 만들어진 것과 확인된 것은 다릅니다.

비밀 열쇠를 둘 자리는 "이걸 넣으면 검사가 통과하나"가 아니라 "이게 돌 때 누구의 코드가 같이 돌나"로 정했어요. 초록불은 안전하다는 뜻이 아니었습니다.

용어 풀이

  • 자동 검사(CI) 코드를 올릴 때마다 대신 점검해 주는 검수원이에요. 정확히는 정해 둔 검사와 빌드를 서버가 자동으로 실행하는 장치입니다.

  • 빌드 흩어진 코드를 사람이 바로 쓸 수 있는 프로그램 한 덩어리로 묶는 일이에요. 설치 파일이 그 결과물입니다.

  • 브랜치 본줄기에서 갈라 둔 작업용 가지예요. 여기서 고치다 망가져도 본줄기는 그대로입니다.

  • 합치기 요청(PR) "제가 고친 걸 본줄기에 넣어 주세요"라고 내는 신청서예요. 영어로는 pull request예요.

  • 비밀값(시크릿) 코드에 적지 않고 따로 금고에 맡겨 두는 값이에요. 자동으로 도는 작업이 필요할 때만 꺼내 씁니다.

  • 서명 꾸러미에 찍는 도장이에요. 받는 쪽이 "정말 만든 사람에게서 온 건가"를 확인하는 데 씁니다.

  • 버전 꼬리표(태그) "여기가 1.0이다"라고 붙이는 이름표예요.

공유

댓글

0/2000

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요.