Azure Workload Identity Federation و GitHub Actions

زندگی سخت یک GitHub Action
GitHub Actions (اسناد در اینجا) می تواند برای ایجاد کل محیط در Azure و به طور کلی، تعامل با پلت فرم Azure استفاده شود.
اما GitHub Actions خارج از مستاجر Azure شما (“پادشاهی” شما) اجرا می شود و به همین دلیل باید توسط Azure Active Directory شما احراز هویت شود و مانند همه برنامه هایی که خارج از مستاجر شما اجرا می شوند، می توانند از یک Service Principal برای شناسایی استفاده کنند.
در ابتدا مدیر سرویس است
اولین قدمی که باید برای ایمن سازی اکشن های GitHub خود در Azure انجام دهید، ایجاد یک Service Principal است.
شما راه های مختلفی برای انجام این کار دارید، اما اگر می خواهید از پورتال Azure استفاده کنید، می توانید از صفحه اکتیو دایرکتوری شروع کنید، “ثبت برنامه” تیغه و “ثبت نام جدید” دکمه:
پورتال Azure باز می شود “ثبت درخواست” صفحه و تنها کاری که باید انجام دهید این است که یک نام به Principal Service خود بدهید و روی آن کلیک کنید “ثبت نام” دکمه.
در یک دقیقه، شما Principal Service خود را خواهید داشت و پورتال آن را به شما نشان می دهد “بررسی اجمالی” صفحه ای که در آن می توانید اطلاعات مفیدی برای پیکربندی اکشن های GitHub خود پیدا کنید.
متأسفانه، اصل خدمات به تنهایی برای رسیدن به هدف ما کافی نیست. ما باید یک راز را ایجاد کنیم که Actions ما باید بداند تا بتواند احراز هویت شود، و یک نقش RBAC (اطلاعات بیشتر در اینجا) برای مدیر سرویس ایجاد کنیم تا مجوزهای مناسب برای مدیریت منابع در اشتراکهای ما را داشته باشد.
انجام هر دو این عملیات آسان است: برای ایجاد یک راز برای مدیر سرویس، باید روی آن کلیک کنید “گواهینامه ها و اسرار” تیغه را باز کنید “رازهای مشتری” را برگه و روی آن کلیک کنید “راز مشتری جدید” دکمه.
برای افزودن راز جدید، فقط توضیحات را ویرایش کنید (من پیشنهاد می کنم از توضیحاتی استفاده کنید که کوتاه است اما توضیح می دهد که راز را برای چه کاربردی ایجاد می کنید) و مدت زمان.
پس از ایجاد مخفی به یاد داشته باشید که ارزش آن را یادداشت کنید، زیرا فقط بلافاصله پس از ایجاد قابل دسترسی است.
یک راز عادت بد (یا اگر از منظر امنیتی به آن نگاه کنیم خوب است) داشتن ضرب الاجل است. حداکثر مدت زمانی که می توانید انتخاب کنید برابر با دو سال است و بدیهی است که باید مطمئن شوید که هرکسی که از Principal سرویس استفاده می کند (در مورد ما اکشن GitHub) همیشه راز به روز شده را داشته باشد.
به طور خلاصه، راز باید مدیریت شود و اگر اقدامات زیادی وجود داشته باشد که از آن استفاده می کنند یا اگر ما Principals خدمات زیادی داشته باشیم، می تواند کار زیادی را شامل شود.
به همین دلیل است که، برای مثال، از شناسه های مدیریت شده استفاده می کنید
وقتی می خواهید تعامل بین دو سرویس را در Azure ایمن کنید …. اما GitHub Actions شما در Azure نیست!! 😟
سه گانه ارزش ها ApplicationID
، TenantID
و SecretValue
اعتبارنامه های اصلی سرویس هستند که در اکشن GitHub خود به آن نیاز دارید.
استفاده از رازها در GitHub Actions
قبل از اینکه به شما نشان دهیم که چگونه از استفاده از راز در اکشنهای GitHub به لطف شناسههای بار کاری فدرال اجتناب کنید، بیایید ببینیم چه مراحلی وجود دارد که به لطف اعتبار مدیر سرویس، به اکشنهای GitHub اجازه تعامل با Azure را میدهد.
به اکشن ساده GitHub زیر نگاه کنید:
name: WIF App registration with Secret
on:
workflow_dispatch
env:
LOCATION: "northeurope"
RESOURCE_GROUP_NAME: "WIF-AppReg-Secret"
SUBSCRIPTION_ID: "********-****-****-****-************"
jobs:
job01:
runs-on: ubuntu-latest
steps:
- uses: Azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
allow-no-subscriptions: true
- name: Create resource group
uses: azure/CLI@v1
with:
inlineScript: |
az group create --location ${{ env.LOCATION }} --name ${{ env.RESOURCE_GROUP_NAME }} --subscription ${{ env.SUBSCRIPTION_ID }}
این اکشن از دو عمل برای باز کردن یک جلسه تأیید شده در Azure استفاده می کند (Azure/login@v1
) و یک دستور ساده Azure CLI را اجرا کنید (azure/CLI@v1
) برای ایجاد یک گروه منابع.
برای باز کردن یک جلسه تأیید شده در Azure، به اعتبارنامه نیاز دارید و اعتبارنامه ها توسط سه گانه قبلی نشان داده می شوند. ApplicationID
، TenantID
و SecretValue
قبلا ذکر کردیم
شما باید JSON زیر را ایجاد کنید (شناسه های مناسب را جایگزین کنید clientId
، clientSecret
و tenantId
خواص):
{
"clientId": "********-****-****-****-************",
"clientSecret": "Lsu************************bAe",
"tenantId": "********-****-****-****-************"
}
و یک Action Secret به نام ایجاد کنید AZURE_CREDENTIALS
که شامل JSON قبلی است که در تصویر زیر نشان داده شده است:
آسان است اما… clientSecret
هر بار که راز در ثبت برنامه تغییر می کند، ویژگی باید به روز شود (در واقع کل راز در GitHub باید به روز شود زیرا رازها در GitHub قابل تغییر نیستند و فقط بازنویسی می شوند). و در نهایت، شما باید مراقب باشید clientSecret
(و همچنین clientId
و tenantId
) زیرا اگر کسی آن مقادیر را دزدیده باشد، می تواند ثبت نام برنامه شما را جعل کند و فکر خوبی نیست!!
فدراسیون هویت حجم کار
این رویکرد برای اعتماد به توکنهای ارائهدهنده هویت خارجی، مانند GitHub یا Google (یا موارد دیگر در آینده) متولد شد.
ابتدا یک رابطه بین هویت (که می تواند یک هویت مدیریت شده یا ثبت برنامه باشد) و ارائه دهنده هویت خارجی ایجاد می کنید.
هنگامی که این رابطه ایجاد شد، هر بار که حجم کاری می خواهد خود را در برابر AzureAD احراز هویت کند، یک توکن را از IdP خارجی بازیابی می کند و از آن برای درخواست توکن دسترسی از AAD استفاده می کند.
این جادو نیست، در پشت صحنه، AzureAD از OpenID Connect استفاده می کند (اطلاعات بیشتر در اینجا).
GitHub Actions یکی از سناریوهایی است که می توانید از این رویکرد استفاده کنید.
برای ایجاد رابطه بین ثبت برنامه و GitHub، می توانید آن را باز کنید “گواهینامه ها و اسرار” blade برای ثبت برنامه (همانطور که در رویکرد اعتبارنامه کامل انجام دادید) و در عوض یک راز ایجاد کنید، از “مدارک فدرال” برگه
را “افزودن اعتبار” دکمه صفحه پیکربندی اعتماد را باز می کند:
در صفحه قبل، باید مخزن مورد اعتماد خود را از نظر سازمان (یا نام کاربری) و نام مخزن پیکربندی کنید.
سپس باید نهادی را که میخواهید به آن اعتماد کنید و میتوانید انتخاب کنید، انتخاب کنید Environment
، Branch
، Pull request
یا Tag
. مقداری که انتخاب میکنید باید تنظیمات GitHub Actions شما باشد. به عنوان مثال، اگر هر بار که شخصی یک کد جدید را در شاخه اصلی فشار می دهید، اقدام شما شروع می شود، شما انتخاب می کنید branch
نوع موجودیت و درج main
در نام شعبه در پیکربندی.
مقداری که برای نوع موجودیت استفاده میکنید توسط جریان OIDC برای ثبت دامنه درخواستهای OIDC استفاده میشود.
هنگامی که رابطه اعتماد ایجاد کردید، می توانید اضافه کنید clientId
و tenantId
مقادیر را به عنوان اسرار عمل در مخزن قرار دهید و اکشن زیر را بنویسید:
name: WIF App registration with federation
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
on:
push:
branches:
- main
env:
LOCATION: "northeurope"
RESOURCE_GROUP_NAME: "WIF-AppReg-Federation"
jobs:
job01:
runs-on: ubuntu-latest
steps:
- uses: Azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Creat resource group
uses: azure/CLI@v1
with:
inlineScript: |
az group create --location ${{ env.LOCATION }} --name ${{ env.RESOURCE_GROUP_NAME }}
این عمل دقیقاً همان عملیات قبلی را انجام می دهد، اما در اینجا شما هیچ کدام را ندارید clientSecret
برای مدیریت.
توجه داشته باشید: به مجوزهای عمل قبلی توجه کنید. اگر می خواهید که این عمل بتواند رمز را از IdP بازیابی کند، آنها اجباری هستند. اگر آنها را حذف کنید، یک خطا دریافت می کنید!!