พอกันที่กับการ rotate secret ของ Service Principal ที่ใช้กับ Github Action ทุก 3 เดือน 6 เดือน
พอกันทีกับโอกาสที่ secret ของ Service Principal จะ leak
วันนี้มีสิ่งที่เรียกว่า "Workload Identity Federation" นำเสนอครับ
Workload Identity Federation
คือการที่เราทำการสร้าง trusted relationship กันระหว่าง Microsoft Identity Platform กับ External Identity Provider (IdP) เช่น GitHub พอ trust กันแล้ว เราจะสามารถใช้ token ของ External IdP ไปแลกเป็น access token ของ Azure เพื่อ access resources ใน Azure ที่ถูก protect ด้วย Azure AD ได้
External Identity Provider (IdP) ที่ support ตอนนี้ เช่น
- GitHub Actions
- Google Cloud
- Workload ใน Kubernetes
- External Provider อื่นๆ ที่ support OpenID Connect (OIDC)
มาดู flow ดีกว่าว่ามันทำงานยังไง
- External Workload เช่น github action ทำการขอ token จาก IdP ของตัวเอง
- External IdP ทำการ generate แล้วให้ token กับ External Workload
- External Workload ใช้ token ที่ได้มาเพื่อขอ access token จาก Microsoft identity platform
- Microsoft identity platform ทำการตรวจสอบว่ามี trust relationship สร้างไว้อยู่หรือไม่ และ เอา token ที่ได้ไป validate กับ External IdP
- ถ้าทุกอย่างเรียบร้อย Microsoft identity platform จะสร้าง access token แล้วส่งให้กับ External Workload
- จากนั้น External Workload จะใช้ access token ที่ได้มาเช้าถึง resources ใน Azure โดย access token จะมี permission เท่ากับ service principal ที่ สร้าง trust relationship ไว้
มาลองลงมือทำดีกว่า
สิ่งที่เราจะทำคือสร้าง
- 1 Github Repos ที่มี 2 Actions และ 2 environments ( develop / production )
- 2 services principals ( develop / production )
- trust relationship ระหว่าง Service Principals และ Environment ของ Github
- 2 resource groups และให้ services principals เป็น Contributors ใน resource groups ( develop / production )
- สร้าง Github Action Workflow เพื่อทดสอบ storage account ใน resource group ตาม environemnt
สร้าง Github Repos และ environment
- สร้าง Github Action Repo
- Create Environment ( ชื่อ environemnt จะถูกใช้ในการ สร้าง trust relationship ใน Azure Portal )
- develop
- production
สร้าง service principal
- ใน
Azure Portal
>Azure Active Directory
>App registrations
>+ New Registration
- ใส่ชื่อของ service principal เลือก single tenant แล้วกด
Register
-
sp-demogithub-az-asse-dev-001
สำหรับ develop -
sp-demogithub-az-asse-prd-001
สำหรับ production
-
สร้าง Trust Relationship ( Federated credentials )
- Click ที่ Service Principal ที่เราสร้างขึ้น >
Certificates & secrets
>Federated credentials
>+ Add credential
- ใส่ข้อมูลของ Github Repo ที่ต้องการสร้าง Trust Relationship ด้วย
-
Organization
: ใส่ชื่อ organization ของ ตัวเอง -
Repository
: ชื่อ repo ของ github ที่เราสร้างไว้ก่อนหน้า -
Entity type
: เลือกEnvironment
ค่าอื่นดูต่อที่ Entity type examples -
Name
: ตั้งชื่อขอ Federated credentials นี้ ( FQDN friendly )
-
- กดที่ overview ของ Service Pricipal แล้วเก็บค่าเหล่านี้ไว้ใช้ add ใน github environment
-
AZURE_CLIENT_ID
: Application (client) ID -
AZURE_TENANT_ID
: Directory (tenant) ID -
AZURE_SUBSCRIPTION_ID
: subscription ID ที่จำให้ Github Action Provision storage account
-
- ทำแบบเดียวกันกับ Service Principal ของ Production Environment
สร้าง resource group แล้ว assign Contributor role ให้กับ Service Principal
- สร้าง resource groups
-
rg-demogithubfed-az-asse-dev-001
สำหรับ develop -
rg-demogithubfed-az-asse-prd-001
สำหรับ production
-
- Create Role Assignment ให้
-
sp-demogithub-az-asse-dev-001
เป็น Contributor ในrg-demogithubfed-az-asse-dev-001
-
-
sp-demogithub-az-asse-prd-001
เป็น Contributor ในrg-demogithubfed-az-asse-prd-001
สร้าง Github workflow เพื่อทดสอบสร้าง storage account
- สร้าง Enviroment secret ใน Github
-
AZURE_CLIENT_ID
: Application (client) ID -
AZURE_TENANT_ID
: Directory (tenant) ID -
AZURE_SUBSCRIPTION_ID
: subscription ID ที่จำให้ Github Action Provision storage account
-
ทำแบบเดียวกัน กับ production enviroment
- สร้าง Github Workflow สำหรับ create github action
Action ที่ใช้ login คือ Azure Login โดยเราจะทำตามตัวอย่างนี้ Sample workflow that uses Azure login action using OIDC to run az cli (Linux)
- สร้าง file สำหรับ develop =>
.github/workflows/dev-demo.yml
name: DEV - Demo Azure Login with OIDC
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment: develop
steps:
- name: 'Az CLI login'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: 'Run az commands'
run: |
az account show --output table
az storage account create \
--subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} \
--location southeastasia \
--resource-group rg-githubfed-az-asse-dev-001 \
--name stdemofeddev001 \
--sku Standard_LRS \
--default-action Deny \
--min-tls-version TLS1_2 \
--output table
- สร้าง file สำหรับ production =>
.github/workflows/prd-demo.yml
name: PRD - Demo Azure Login with OIDC
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment: production
steps:
- name: 'Az CLI login'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: 'Run az commands'
run: |
az account show --output table
az storage account create \
--subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} \
--location southeastasia \
--resource-group rg-githubfed-az-asse-prd-001 \
--name stdemofedprd001 \
--sku Standard_LRS \
--default-action Deny \
--min-tls-version TLS1_2 \
--output table
- ทดสอบ run Github Action
- ตรวจสอบ storage account ที่ Azure Portal
Top comments (1)
Great article. Keep teaching, keep learning