해당 스터디는 90DaysOfDevOps
https://github.com/MichaelCade/90DaysOfDevOps
를 기반으로 진행한 내용입니다.
Day 77 - Connect to Microsoft APIs in Azure DevOps Pipelines using Workload Identity Federation
DevOps 환경을 구축하다 보면 GitHub Actions나 Azure DevOps와 같은 외부 서비스에서 Azure 리소스에 접근해야 할 일이 빈번하다.
기존에는 이를 위해 클라이언트 Secret을 생성하고 관리해야 했지만, 이는 보안상 취약점이 될 수 있고 만료 주기마다 갱신해야 하는 번거로움이 있었다.

Workload Identity Federation은 GitHub, Azure DevOps 등과 같은 외부 워크로드의 ID를 Microsoft Entra ID의 ID와 연동하여, 별도의 암호나 액세스 키를 관리할 필요 없이 Azure 리소스에 접근할 수 있게 해주는 기능이다.
Workload Identity Federation: 앱 등록이나 사용자 할당 관리 ID를 생성한 후, OpenID Connect를 통해 신뢰 관계를 설정함으로써 외부 파이프라인이 Azure 리소스에 액세스하도록 허용하는 방식
Workload Identity Federation은 OIDC(OpenID Connect) 프로토콜을 사용한다.
Azure AD는 외부 자격 증명 공급자(예: GitHub, Azure DevOps)가 발급한 토큰을 신뢰하도록 설정된다.
즉, "비밀번호를 가져와"가 아니라, "내가 신뢰하는 시스템(Azure DevOps)이 증명한 사용자니까 통과시켜"라는 방식이다. 이로 인해 시크릿 관리가 필요 없어지는 Secret-less 인증이 가능해진다.
Workload Identity Federation은 OIDC(OpenID Connect) 프로토콜을 사용한다.
그렇다면 OIDC는 무엇이며, 해당 시나리오에서 어떻게 작동하는 것일까?

차이점:
OAuth 2.0: "이 사용자가 내 사진첩에 접근해도 될까?" (권한 부여: Authorization)에 초점
OIDC: "이 사용자가 누구인가?" (신원 확인: Authentication)에 초점
OAuth 2.0이 호텔의 객실 카드키를 발급해 주는 절차라면, OIDC는 그 카드키를 발급받기 위해 프론트 데스크에서 신분증을 확인하는 과정과 유사하다.
Workload Identity Federation 환경에서 Azure Entra ID와 외부 공급자인 Azure DevOps/GitHub는 다음과 같은 방식으로 신뢰를 구축한다.

외부 토큰 생성 (External Token):
Azure DevOps 파이프라인이 실행되면, 외부 자격 증명 공급자(Azure DevOps)는 현재 작업에 대한 정보를 담은 JWT(JSON Web Token)를 생성한다.
이 토큰에는 발급자(Issuer), 대상(Subject), 유효기간 등의 정보가 서명(Signed)되어 있다.
토큰 교환 요청:
검증:
Azure AD는 외부 공급자의 공개 키를 사용하여 JWT의 서명을 확인한다. (OIDC Discovery)
등록된 '페더레이션 자격 증명' 설정과 토큰의 정보(Issuer, Subject)가 일치하는지 대조한다.
액세스 토큰 발급:
Secret-less: 클라이언트 시크릿(비밀번호)을 어딘가에 저장하거나 전송할 필요가 없다. 오직 신뢰 관계(Trust)만 존재한다.
단기 유효성: 교환에 사용되는 토큰은 유효 기간이 매우 짧아, 탈취되더라도 위험이 적다.
표준화: GitHub, Azure DevOps, Kubernetes 등 다양한 플랫폼이 OIDC 표준을 따르므로 확장성이 뛰어나다.
Workload Identity Federation을 설정하는 데는 크게 두 가지 진입점이 있다.
옵션 A: 앱 등록 (App Registration) 사용
Microsoft Entra ID 테넌트에서 새 앱 등록을 생성한다.
등록 후 [인증서 및 암호] 메뉴로 이동
클라이언트 암호를 만드는 대신 [페더레이션 자격 증명(Federated Credentials)] 탭을 선택
[자격 증명 추가]를 클릭하고 시나리오를 선택
GitHub Actions나 Kubernetes 등을 선택할 수 있다.
Azure DevOps를 사용하는 경우 기타 발급자(Other issuer)를 선택하고 값을 수동으로 입력
옵션 B: 사용자 할당 관리 ID (User-assigned Managed Identity) 사용
Azure Portal에서 관리 ID(Managed Identities)를 검색하여 생성 또는 선택
설정 메뉴 중 [페더레이션 자격 증명] 탭으로 이동
자격 증명을 추가하며 GitHub Actions, Kubernetes 등의 시나리오를 지원
💡관리 ID (Managed Identity)란?
Azure 리소스(VM, App Service 등)가 다른 Azure 서비스(SQL DB, Storage 등)에 접근할 때, 코드 내에 자격 증명을 저장하지 않도록 돕는 기능
Azure가 내부적으로 ID 관리를 전담하므로 개발자가 비밀번호를 알 필요도, 관리할 필요도 없음.

시스템 할당: 리소스 생명주기와 함께 생성 및 삭제됨.
사용자 할당: 독립적인 리소스로 생성되어 여러 서비스에 할당 가능.
해당 프레젠테이션 데모에서는 Azure DevOps 프로젝트로 이동하여 실제 연결을 설정하는 과정을 설명하였다.
Azure DevOps 프로젝트의 [Project Settings] -> [Service connections]로 이동한다.
[New service connection]을 클릭하고 Azure Resource Manager 타입을 선택한다.
Azure Resource Manager (ARM) 란?
Azure의 배포 및 관리 서비스
Azure의 모든 리소스(VM, DB, Network 등)를 생성, 업데이트, 삭제하는 관리 계층을 제공

