mirror of
https://github.com/azure/login.git
synced 2026-03-15 09:20:56 -04:00
Compare commits
1 Commits
sy/improve
...
update-nod
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2431008d0a |
33
.github/workflows/azure-login-negative.yml
vendored
33
.github/workflows/azure-login-negative.yml
vendored
@@ -333,3 +333,36 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
core.setFailed('Last action should fail but not. Please check it.')
|
core.setFailed('Last action should fail but not. Please check it.')
|
||||||
|
|
||||||
|
VMTest:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [self_linux, self_windows]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
environment: Automation test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Checking out repo code'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set Node.js 20.x for GitHub Action
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20.x
|
||||||
|
|
||||||
|
- name: 'Validate build'
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
- name: Login with system-assigned managed identity without auth-type
|
||||||
|
id: login_14
|
||||||
|
continue-on-error: true
|
||||||
|
uses: ./
|
||||||
|
|
||||||
|
- name: Check Last step failed
|
||||||
|
if: steps.login_14.outcome == 'success'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.setFailed('Last action should fail but not. Please check it.')
|
||||||
|
|||||||
141
.github/workflows/azure-login-positive.yml
vendored
141
.github/workflows/azure-login-positive.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
BasicTest:
|
BasicTest:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest, self_linux, self_windows]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
environment: Automation test
|
environment: Automation test
|
||||||
|
|
||||||
@@ -47,11 +47,13 @@ jobs:
|
|||||||
az vm list --output none
|
az vm list --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
|
||||||
|
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
|
||||||
if(-not $checkResult){
|
if(-not $checkResult){
|
||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
@@ -69,7 +71,7 @@ jobs:
|
|||||||
az account show --output none
|
az account show --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell again
|
- name: Run Azure PowerShell again
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -92,11 +94,13 @@ jobs:
|
|||||||
az vm list --output none
|
az vm list --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
|
||||||
|
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
|
||||||
if(-not $checkResult){
|
if(-not $checkResult){
|
||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
@@ -160,11 +164,13 @@ jobs:
|
|||||||
az vm list --output none
|
az vm list --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
|
||||||
|
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
|
||||||
if(-not $checkResult){
|
if(-not $checkResult){
|
||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
@@ -183,7 +189,7 @@ jobs:
|
|||||||
az account show --output none
|
az account show --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell again
|
- name: Run Azure PowerShell again
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -203,17 +209,17 @@ jobs:
|
|||||||
- name: Run Azure Cli
|
- name: Run Azure Cli
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
$checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 3
|
$checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 2
|
||||||
if(-not $checkResult){
|
if(-not $checkResult){
|
||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
$checkResult = (Get-AzContext -ListAvailable).Count -eq 2
|
||||||
if(-not $checkResult){
|
if(-not $checkResult){
|
||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
@@ -230,7 +236,7 @@ jobs:
|
|||||||
az account show --output none
|
az account show --output none
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -239,3 +245,118 @@ jobs:
|
|||||||
throw "Not all checks passed!"
|
throw "Not all checks passed!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VMTest:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [self_linux, self_windows]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
environment: Automation test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 'Checking out repo code'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set Node.js 20.x for GitHub Action
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20.x
|
||||||
|
|
||||||
|
- name: 'Validate build'
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
- name: Login with system-assigned managed identity, no subscription-id
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
auth-type: IDENTITY
|
||||||
|
allow-no-subscriptions: true
|
||||||
|
enable-AzPSSession: true
|
||||||
|
|
||||||
|
- name: Run Azure Cli
|
||||||
|
run: |
|
||||||
|
az account show --output none
|
||||||
|
|
||||||
|
- name: Run Azure PowerShell
|
||||||
|
uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
azPSVersion: "latest"
|
||||||
|
inlineScript: |
|
||||||
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
if(-not $checkResult){
|
||||||
|
throw "Not all checks passed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Login with system-assigned managed identity, with subscription id
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
auth-type: IDENTITY
|
||||||
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}
|
||||||
|
enable-AzPSSession: true
|
||||||
|
|
||||||
|
- name: Run Azure Cli
|
||||||
|
run: |
|
||||||
|
az account show --output none
|
||||||
|
az group show --name GitHubAction_CI_RG --output none
|
||||||
|
az vm list --output none
|
||||||
|
|
||||||
|
- name: Run Azure PowerShell
|
||||||
|
uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
azPSVersion: "latest"
|
||||||
|
inlineScript: |
|
||||||
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
|
||||||
|
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
|
||||||
|
if(-not $checkResult){
|
||||||
|
throw "Not all checks passed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Login with tenant-level user-assigned managed identity with allow-no-subscriptions
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
client-id: ${{ secrets.UMI2_CLIENT_ID }}
|
||||||
|
allow-no-subscriptions: true
|
||||||
|
auth-type: IDENTITY
|
||||||
|
enable-AzPSSession: true
|
||||||
|
|
||||||
|
- name: Run Azure Cli
|
||||||
|
run: |
|
||||||
|
az account show --output none
|
||||||
|
|
||||||
|
- name: Run Azure PowerShell
|
||||||
|
uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
azPSVersion: "latest"
|
||||||
|
inlineScript: |
|
||||||
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
if(-not $checkResult){
|
||||||
|
throw "Not all checks passed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Login with user-assigned managed identity, subscription-id
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
client-id: ${{ secrets.UMI1_CLIENT_ID }}
|
||||||
|
subscription-id: ${{ secrets.UMI1_SUBSCRIPTION_ID }}
|
||||||
|
auth-type: IDENTITY
|
||||||
|
enable-AzPSSession: true
|
||||||
|
|
||||||
|
- name: Run Azure Cli
|
||||||
|
run: |
|
||||||
|
az account show --output none
|
||||||
|
az group show --name GitHubAction_CI_RG --output none
|
||||||
|
az vm list --output none
|
||||||
|
|
||||||
|
- name: Run Azure PowerShell
|
||||||
|
uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
azPSVersion: "latest"
|
||||||
|
inlineScript: |
|
||||||
|
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
|
||||||
|
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
|
||||||
|
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
|
||||||
|
if(-not $checkResult){
|
||||||
|
throw "Not all checks passed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
46
.github/workflows/azure-login-pr-check.yml
vendored
46
.github/workflows/azure-login-pr-check.yml
vendored
@@ -1,12 +1,13 @@
|
|||||||
name: pr-check
|
name: pr-check
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request_target:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- 'releases/*'
|
- 'releases/*'
|
||||||
jobs:
|
jobs:
|
||||||
az-login-test:
|
az-login-test:
|
||||||
|
environment: Automation test
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout from PR branch
|
- name: Checkout from PR branch
|
||||||
@@ -27,5 +28,44 @@ jobs:
|
|||||||
- name: Build GitHub Action
|
- name: Build GitHub Action
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: Run mock test
|
- name: 'Az CLI login with subscription'
|
||||||
run: npm run test
|
uses: ./
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
az account show --output none
|
||||||
|
az vm list --output none
|
||||||
|
|
||||||
|
- name: 'Az CLI login without subscription'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS_NO_SUB }}
|
||||||
|
allow-no-subscriptions: true
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
az account show --output none
|
||||||
|
# az vm list --output none
|
||||||
|
|
||||||
|
- name: 'Azure PowerShell login with subscription'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
enable-AzPSSession: true
|
||||||
|
|
||||||
|
- uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
inlineScript: "(Get-AzContext).Environment.Name"
|
||||||
|
azPSVersion: "latest"
|
||||||
|
|
||||||
|
# - name: 'Azure PowerShell login without subscription'
|
||||||
|
# uses: ./
|
||||||
|
# with:
|
||||||
|
# creds: ${{secrets.AZURE_CREDENTIALS_NO_SUB}}
|
||||||
|
# enable-AzPSSession: true
|
||||||
|
# allow-no-subscriptions: true
|
||||||
|
|
||||||
|
# - uses: azure/powershell@v1
|
||||||
|
# with:
|
||||||
|
# inlineScript: "Get-AzContext"
|
||||||
|
# azPSVersion: "latest"
|
||||||
|
|||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
- name: 'Run L0 tests'
|
- name: 'Run L0 tests'
|
||||||
run: |
|
run: |
|
||||||
npm run test
|
npm run test
|
||||||
|
|||||||
11
.github/workflows/codeql.yml
vendored
11
.github/workflows/codeql.yml
vendored
@@ -6,11 +6,6 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 19 * * 0'
|
- cron: '0 19 * * 0'
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CodeQL-Build:
|
CodeQL-Build:
|
||||||
|
|
||||||
@@ -23,14 +18,14 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v2
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v3
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -44,4 +39,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|||||||
@@ -7,4 +7,3 @@ Resources:
|
|||||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
||||||
- Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
|
|
||||||
|
|||||||
121
README.md
121
README.md
@@ -19,7 +19,7 @@
|
|||||||
- [Login to Azure US Government cloud](#login-to-azure-us-government-cloud)
|
- [Login to Azure US Government cloud](#login-to-azure-us-government-cloud)
|
||||||
- [Login to Azure Stack Hub](#login-to-azure-stack-hub)
|
- [Login to Azure Stack Hub](#login-to-azure-stack-hub)
|
||||||
- [Login without subscription](#login-without-subscription)
|
- [Login without subscription](#login-without-subscription)
|
||||||
- [Security hardening](#security-hardening)
|
- [Az logout and security hardening](#az-logout-and-security-hardening)
|
||||||
- [Azure CLI dependency](#azure-cli-dependency)
|
- [Azure CLI dependency](#azure-cli-dependency)
|
||||||
- [Reference](#reference)
|
- [Reference](#reference)
|
||||||
- [GitHub Action](#github-action)
|
- [GitHub Action](#github-action)
|
||||||
@@ -56,7 +56,7 @@ Azure Login Action supports different ways of authentication with Azure.
|
|||||||
|tenant-id|false|UUID||the login tenant id|
|
|tenant-id|false|UUID||the login tenant id|
|
||||||
|creds|false|string||a json string for login with an Azure service principal|
|
|creds|false|string||a json string for login with an Azure service principal|
|
||||||
|enable-AzPSSession|false|boolean|false|if Azure PowerShell login is enabled|
|
|enable-AzPSSession|false|boolean|false|if Azure PowerShell login is enabled|
|
||||||
|environment|false|string|azurecloud|the Azure Cloud environment. For cloud environments other than the public cloud, the `audience` will also need to be updated.|
|
|environment|false|string|azurecloud|the Azure Cloud environment|
|
||||||
|allow-no-subscriptions|false|boolean|false|if login without subscription is allowed|
|
|allow-no-subscriptions|false|boolean|false|if login without subscription is allowed|
|
||||||
|audience|false|string|api://AzureADTokenExchange|the audience to get the JWT ID token from GitHub OIDC provider|
|
|audience|false|string|api://AzureADTokenExchange|the audience to get the JWT ID token from GitHub OIDC provider|
|
||||||
|auth-type|false|string|SERVICE_PRINCIPAL|the auth type|
|
|auth-type|false|string|SERVICE_PRINCIPAL|the auth type|
|
||||||
@@ -126,8 +126,6 @@ By default, Azure Login Action connects to the Azure Public Cloud (`AzureCloud`)
|
|||||||
|
|
||||||
To login to one of the Azure Government clouds or Azure Stack, set `environment` to one of the supported values `AzureUSGovernment` or `AzureChinaCloud` or `AzureGermanCloud` or `AzureStack`.
|
To login to one of the Azure Government clouds or Azure Stack, set `environment` to one of the supported values `AzureUSGovernment` or `AzureChinaCloud` or `AzureGermanCloud` or `AzureStack`.
|
||||||
|
|
||||||
The default [`audience`](#audience) for each of these clouds is different and will also need to be set if using anything other than the public environment.
|
|
||||||
|
|
||||||
Refer to [Login to Azure US Government cloud](#login-to-azure-us-government-cloud) for its usage.
|
Refer to [Login to Azure US Government cloud](#login-to-azure-us-government-cloud) for its usage.
|
||||||
|
|
||||||
### `allow-no-subscriptions`
|
### `allow-no-subscriptions`
|
||||||
@@ -185,21 +183,21 @@ name: Run Azure Login with OIDC
|
|||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
contents: read
|
contents: read
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Azure login
|
- name: Azure login
|
||||||
uses: azure/login@v2
|
uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
|
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -215,29 +213,29 @@ name: Run Azure Login with OIDC
|
|||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
contents: read
|
contents: read
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Azure login
|
- name: Azure login
|
||||||
uses: azure/login@v2
|
uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
- name: Azure PowerShell script
|
- name: Azure PowerShell script
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -283,17 +281,18 @@ jobs:
|
|||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: azure/login@v2
|
- uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- **The workflow sample to run both Azure CLI and Azure PowerShell**
|
- **The workflow sample to run both Azure CLI and Azure PowerShell**
|
||||||
@@ -310,21 +309,21 @@ jobs:
|
|||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: azure/login@v2
|
- uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
- name: Azure PowerShell script
|
- name: Azure PowerShell script
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -334,7 +333,7 @@ jobs:
|
|||||||
If you want to pass subscription ID, tenant ID, client ID, and client secret as individual parameters instead of bundling them in a single JSON object to address the [security concerns](https://docs.github.com/actions/security-guides/encrypted-secrets), below snippet can help with the same.
|
If you want to pass subscription ID, tenant ID, client ID, and client secret as individual parameters instead of bundling them in a single JSON object to address the [security concerns](https://docs.github.com/actions/security-guides/encrypted-secrets), below snippet can help with the same.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: azure/login@v2
|
- uses: Azure/login@v1
|
||||||
with:
|
with:
|
||||||
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
|
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
|
||||||
```
|
```
|
||||||
@@ -373,29 +372,29 @@ Now you can try the workflow to login with system-assigned managed identity.
|
|||||||
name: Run Azure Login with System-assigned Managed Identity
|
name: Run Azure Login with System-assigned Managed Identity
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
- name: Azure login
|
- name: Azure login
|
||||||
uses: azure/login@v2
|
uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
auth-type: IDENTITY
|
auth-type: IDENTITY
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
# Azure CLI Action only supports linux self-hosted runners for now.
|
# Azure CLI Action only supports linux self-hosted runners for now.
|
||||||
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
|
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
- name: Azure PowerShell script
|
- name: Azure PowerShell script
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -439,30 +438,30 @@ Now you can try the workflow to login with user-assigned managed identity.
|
|||||||
name: Run Azure Login with User-assigned Managed Identity
|
name: Run Azure Login with User-assigned Managed Identity
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
- name: Azure login
|
- name: Azure login
|
||||||
uses: azure/login@v2
|
uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
auth-type: IDENTITY
|
auth-type: IDENTITY
|
||||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
# Azure CLI Action only supports linux self-hosted runners for now.
|
# Azure CLI Action only supports linux self-hosted runners for now.
|
||||||
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
|
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
- name: Azure PowerShell script
|
- name: Azure PowerShell script
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
@@ -483,12 +482,13 @@ jobs:
|
|||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: azure/login@v2
|
- uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
environment: 'AzureUSGovernment'
|
environment: 'AzureUSGovernment'
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Login to Azure Stack Hub
|
### Login to Azure Stack Hub
|
||||||
@@ -505,12 +505,13 @@ jobs:
|
|||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: azure/login@v2
|
- uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
environment: 'AzureStack'
|
environment: 'AzureStack'
|
||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Refer to the [Azure Stack Hub Login Action Tutorial](https://learn.microsoft.com/azure-stack/user/ci-cd-github-action-login-cli) for more detailed instructions.
|
Refer to the [Azure Stack Hub Login Action Tutorial](https://learn.microsoft.com/azure-stack/user/ci-cd-github-action-login-cli) for more detailed instructions.
|
||||||
@@ -533,7 +534,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Azure Login
|
- name: Azure Login
|
||||||
uses: azure/login@v2
|
uses: azure/login@v1
|
||||||
with:
|
with:
|
||||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
@@ -541,24 +542,44 @@ jobs:
|
|||||||
enable-AzPSSession: true
|
enable-AzPSSession: true
|
||||||
|
|
||||||
- name: Azure CLI script
|
- name: Azure CLI script
|
||||||
uses: azure/cli@v2
|
uses: azure/CLI@v1
|
||||||
with:
|
with:
|
||||||
azcliversion: latest
|
azcliversion: latest
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
az account show
|
az account show
|
||||||
|
|
||||||
- name: Run Azure PowerShell
|
- name: Run Azure PowerShell
|
||||||
uses: azure/powershell@v2
|
uses: azure/powershell@v1
|
||||||
with:
|
with:
|
||||||
azPSVersion: "latest"
|
azPSVersion: "latest"
|
||||||
inlineScript: |
|
inlineScript: |
|
||||||
Get-AzContext
|
Get-AzContext
|
||||||
```
|
```
|
||||||
|
|
||||||
## Security hardening
|
## Az logout and security hardening
|
||||||
|
|
||||||
|
This action doesn't implement ```az logout``` by default at the end of execution. However, there is no way to tamper with the credentials or account information because the GitHub-hosted runner is on a VM that will get re-imaged for every customer run, which deletes everything. But if the runner is self-hosted (not provided by GitHub), it is recommended to manually log out at the end of the workflow, as shown below. More details on security of the runners can be found [here](https://docs.github.com/actions/learn-github-actions/security-hardening-for-github-actions#hardening-for-self-hosted-runners).
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> When using self hosted runners it is possible to have multiple runners on a single VM. Currently if your runners share a single user on the VM each runner will share the same credentials. That means in detail that each runner is able to change the permissions of another run. As a workaround we propose to use one single VM user per runner. If you start the runner as a service, do not forget to add the [optional user argument](https://docs.github.com/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service#installing-the-service)
|
> When using self hosted runners it is possible to have multiple runners on a single VM. Currently if your runners share a single user on the VM each runner will share the same credentials. That means in detail that each runner is able to change the permissions of another run. As a workaround we propose to use one single VM user per runner. If you start the runner as a service, do not forget to add the [optional user argument](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service#installing-the-service)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Azure CLI script
|
||||||
|
uses: azure/CLI@v1
|
||||||
|
with:
|
||||||
|
inlineScript: |
|
||||||
|
az logout
|
||||||
|
az cache purge
|
||||||
|
az account clear
|
||||||
|
|
||||||
|
- name: Azure PowerShell script
|
||||||
|
uses: azure/powershell@v1
|
||||||
|
with:
|
||||||
|
azPSVersion: "latest"
|
||||||
|
inlineScript: |
|
||||||
|
Clear-AzContext -Scope Process
|
||||||
|
Clear-AzContext -Scope CurrentUser
|
||||||
|
```
|
||||||
|
|
||||||
## Azure CLI dependency
|
## Azure CLI dependency
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ describe("LoginConfig Test", () => {
|
|||||||
expect(loginConfig.servicePrincipalId).toBe("client-id");
|
expect(loginConfig.servicePrincipalId).toBe("client-id");
|
||||||
expect(loginConfig.servicePrincipalSecret).toBe("client-secret");
|
expect(loginConfig.servicePrincipalSecret).toBe("client-secret");
|
||||||
expect(loginConfig.tenantId).toBe("tenant-id");
|
expect(loginConfig.tenantId).toBe("tenant-id");
|
||||||
expect(loginConfig.subscriptionId).toBe(undefined);
|
expect(loginConfig.subscriptionId).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initialize with creds', async () => {
|
test('initialize with creds', async () => {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('service principal with secret');
|
expect(loginMethod).toBe('service principal with secret');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -61,7 +61,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('service principal with secret');
|
expect(loginMethod).toBe('service principal with secret');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -82,7 +82,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('service principal with secret');
|
expect(loginMethod).toBe('service principal with secret');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -100,7 +100,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => {loginConfig.federatedToken = "fake-token";});
|
jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => {loginConfig.federatedToken = "fake-token";});
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('OIDC');
|
expect(loginMethod).toBe('OIDC');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -115,7 +115,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('system-assigned managed identity');
|
expect(loginMethod).toBe('system-assigned managed identity');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -130,7 +130,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('system-assigned managed identity');
|
expect(loginMethod).toBe('system-assigned managed identity');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -145,7 +145,7 @@ describe("Getting AzLogin PS script", () => {
|
|||||||
let loginConfig = new LoginConfig();
|
let loginConfig = new LoginConfig();
|
||||||
loginConfig.initialize();
|
loginConfig.initialize();
|
||||||
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
|
||||||
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' -InformationAction Ignore | out-null;")).toBeTruthy();
|
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
|
||||||
expect(loginMethod).toBe('user-assigned managed identity');
|
expect(loginMethod).toBe('user-assigned managed identity');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
16
action.yml
16
action.yml
@@ -1,7 +1,7 @@
|
|||||||
# Login to Azure subscription
|
# Login to Azure subscription
|
||||||
name: 'Azure Login'
|
name: 'Azure Login'
|
||||||
description: 'Authenticate to Azure and run your Azure CLI or Azure PowerShell based actions or scripts.'
|
description: 'Authenticate to Azure and run your Azure CLI or Azure PowerShell based actions or scripts.'
|
||||||
inputs:
|
inputs:
|
||||||
creds:
|
creds:
|
||||||
description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS'
|
description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS'
|
||||||
required: false
|
required: false
|
||||||
@@ -14,7 +14,7 @@ inputs:
|
|||||||
subscription-id:
|
subscription-id:
|
||||||
description: 'Azure subscriptionId'
|
description: 'Azure subscriptionId'
|
||||||
required: false
|
required: false
|
||||||
enable-AzPSSession:
|
enable-AzPSSession:
|
||||||
description: 'Set this value to true to enable Azure PowerShell Login in addition to Azure CLI login'
|
description: 'Set this value to true to enable Azure PowerShell Login in addition to Azure CLI login'
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
@@ -27,11 +27,11 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
audience:
|
audience:
|
||||||
description: 'Provide audience field for access-token. Default value is api://AzureADTokenExchange'
|
description: 'Provide audience field for access-token. Default value is api://AzureADTokenExchange'
|
||||||
required: false
|
required: false
|
||||||
default: 'api://AzureADTokenExchange'
|
default: 'api://AzureADTokenExchange'
|
||||||
auth-type:
|
auth-type:
|
||||||
description: 'The type of authentication. Supported values are SERVICE_PRINCIPAL, IDENTITY. Default value is SERVICE_PRINCIPAL'
|
description: 'The type of authentication. Supported values are SERVICE_PRINCIPAL, IDENTITY. Default value is SERVICE_PRINCIPAL'
|
||||||
required: false
|
required: false
|
||||||
default: 'SERVICE_PRINCIPAL'
|
default: 'SERVICE_PRINCIPAL'
|
||||||
branding:
|
branding:
|
||||||
@@ -39,8 +39,6 @@ branding:
|
|||||||
color: 'blue'
|
color: 'blue'
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: 'node20'
|
||||||
pre: 'lib/cleanup/index.js'
|
pre: 'lib/cleanup.js'
|
||||||
pre-if: (! env.AZURE_LOGIN_PRE_CLEANUP_OFF)
|
main: 'lib/main.js'
|
||||||
main: 'lib/main/index.js'
|
post: 'lib/cleanup.js'
|
||||||
post: 'lib/cleanup/index.js'
|
|
||||||
post-if: (! env.AZURE_LOGIN_POST_CLEANUP_OFF)
|
|
||||||
|
|||||||
4232
package-lock.json
generated
4232
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -1,20 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "login",
|
"name": "login",
|
||||||
"version": "2.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure",
|
"description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure",
|
||||||
"main": "lib/main/index.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:main": "ncc build src/main.ts -o lib/main",
|
"build": "tsc",
|
||||||
"build:cleanup": "ncc build src/cleanup.ts -o lib/cleanup",
|
|
||||||
"build": "npm run build:main && npm run build:cleanup",
|
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"author": "Microsoft",
|
"author": "Sumiran Aggarwal",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.2.4",
|
"@types/jest": "^29.2.4",
|
||||||
"@types/node": "^20.11.1",
|
"@types/node": "^12.7.11",
|
||||||
"@vercel/ncc": "^0.38.1",
|
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.3.1",
|
||||||
"jest-circus": "^29.3.1",
|
"jest-circus": "^29.3.1",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
@@ -24,6 +21,7 @@
|
|||||||
"@actions/core": "1.9.1",
|
"@actions/core": "1.9.1",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.0.1",
|
||||||
|
"actions-secret-parser": "^1.0.4",
|
||||||
"package-lock": "^1.0.3"
|
"package-lock": "^1.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,10 +28,10 @@ export class AzureCliLogin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.executeAzCliCommand(["version"], true, execOptions);
|
await this.executeAzCliCommand(["--version"], true, execOptions);
|
||||||
core.debug(`Azure CLI version used:\n${output}`);
|
core.debug(`Azure CLI version used:\n${output}`);
|
||||||
|
|
||||||
await this.registerAzurestackEnvIfNecessary();
|
this.setAzurestackEnvIfNecessary();
|
||||||
|
|
||||||
await this.executeAzCliCommand(["cloud", "set", "-n", this.loginConfig.environment], false);
|
await this.executeAzCliCommand(["cloud", "set", "-n", this.loginConfig.environment], false);
|
||||||
core.info(`Done setting cloud: "${this.loginConfig.environment}"`);
|
core.info(`Done setting cloud: "${this.loginConfig.environment}"`);
|
||||||
@@ -59,7 +59,7 @@ export class AzureCliLogin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerAzurestackEnvIfNecessary() {
|
async setAzurestackEnvIfNecessary() {
|
||||||
if (this.loginConfig.environment != "azurestack") {
|
if (this.loginConfig.environment != "azurestack") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ export class AzureCliLogin {
|
|||||||
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
|
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
|
||||||
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
|
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
|
||||||
let profileVersion = "2019-03-01-hybrid";
|
let profileVersion = "2019-03-01-hybrid";
|
||||||
await this.executeAzCliCommand(["cloud", "register", "-n", this.loginConfig.environment, "--endpoint-resource-manager", this.loginConfig.resourceManagerEndpointUrl, "--suffix-keyvault-dns", suffixKeyvault, "--suffix-storage-endpoint", suffixStorage, "--profile", profileVersion], false);
|
await this.executeAzCliCommand(["cloud", "register", "-n", this.loginConfig.environment, "--endpoint-resource-manager", `"${this.loginConfig.resourceManagerEndpointUrl}"`, "--suffix-keyvault-dns", `"${suffixKeyvault}"`, "--suffix-storage-endpoint", `"${suffixStorage}"`, "--profile", `"${profileVersion}"`], false);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.error(`Error while trying to register cloud "${this.loginConfig.environment}"`);
|
core.error(`Error while trying to register cloud "${this.loginConfig.environment}"`);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ export default class AzPSScriptBuilder {
|
|||||||
if(subscriptionId){
|
if(subscriptionId){
|
||||||
loginCmdlet += `-Subscription '${subscriptionId}' `;
|
loginCmdlet += `-Subscription '${subscriptionId}' `;
|
||||||
}
|
}
|
||||||
loginCmdlet += `${cmdletSuffix} -InformationAction Ignore | out-null;`;
|
loginCmdlet += `${cmdletSuffix} | out-null;`;
|
||||||
return loginCmdlet;
|
return loginCmdlet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
import { FormatType, SecretParser } from 'actions-secret-parser';
|
||||||
|
|
||||||
export class LoginConfig {
|
export class LoginConfig {
|
||||||
static readonly AUTH_TYPE_SERVICE_PRINCIPAL = "SERVICE_PRINCIPAL";
|
static readonly AUTH_TYPE_SERVICE_PRINCIPAL = "SERVICE_PRINCIPAL";
|
||||||
@@ -48,10 +49,10 @@ export class LoginConfig {
|
|||||||
|
|
||||||
private readParametersFromCreds() {
|
private readParametersFromCreds() {
|
||||||
let creds = core.getInput('creds', { required: false });
|
let creds = core.getInput('creds', { required: false });
|
||||||
if (!creds) {
|
let secrets = creds ? new SecretParser(creds, FormatType.JSON) : null;
|
||||||
|
if (!secrets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let secrets = JSON.parse(creds);
|
|
||||||
|
|
||||||
if(this.authType != LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL){
|
if(this.authType != LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL){
|
||||||
return;
|
return;
|
||||||
@@ -63,11 +64,11 @@ export class LoginConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
core.debug('Reading creds in JSON...');
|
core.debug('Reading creds in JSON...');
|
||||||
this.servicePrincipalId = this.servicePrincipalId ? this.servicePrincipalId : secrets.clientId;
|
this.servicePrincipalId = this.servicePrincipalId ? this.servicePrincipalId : secrets.getSecret("$.clientId", false);
|
||||||
this.servicePrincipalSecret = secrets.clientSecret;
|
this.servicePrincipalSecret = secrets.getSecret("$.clientSecret", false);
|
||||||
this.tenantId = this.tenantId ? this.tenantId : secrets.tenantId;
|
this.tenantId = this.tenantId ? this.tenantId : secrets.getSecret("$.tenantId", false);
|
||||||
this.subscriptionId = this.subscriptionId ? this.subscriptionId : secrets.subscriptionId;
|
this.subscriptionId = this.subscriptionId ? this.subscriptionId : secrets.getSecret("$.subscriptionId", false);
|
||||||
this.resourceManagerEndpointUrl = secrets.resourceManagerEndpointUrl;
|
this.resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
|
||||||
if (!this.servicePrincipalId || !this.servicePrincipalSecret || !this.tenantId) {
|
if (!this.servicePrincipalId || !this.servicePrincipalSecret || !this.tenantId) {
|
||||||
throw new Error("Not all parameters are provided in 'creds'. Double-check if all keys are defined in 'creds': 'clientId', 'clientSecret', 'tenantId'.");
|
throw new Error("Not all parameters are provided in 'creds'. Double-check if all keys are defined in 'creds': 'clientId', 'clientSecret', 'tenantId'.");
|
||||||
}
|
}
|
||||||
@@ -116,3 +117,4 @@ async function jwtParser(federatedToken: string) {
|
|||||||
let decodedPayload = JSON.parse(bufferObj.toString("utf8"));
|
let decodedPayload = JSON.parse(bufferObj.toString("utf8"));
|
||||||
return [decodedPayload['iss'], decodedPayload['sub']];
|
return [decodedPayload['iss'], decodedPayload['sub']];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user