Claude Code를 팀에 들이려는데 IDE, 터미널, PR, 클라우드 중 어디서 굴려야 할지 막히셨죠. 작업 범위와 저장소에 맞는 워크플로우를 바로 고를 수 있게 정리해 둘게요.

결론부터 말하면, 승인 방식으로 고르면 돼요

2026년 10월 기준이고, 특정 버전에 의존하지 않는 워크플로우 유형 분류 수준의 이야기예요.

이런 문장을 검색창에 넣고 계셨다면 제대로 찾아오신 거예요. 실제 에러 메시지로 뜨는 출력은 없고, 증상을 재구성한 예시예요.

어떤 AI 코딩 에이전트 워크플로우를 써야 할지 모르겠다
터미널은 단계마다 승인하라는데, 클라우드는 나중에 브랜치나 PR로 보고한다

Claude Code를 팀 저장소에 들이려고 IDE, 터미널, PR, 클라우드 유형을 나란히 놓으면 이런 막막함이 생기죠. 유형마다 자율성과 승인 방식이 달라서 어느 쪽을 골라야 할지 기준이 서지 않거든요.

Claude Code는 터미널·IDE·클라우드·PR 네 가지를 모두 다뤄요. 유형마다 달라지는 건 승인 방식이에요. IDE는 수정마다 수락/거절하고, 터미널은 단계마다 승인해요.

PR은 비동기로 리뷰하고, 클라우드는 브랜치나 PR로 결과를 보고하죠. 그러니 작업을 지켜볼 수 있는지, 저장소가 얼마나 민감한지에 맞춰 승인 방식부터 고르면 돼요.

승인 지점을 따라 고르는 순서

1. 네 유형은 같은 루프를 돌아요

헷갈리는 이유부터 짚고 갈게요. 네 유형 모두 Read, Reason, Act, Evaluate 루프를 돌아요. 파일을 읽고, 할 일을 판단하고, 파일을 고치거나 명령을 실행하고, 결과를 확인하는 흐름이에요.

에이전트가 하는 일은 어느 유형이든 같고, 다른 건 이 루프 사이에 사람이 끼어드는 자리뿐이에요. 그 자리가 에디터, 셸, PR, 원격 환경으로 갈리다 보니 같은 도구인데도 쓰는 느낌이 전혀 다르게 느껴지는 거죠. 그래서 유형을 고를 때 볼 건 하나예요.

사람이 어느 지점에서 승인하느냐.

2. 내 작업과 가장 가까운 줄 고르기

아래 표에서 내 작업과 가장 가까운 줄을 골라 보세요. 이 네 가지 분류는 Real Python 가이드 같은 커뮤니티·블로그 자료를 따른 것이라 공식 규격은 아니에요.

유형 실행 위치 승인 방식
IDE 에이전트 코드 에디터 안 인라인 diff를 수정마다 수락/거절
터미널 에이전트 셸 단계마다 승인/거절
PR 에이전트 PR 열림·업데이트 시 자동 실행 비동기, 코멘트와 수정 제안을 사람이 리뷰
클라우드 에이전트 원격·관리형 환경 자율성이 가장 높고, 나중에 브랜치·PR·프로토타입으로 보고

3. 화면 앞에서 지켜볼 수 있나요?

한 줄로 좁혀지지 않는다면 이 질문 하나로 갈라 보세요. 작업하는 동안 내가 화면 앞에서 지켜볼 수 있나요?

  • 지켜보면서 바로 판단할 수 있는 작업이면 IDE나 터미널
  • 지켜보지 않아도 되고 결과만 리뷰하면 되는 작업이면 PR이나 클라우드

터미널을 골랐다면 자주 하는 실수가 하나 있어요. 단계마다 승인이나 거절을 요구하니까 어느 순간부터 내용을 읽지 않고 습관처럼 수락을 누르게 되는데, 그러면 승인 모델이 의미를 잃어요. 명령 실행과 파일 수정 단계는 내용을 확인한 뒤에 승인하세요. 습관처럼 누를 거라면 굳이 터미널을 고를 이유가 없다고 봐요.

