Compare commits

...

7 Commits

Author SHA1 Message Date
shiyingchen
e71c9e98f6 test ncc 2024-03-27 16:25:12 +08:00
shiyingchen
67253182eb use ncc to compile 2024-03-27 16:21:03 +08:00
Shiying Chen
81e1d9f360 Update README.md for azure/login@v2 (#423)
* update readme

* fix lint error

* remove 'en' from link
2024-03-04 14:01:45 +08:00
Shiying Chen
c847559275 Bump dependencies versions (#419)
* bump dependencies version

* abandon jsonpath

* remove jspath
2024-02-22 16:10:10 +08:00
Justin Chao
332d569187 Update Action to use Node.js v20 (#411)
* Update Action to use Node.js v20

Node.js 16 actions are deprecated.
Updating action to use Node.js 20.

Link: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/

* Updating all Github workflows to use Node 20.x

Updating all Github workflows used in CI checks to use Node 20.x

---------

Co-authored-by: Justin Chao <justin.chao@optum.com>
Co-authored-by: Shiying Chen <shiyingchen@microsoft.com>
2024-02-20 13:44:57 +08:00
Shiying Chen
dcaef1266d Temp change ci test for a bug in azps (#416) 2024-02-20 13:33:37 +08:00
Shiying Chen
3d449ed579 Fix CodeQL error: Resource not accessible by integration & Update CodeQL version (#417) 2024-02-20 13:27:37 +08:00
14 changed files with 10080 additions and 3842 deletions

View File

@@ -21,10 +21,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |
@@ -84,10 +84,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |
@@ -345,10 +345,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |

View File

@@ -20,10 +20,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |
@@ -116,10 +116,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |
@@ -219,7 +219,7 @@ jobs:
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext -ListAvailable).Count -eq 2
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
if(-not $checkResult){
throw "Not all checks passed!"
}
@@ -256,10 +256,10 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |

View File

@@ -16,11 +16,11 @@ jobs:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
# Using 16.x version as an example
- name: Set Node.js 16.x for GitHub Action
# Using 20.x version as an example
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: installing node_modules
run: npm install

View File

@@ -20,16 +20,16 @@ jobs:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: 'Validate build'
run: |
npm install
npm run build
- name: 'Run L0 tests'
run: |
npm run test

View File

@@ -6,6 +6,11 @@ on:
schedule:
- cron: '0 19 * * 0'
permissions:
actions: read
contents: read
security-events: write
jobs:
CodeQL-Build:
@@ -18,14 +23,14 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: javascript
# 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)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -39,4 +44,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

View File

@@ -11,7 +11,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: Run Markdownlint
run: |
npm i -g markdownlint-cli2

View File

@@ -19,7 +19,7 @@
- [Login to Azure US Government cloud](#login-to-azure-us-government-cloud)
- [Login to Azure Stack Hub](#login-to-azure-stack-hub)
- [Login without subscription](#login-without-subscription)
- [Az logout and security hardening](#az-logout-and-security-hardening)
- [Security hardening](#security-hardening)
- [Azure CLI dependency](#azure-cli-dependency)
- [Reference](#reference)
- [GitHub Action](#github-action)
@@ -190,7 +190,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
@@ -220,7 +220,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
@@ -282,7 +282,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
@@ -310,7 +310,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true
@@ -333,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.
```yaml
- uses: Azure/login@v1
- uses: azure/login@v2
with:
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
```
@@ -377,7 +377,7 @@ jobs:
runs-on: self-hosted
steps:
- name: Azure login
uses: azure/login@v1
uses: azure/login@v2
with:
auth-type: IDENTITY
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
@@ -443,7 +443,7 @@ jobs:
runs-on: self-hosted
steps:
- name: Azure login
uses: azure/login@v1
uses: azure/login@v2
with:
auth-type: IDENTITY
client-id: ${{ secrets.AZURE_CLIENT_ID }}
@@ -483,7 +483,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
environment: 'AzureUSGovernment'
@@ -506,7 +506,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
environment: 'AzureStack'
@@ -534,7 +534,7 @@ jobs:
steps:
- name: Azure Login
uses: azure/login@v1
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
@@ -556,30 +556,10 @@ jobs:
Get-AzContext
```
## 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).
## Security hardening
> [!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/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
```
> 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)
## Azure CLI dependency

View File

@@ -96,7 +96,7 @@ describe("LoginConfig Test", () => {
expect(loginConfig.servicePrincipalId).toBe("client-id");
expect(loginConfig.servicePrincipalSecret).toBe("client-secret");
expect(loginConfig.tenantId).toBe("tenant-id");
expect(loginConfig.subscriptionId).toBe("");
expect(loginConfig.subscriptionId).toBe(undefined);
});
test('initialize with creds', async () => {

View File

@@ -1,7 +1,7 @@
# Login to Azure subscription
name: 'Azure Login'
description: 'Authenticate to Azure and run your Azure CLI or Azure PowerShell based actions or scripts.'
inputs:
inputs:
creds:
description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS'
required: false
@@ -14,7 +14,7 @@ inputs:
subscription-id:
description: 'Azure subscriptionId'
required: false
enable-AzPSSession:
enable-AzPSSession:
description: 'Set this value to true to enable Azure PowerShell Login in addition to Azure CLI login'
required: false
default: false
@@ -27,18 +27,18 @@ inputs:
required: false
default: false
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
default: 'api://AzureADTokenExchange'
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
default: 'SERVICE_PRINCIPAL'
branding:
icon: 'login.svg'
color: 'blue'
runs:
using: 'node16'
pre: 'lib/cleanup.js'
main: 'lib/main.js'
post: 'lib/cleanup.js'
using: 'node20'
pre: 'lib/cleanup/index.js'
main: 'lib/main/index.js'
post: 'lib/cleanup/index.js'

4632
lib/cleanup/index.js Normal file

File diff suppressed because it is too large Load Diff

4911
lib/main/index.js Normal file

File diff suppressed because it is too large Load Diff

4232
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,20 @@
{
"name": "login",
"version": "1.0.0",
"version": "2.0.0",
"description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure",
"main": "lib/main.js",
"main": "lib/main/index.js",
"scripts": {
"build": "tsc",
"build:main": "ncc build src/main.ts -o lib/main",
"build:cleanup": "ncc build src/cleanup.ts -o lib/cleanup",
"build": "npm run build:main && npm run build:cleanup",
"test": "jest"
},
"author": "Sumiran Aggarwal",
"author": "Microsoft",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.2.4",
"@types/node": "^12.7.11",
"@types/node": "^20.11.1",
"@vercel/ncc": "^0.38.1",
"jest": "^29.3.1",
"jest-circus": "^29.3.1",
"ts-jest": "^29.0.3",
@@ -21,7 +24,6 @@
"@actions/core": "1.9.1",
"@actions/exec": "^1.0.1",
"@actions/io": "^1.0.1",
"actions-secret-parser": "^1.0.4",
"package-lock": "^1.0.3"
}
}
}

View File

@@ -1,5 +1,4 @@
import * as core from '@actions/core';
import { FormatType, SecretParser } from 'actions-secret-parser';
export class LoginConfig {
static readonly AUTH_TYPE_SERVICE_PRINCIPAL = "SERVICE_PRINCIPAL";
@@ -49,10 +48,10 @@ export class LoginConfig {
private readParametersFromCreds() {
let creds = core.getInput('creds', { required: false });
let secrets = creds ? new SecretParser(creds, FormatType.JSON) : null;
if (!secrets) {
if (!creds) {
return;
}
let secrets = JSON.parse(creds);
if(this.authType != LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL){
return;
@@ -64,11 +63,11 @@ export class LoginConfig {
}
core.debug('Reading creds in JSON...');
this.servicePrincipalId = this.servicePrincipalId ? this.servicePrincipalId : secrets.getSecret("$.clientId", false);
this.servicePrincipalSecret = secrets.getSecret("$.clientSecret", false);
this.tenantId = this.tenantId ? this.tenantId : secrets.getSecret("$.tenantId", false);
this.subscriptionId = this.subscriptionId ? this.subscriptionId : secrets.getSecret("$.subscriptionId", false);
this.resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
this.servicePrincipalId = this.servicePrincipalId ? this.servicePrincipalId : secrets.clientId;
this.servicePrincipalSecret = secrets.clientSecret;
this.tenantId = this.tenantId ? this.tenantId : secrets.tenantId;
this.subscriptionId = this.subscriptionId ? this.subscriptionId : secrets.subscriptionId;
this.resourceManagerEndpointUrl = secrets.resourceManagerEndpointUrl;
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'.");
}
@@ -117,4 +116,3 @@ async function jwtParser(federatedToken: string) {
let decodedPayload = JSON.parse(bufferObj.toString("utf8"));
return [decodedPayload['iss'], decodedPayload['sub']];
}