Azure Resource Manager가 되어야 함.연결 설정 방식: 자동 vs 수동
Automatic (권장):
테넌트 내 앱 등록 권한이 있다면 권장되는 방식
구독을 선택하고 저장하면 자동으로 앱 등록과 페더레이션 설정이 완료
Manual:
앱 등록 권한이 없는 경우 사용
시스템이 생성해주는 발급자(Issuer)와 주체 식별자(Subject Identifier) 정보를 복사하여 Entra ID 관리자에게 전달하고 설정을 요청해야 함.
페더레이션 자격 증명의 구성 요소
설정이 완료된 후 Entra ID에서 해당 앱 등록을 확인해보면 시크릿은 없고 페더레이션 자격 증명만 존재한다.

Issuer (발급자): Azure DevOps 환경의 URL
Subject Identifier (주체 식별자): Organization, 프로젝트, 그리고 서비스 연결 이름을 식별하는 문자열
Audience (대상): api://AzureADTokenExchange (항상 해당 값으로 고정)
해당 설정 덕분에 Azure DevOps의 특정 서비스 연결이 요청을 보낼 때, Entra ID는 이를 신뢰할 수 있는 요청으로 식별하게 된다.
설정된 Workload ID Federation을 활용하여, 파이프라인 상에서 Microsoft Graph에 인증하고 데이터를 가져오는 시나리오이다.
데모의 핵심 의도
일반적으로 Azure AD 사용자 조회나 관리 작업은 관리자가 직접 수행하거나, 스크립트에 관리자 ID/PW를 저장하여 수행한다.
해당 데모는 파이프라인이 Workload ID Federation을 통해 스스로 신원을 증명하고, 관리자 개입 없이 보안 토큰을 발급받아 관리 도구인 Graph API를 호출할 수 있음을 검증하는 개념 증명 과정이다.
Microsoft Graph란?
Microsoft 365(Office, Windows, Entra ID 등)의 수많은 데이터와 인텔리전스에 접근할 수 있는 통합 API 엔드포인트

이를 통해 사용자 정보 조회, 메일 발송, 일정 관리 등을 프로그래밍 방식으로 제어할 수 있다.
해당 데모에서는 Connect-MgGraph를 통해 Entra ID의 사용자 정보를 조회하는 데 사용
먼저 AzureCLI@2 태스크를 사용하여 토큰을 가져온다.
해당 단계는 파이프라인이 "나 신뢰할 수 있는 파이프라인이야"라고 Azure AD에 신호를 보내고, OIDC 검증을 거쳐 Access Token를 건네받는 과정이다.
이때 서비스 연결은 Workload Identity Federation이 적용된 연결을 사용한다.
# Azure CLI로 액세스 토큰 요청
az account get-access-token --resource-type ms-graph
--resource-type을 ms-graph로 지정하여 Graph API용 토큰을 받는다.
(ARM API나 Key Vault용으로도 변경 가능)
핵심 원리: 파이프라인 에이전트가 자신의 OIDC 토큰을 Azure AD에 제시하면, Azure AD는 미리 등록된 '페더레이션 자격 증명'과 대조하여 유효성을 확인한 후 Microsoft Graph 접근용 액세스 토큰을 발급해준다.
받아온 토큰을 파이프라인 내에서 사용할 변수인 secretToken로 설정하고, 이를 Secret 타입으로 지정하여 로그에 노출되지 않도록 한다.
앞서 발급받은 토큰을 사용하여 실제로 Microsoft Graph에 로그인하고 관리 작업을 수행한다.
# 1. 일반 변수를 PowerShell의 SecureString으로 변환
$secureToken = ConvertTo-SecureString -String $env:secretToken -AsPlainText -Force
# 2. Microsoft Graph 연결
Connect-MgGraph -AccessToken $secureToken
# 3. 사용자 정보 조회
Get-MgUser -UserId "testuser@domain.com"
의의: Connect-MgGraph 명령어 실행 시 별도의 로그인 창이나 패스워드 입력 없이, 1단계에서 획득한 토큰만으로 인증(-AccessToken)을 통과하는 것이 핵심이다.
파이프라인은 비밀 변수를 평문으로 접근할 수 있지만, Connect-MgGraph 명령어는 SecureString을 요구하므로 변환 과정이 필요하다.
인증(Authentication)에 성공했더라도, 특정 작업을 수행하려면 권한(Authorization)이 필요하다.
토큰을 통해 "내가 누구인지"는 증명했지만, "무엇을 할 수 있는지"는 별도로 정의해야 한다.
Entra ID 포털의 해당 앱 등록 메뉴로 이동한다.
[API 권한] 탭에서 Microsoft Graph -> User.Read.All 등의 필요한 권한을 추가하고 관리자 동의를 얻어야 한다.
이 과정이 누락되면 Get-MgUser 실행 시 권한 부족 오류가 발생한다.
Workload Identity Federation은 기존의 클라이언트 시크릿 방식이 가진 보안 취약점과 관리 비용을 OIDC 기반의 신뢰 관계로 대체하는 인증 기술이다.
이는 외부 ID 공급자와 Azure AD 간의 토큰 교환을 통해 자격 증명이 필요 없는(Secret-less) 아키텍처를 구현함으로써, 보안 리스크를 원천적으로 차단한다.
결과적으로 엔지니어는 시크릿 만료나 유출 걱정 없이 Microsoft Graph 및 Azure 리소스에 대한 일관된 보안 거버넌스를 유지하며, 더욱 견고한 자동화 파이프라인을 구축할 수 있다.