PR 에이전트는 반대로 실시간으로 지켜볼 필요가 없어요. PR이 열리거나 업데이트될 때 자동으로 돌고, 사람은 나중에 코멘트와 수정 제안을 비동기로 확인하면 되거든요. 다만 제안을 반영할지는 리뷰어가 정해야 해요.

4. 팀·사내 저장소는 승인이 촘촘한 쪽에서 시작하기

가장 신경 써야 할 단계가 여기예요. 사내 저장소라면 사람이 개입하는 지점이 많은 IDE나 터미널로 시작하고, 자율성은 한 단계씩만 올리세요. 예를 들어 터미널에서 단계별 승인으로 시작한 뒤 결과 품질을 보고 PR 리뷰를 붙이고, 그다음 범위가 작은 작업부터 클라우드에 맡기는 순서를 생각해 볼 수 있어요. 이 순서는 하나의 예시이니 팀 상황에 맞게 바꾸면 돼요.

클라우드까지 왔다면 챙길 게 두 가지 있어요.

먼저 회사 정책이에요. 클라우드 에이전트는 벤더가 관리하는 인프라에서 도는 경우가 많고, 보안이나 컴플라이언스 때문에 막아 둔 조직도 있어요. 사내 코드를 정책 확인 없이 맡기는 게 흔한 실수인데요, 사내 저장소에 쓰기 전에 회사 정책부터 확인하세요. 직접 관리하는 머신에서 돌릴 수 있는 에이전트도 있으니 그쪽도 함께 알아보면 되고요.

다음은 결과 검토예요. 클라우드 에이전트의 결과물은 브랜치나 PR로 돌아오는데, 이걸 검토 없이 믿는 실수도 자주 나와요. GitHub Copilot cloud agent를 예로 들면, PR을 스스로 머지하지 못하는 기본 가드레일이 있어요.

하지만 이건 Copilot 기준이라 Claude Code on the web에도 똑같이 적용된다고 볼 수 없죠. Claude Code의 머지 권한은 Anthropic 공식 문서에서 확인하세요. 어느 쪽이든 가드레일을 믿고 대충 넘기지 말고, 머지 전에 사람이 diff를 직접 리뷰하세요. 이 리뷰를 필수 단계로 두면 승인 모델이 유지돼요.

사내 저장소라면 이 단계만큼은 예외 없이 못 박아 두는 게 나아 보여요.

5. 고른 유형을 Claude Code 기능에 연결하기

이제 고른 유형을 Claude Code의 진입점에 대응시키면 돼요. Claude Code는 네 유형을 모두 다룬다고 알려져 있어요.

유형 Claude Code 대응
터미널 에이전트 셸에서 돌리는 Claude Code 본체
IDE 에이전트 VS Code, JetBrains 연동
PR 에이전트 Code Review, Claude Code GitHub Actions
클라우드 에이전트 Claude Code on the web

이 대응은 벤더와 가까운 출처에서 나온 정보예요. 사내 저장소에 적용하기 전에 Anthropic 공식 문서에서 각 기능의 현재 제공 상태와 권한 범위를 확인하세요. 설정 방법도 Anthropic 공식 문서를 참고하면 돼요.

Copilot과 견줘 보고 있다면

Claude Code와 GitHub Copilot 중 뭐가 더 나은지도 궁금하실 텐데요. 이 글의 재료에는 가격, 벤치마크, 품질을 직접 비교한 데이터가 없어서 성능 우열은 말할 수 없어요. 숫자로 견줄 근거가 없다는 점은 좀 아쉽네요.

대신 기준은 분명해요. 워크플로우 적합성과 거버넌스죠. Copilot은 GitHub에 통합되어 있어 라이선스와 거버넌스가 단순하다는 점이 장점이에요.

이미 GitHub 중심으로 운영하는 팀이라면 이 부분을 먼저 따져 보세요.

정리

  • 네 가지 유형(IDE, 터미널, PR, 클라우드)의 공통 루프와 승인 방식 차이 확인
  • 작업 범위와 저장소 민감도에 맞춰 승인 단위가 촘촘한 유형부터 선택
  • Claude Code 지원 범위와 사내 저장소 적용 전 Anthropic 공식 문서 확인

참고 자료

이 글은 공개 자료를 바탕으로 생성형 AI를 활용해 작성했어요.

Posted by 튼튼한노예
,

로그인 없이 원격 코드 실행이 된다는 PHP 취약점 경고가 떴죠. 그런데 당장 패치가 어려운 서버도 있을 거예요. 내 환경이 해당되는지 판별하는 법과 오늘 할 조치를 이 글에 한 번에 정리했어요.

결론부터

2026년 11월 기준이에요. CVE-2026-109618, 109619는 로그인 없이 원격 코드 실행이 가능한 CVSS 9.2 취약점이에요. 쓰는 계열의 수정 릴리스(8.3이면 8.3.36 이상)로 올리고 PHP 실행 서비스를 전부 재시작하면 해결되죠. 8.1 이하는 공식 패치가 없어서 8.3 이상으로 이전해야 해요.

패치가 당장 어렵다면 아래 두 값을 쓸 수 있는데요, 어디까지나 부분 완화예요.

session.upload_progress.enabled = 0
memory_limit = -1

로그에 이런 흔적이 보인다면

보안 공지를 받고 서버 로그를 열었는데 아래 흔적이 있다면 이 취약점을 의심해 볼 만해요. 로그 문구는 환경마다 달라요. 정확한 문장 말고 패턴으로 찾으세요.

  • PHP 페이지로 들어온 비정상적으로 큰 요청, 그 뒤에 반복되는 HTTP 500
  • 원인을 알 수 없는 PHP 프로그램 재시작이나 비정상 종료(segfault)
  • 메모리 부족 오류

확인할 곳은 Apache, PHP-FPM 같은 PHP 실행 환경의 에러 로그예요. 다만 이 증상만으로 공격을 확정할 수는 없어요. 그래도 흔적이 있다면 비밀번호, 토큰, API 키 교체를 검토하세요.

이 취약점은 서버 메모리에 있던 비밀번호, 접속 토큰, 외부 서비스 API 키를 유출시킬 수 있거든요. 패치는 앞으로의 공격만 막아 줘요. 공격 흔적이 의심된다면 패치를 끝냈더라도, 이미 새어 나갔을 수 있는 값은 별도로 교체하는 쪽이 안전하죠.

오늘 할 조치: 확인부터 검증까지

순서는 버전 확인, 업데이트, 재시작, 검증이에요. 패치가 정말 불가능한 서버만 마지막 5단계로 가면 돼요.

1. 내 PHP 버전 확인

먼저 서버의 PHP 버전을 봐요.

php -v

버전 숫자만 보지 말고 계열부터 찾은 다음, 아래 표의 수정 버전과 비교하세요. 계열마다 기준이 다르거든요. 그리고 CLI에서 보이는 버전이 웹에서 도는 PHP의 버전과 같다는 보장은 없어요. 이 부분은 4단계에서 다시 짚을게요.

계열 수정 버전 판단
8.5 8.5.12 미만이면 2단계, 이상이면 3단계
8.4 8.4.27 미만이면 2단계, 이상이면 3단계
8.3 8.3.36 미만이면 2단계, 이상이면 3단계
8.2 8.2.35 패치는 되지만 2026-12-31에 보안 지원이 끝나요. 8.3 이상 이전을 계획하세요
8.1 이하 없음 공식 업데이트가 없어요. 지원 버전으로 이전해야 해요

8.2 외 계열에서 영향이 시작되는 버전은 확인되지 않았어요. 그러니 수정 버전보다 낮으면 일단 대상으로 보세요.

2. 수정 버전 이상으로 업데이트

기준은 단순해요. 쓰는 계열의 수정 버전 이상이면 되고, 다른 계열의 숫자와 섞어 비교하지만 않으면 돼요. 업데이트는 사용 중인 배포판이나 저장소가 내놓는 PHP 패키지로 받으세요. 패키지 이름과 명령은 환경마다 다르니 쓰는 저장소의 공지를 확인해야 해요.

8.1 이하는 공식 패치가 없으니 8.3 이상으로 옮기는 게 답이에요. 8.2는 올릴 수는 있지만 연말에 보안 지원이 끝나죠. 8.2를 쓰고 있다면 수정 버전으로 올리는 김에 8.3 이상 이전 일정까지 같이 잡아 두는 게 나아 보여요.

3. PHP를 실행하는 모든 서비스 재시작

자주 하는 실수가 바로 이 단계를 건너뛰는 거예요. 패키지만 올리고 끝내면 새 버전이 적용되지 않을 수 있어요. 웹에서 도는 프로세스는 여전히 옛 버전일 수 있거든요. 그래서 PHP를 실행하는 서비스는 전부 재시작해야 해요.

  1. Apache mod_php를 제일 먼저 처리해요. 가장 위험한 환경이에요.
  2. 그 외 환경(PHP-FPM, LiteSpeed, php-cgi, FrankenPHP)도 모두 재시작해요.

그럼 mod_php가 아니라 PHP-FPM을 쓰는 서버는 패치를 좀 미뤄도 될까요? 아니요. mod_php는 위험도가 가장 높은 환경일 뿐이고, PHP-FPM이나 LiteSpeed 같은 다른 실행 방식도 수정 버전으로 올려야 해요.

위험도는 패치 순서를 정할 때만 참고하세요. mod_php 서버를 가장 먼저 처리하면 되는 거죠.

서비스 이름은 환경마다 달라서 직접 확인해야 해요. 한 서버에 실행 방식이 여러 개라면 하나도 빠뜨리지 마세요.

4. 체크리스트로 검증

앞에서 말했듯 CLI의 php -v만으로는 웹 쪽 적용 여부를 보장하지 못해요. 버전 출력에 더해 아래 항목을 하나씩 체크하세요.

  • php -v가 쓰는 계열의 수정 버전 이상을 보여요
  • 이 서버에서 쓰는 PHP 실행 방식을 전부 적어 뒀어요
  • 적어 둔 서비스를 업데이트 이후에 모두 재시작했어요
  • 서버가 여러 대면 대수마다 같은 절차를 끝냈어요

하나라도 비어 있으면 아직 패치가 끝난 게 아니에요.

5. 당장 패치가 어려울 때만: 임시 완화

패치가 불가능할 때만 아래 두 값을 넣어요. 먼저 분명히 해 둘게요. 둘 다 일부 경로만 막는 부분 완화라서 패치를 대신하지 못해요.

이 설정을 넣고 해결된 걸로 착각하는 것도 자주 하는 실수 중 하나죠. 막아 주는 범위가 이렇게 좁다는 점은 좀 아쉬워요.

두 값은 넣는 위치도 달라요.

session.upload_progress.enabled=0은 php.ini 또는 PHP-FPM 풀 설정에 넣어요. CVE-2026-109619 중 세션 관련 경로만 막아 줘요. php.ini에서 세션 업로드 진행률을 끄는 설정은 이렇습니다.

session.upload_progress.enabled=0

memory_limit=-1은 CVE-2026-109618에만 해당하고, 넣어도 취약한 경로가 전부 사라지는 건 아니에요. 여기서 신경 쓸 건 넣는 위치인데요. php.ini에만 넣으면 FPM 풀이나 Apache 설정, 앱 코드가 다른 값으로 바꿀 수 있어요.

풀·서버 설정에서 다시 지정한 값이 php.ini보다 우선할 수 있거든요. 그래서 PHP-FPM 풀 설정이나 Apache 설정의 php_admin_value처럼 애플리케이션이 덮어쓸 수 없는 방식으로 넣어야 해요.

Apache mod_php라면 Apache 설정 파일에 넣어요.

php_admin_value memory_limit -1

PHP-FPM이라면 사용 중인 풀 설정 파일에 넣으면 돼요.

php_admin_value[memory_limit] = -1

파일 위치는 환경마다 달라서 직접 확인해야 해요. 값을 넣은 뒤에는 PHP 실행 서비스를 재시작해야 반영되죠. 특히 session.upload_progress.enabled=0은 값을 넣어도 이미 떠 있는 워커에는 반영되지 않을 수 있어요. 모든 워커를 재시작하세요.

memory_limit을 -1로 두면 메모리 상한이 없어지니 메모리 사용량을 모니터링해야 해요. 완화 설정을 넣었어도 패치 일정은 그대로 잡아 두시고요.

왜 이런 문제가 생길까

조치를 끝냈다면 원인도 짧게 볼게요. 두 CVE는 문제가 생기는 지점이 달라요. 하나는 메모리가 부족한 상황에서, 다른 하나는 메모리가 해제된 뒤에 틈이 생기죠.

CVE-2026-109618: 일부만 초기화된 요청 데이터

메모리가 모자라면 PHP는 요청 처리를 멈추고 뒷정리에 들어가요. 문제는 이때 요청 데이터가 일부만 초기화된 상태로 정리될 수 있다는 거예요. 비정상 상황을 끝까지 안전하게 다루지 못하는 결함인데, 이 틈이 원격 코드 실행으로 이어질 수 있어요.

CVE-2026-109619: 메모리는 풀렸는데 남아 있는 상태

요청에 속한 내부 상태가, 그걸 담던 메모리가 해제된 뒤에도 남을 수 있어요. 이미 반납된 메모리를 계속 참조하는 Use After Free 유형이죠. 이 경로로도 원격 코드 실행이 가능해요.

결국 두 문제 모두 애플리케이션 코드를 고친다고 해결되지 않아요. PHP 자체를 고쳐야 하는 문제거든요.

자주 묻는 질문

Q. 우리 앱은 로그인 검사를 하는데, 그래도 공격받을 수 있나요? A.

받을 수 있어요. mod_php에서는 인증되지 않은 요청이 애플리케이션 코드가 실행되기 전에 공격을 일으키는 사례가 확인됐어요. 앱 안의 로그인 검사나 입력 검증 코드는 그 시점에 아직 실행되지 않은 상태예요.

정리

순서만 다시 짚을게요. 수정 버전으로 올린 뒤 mod_php부터 PHP-FPM 등 실행 서비스 전체를 재시작하세요. 8.2 사용자라면 2026-12-31 전에 8.3 이상으로 이전해야 해요.

패치가 어려운 서버는 session.upload_progress.enabled=0과 memory_limit=-1로 부분 완화하되, 메모리 사용량은 계속 지켜봐야 하죠. 공격 흔적이 보인다면 메모리에 있던 비밀번호·토큰·API 키 교체를 검토하는 것까지가 오늘 할 일이에요.

참고 자료

이 글은 공개 자료를 바탕으로 생성형 AI를 활용해 작성했어요.

Posted by 튼튼한노예
,

워크플로가 아예 안 돌거나, cron이 멈췄거나, 취소가 안 먹히거나, Azure 인증이 실패하는 상황인가요? 이 글은 증상별로 원인을 가려낸 다음 gh run rerun으로 다시 돌려 확정하는 데까지 다뤄요. 기준은 2026년 11월의 GitHub Actions와 gh CLI예요(Go azidentity는 1.11.0+).

증상부터 보고 원인을 좁혀요

결론부터 말하면, 원인은 증상마다 몇 개로 정해져 있어요. 워크플로가 실행되지 않는다면 비활성화, issues·schedule처럼 기본 브랜치에서만 도는 이벤트, PR 병합 충돌, paths 3,000파일 한도 중 하나예요. cron이 멈췄다면 실행 계정이 정지·삭제됐거나 프로비저닝이 해제된 경우고요. 취소가 안 되면 always(), 인증 실패는 169.254.169.254 주소 충돌을 보면 돼요.

까다로운 건 앞의 두 증상이에요. run이 아예 안 생기거나 cron이 멈춰도 에러 하나 없이 조용히 지나가거든요. 그러니 검색창에도 증상을 그대로 적게 되죠. 아래 코드 블록은 그런 증상을 재구성해 적은 예시예요.

push 후 Actions 탭에 새 run이 없음
수동 실행(workflow_dispatch)은 되는데 cron만 멈춤
증상 문서화된 원인
push해도 run이 없음 워크플로를 수동으로 비활성화함
issues, schedule이 안 뜸 기본 브랜치에서만 실행되는 이벤트인데 파일이 다른 브랜치에만 있음
수동 실행은 되는데 cron만 멈춤 연결된 actor 계정이 일시 중단, 삭제, 프로비전 해제됨

cron은 한 가지 더 알아 둘 게 있어요. 스케줄이 매시 정각에 늦게 도는 건 문서에 나와 있는 동작이에요. GitHub Actions 부하가 높을 때 스케줄 이벤트가 지연될 수 있는데, 매시 정각이 그 고부하 시간대에 들어가거든요. 부하가 충분히 높으면 대기 중인 job 일부가 누락될 수도 있어요.

취소가 안 되면 always()부터

job 조건에 always()를 쓰면 취소 요청이 들어와도 그 job이 계속 돌 수 있어요. 그래서 run이 취소되지 않고 queued나 in progress로 남기도 하죠. 다만 취소를 시도한 뒤에도 이 상태가 이어진다면 run 자체가 비정상 상태로 멈췄을 수 있어요.

구분하는 방법은 간단해요. 조건을 ${{ !cancelled() }}로 바꿔도 그대로이고, 취소 API에서 HTTP 500/409나 Failed to cancel workflow가 보이면 run이 비정상 상태인 거예요. 그때는 조건식을 더 손볼 필요가 없어요.

gh run rerun으로 다시 돌려 확정해요

원인을 짐작했으면 이제 다시 돌려서 확인할 차례예요.

실패한 run 다시 실행하기

기본은 gh run rerun 뒤에 실패한 run의 ID를 넣는 거예요. RUN_ID 자리에 다시 돌리려는 run의 ID를 넣으세요.

gh run rerun RUN_ID

명령은 한 줄인데 제약이 꽤 붙어요. 다시 실행할 수 없는 경우는 이렇게 세 가지예요.

  • 30일이 지난 run
  • 50회를 넘긴 재실행. 한 run은 최대 50회까지 다시 실행할 수 있고, 전체 재실행과 일부 job 재실행이 모두 이 횟수에 들어가요.
  • 비활성화된 워크플로의 run. 이 상태에서는 run도 job도 다시 실행할 수 없어요.

비활성화 때문에 run이 안 생긴 경우라면 순서가 중요해요. 바로 재실행하지 말고, 워크플로를 먼저 사용 설정한 뒤 gh run rerun을 쓰세요.

권한도 헷갈리기 쉬운 부분이에요. 재실행은 재실행을 누른 사람이 아니라 워크플로를 처음 트리거한 행위자의 권한으로 돌거든요. 재실행을 시작한 계정의 권한은 적용되지 않아요.

깨진 job만 골라 돌리기

job이 여러 개이고 일부만 깨졌다면 --failed를 붙여요.

gh run rerun RUN_ID --failed

의심되는 job이 정해졌다면 --job에 JOB_ID를 넘기면 되고요. JOB_ID는 다시 실행하려는 job의 ID로 바꾸세요.

gh run rerun --job JOB_ID

일부 job 재실행도 50회 한도에서 똑같이 차감돼요. 그래도 job이 여럿인 워크플로라면 전체를 다시 돌리기보다 이쪽이 나아 보여요. 확인할 범위가 깨진 job으로 좁혀지니까요.

로그로도 안 보이면 디버그 로깅

일반 로그로 원인이 안 보이면 --debug를 붙여 재실행해요. 재실행에 러너 진단 로깅과 스텝 디버그 로깅을 켜 주는 옵션이에요.

gh run rerun RUN_ID --debug

재실행 한 번이 아니라 앞으로의 모든 실행에서 상세 로그가 필요하다면 방법이 달라요. 워크플로가 들어 있는 리포지토리에 아래 이름의 secret 또는 variable을 true로 설정하면 돼요.

켜려는 로그 이름 값
러너 진단 로깅 ACTIONS_RUNNER_DEBUG true
스텝 디버그 로깅 ACTIONS_STEP_DEBUG true

같은 이름을 secret과 variable 양쪽에 두면 secret이 우선해요. 값이 기대와 다르게 적용되면 두 곳을 모두 확인하세요. 처음부터 한쪽에만 두면 이런 혼선이 생길 일이 없어서, 그쪽이 깔끔해 보여요.

진단 로그는 어디서 볼까요? 러너 진단 로깅을 켜고 돌리면 로그 아카이브 안의 runner-diagnostic-logs 폴더에 들어 있어요. runner 프로세스 로그에는 러너가 작업을 조정하고 설정하는 과정이, worker 프로세스 로그에는 작업을 실제로 실행한 기록이 남아요.

스텝 안에서 쓰는 도구의 상세 출력은 도구 쪽 옵션으로 따로 켜야 해요. npm은 --verbose, Git은 GIT_TRACE 환경 변수를 쓰면 되죠.

멀티클라우드 러너에서 Azure 인증이 실패할 때

마지막 증상은 원인이 엉뚱한 데 있어요. AWS와 Azure가 메타데이터 주소로 같은 169.254.169.254를 쓰거든요. 일부 Azure Identity SDK는 이 주소에서 받은 EC2 메타데이터 응답을 Azure 관리 ID 인증 실패로 해석해요. 그래서 앞선 azure/login 단계가 성공해도, DefaultAzureCredential을 쓰는 앱은 다중 클라우드 컴퓨팅 풀의 러너에서 인증에 실패할 수 있어요.

그러니 azure/login이 성공했는데 인증이 실패한다고 로그인 스텝을 고칠 필요는 없어요. 원인은 169.254.169.254 메타데이터 주소 충돌이니까요.

앱이 Go의 azidentity 모듈 v1.11.0 이상을 쓴다면, 로그인 성공 뒤 앱을 실행하는 스텝에 환경 변수를 지정하면 돼요.

- name: Run application
  env:
    AZURE_TOKEN_CREDENTIALS: AzureCLICredential
  run: ./application

이 해법은 Go azidentity 1.11.0 이상 기준이에요. 그 외 SDK·버전의 해법은 이 글의 근거 자료에서 확인되지 않았어요. 다른 언어로 앱을 짠 분에게는 이 부분이 좀 아쉽네요.

어느 증상이든 마지막 확인은 gh run rerun으로 하면 돼요. 원인이 모호하면 --debug 플래그를 붙여 상세 로그부터 보세요.

참고 자료

이 글은 공개 자료를 바탕으로 생성형 AI를 활용해 작성했어요.

Posted by 튼튼한노예
,