Compare commits

...

5 Commits

Author SHA1 Message Date
Shiying Chen
bbcc074a23 Use --client-id for user-assigned managed identity authentication in Azure CLI v2.69.0 or later. (#514) 2025-03-04 09:39:48 +08:00
Shiying Chen
877e2b442c Log more claims for OIDC login (#520) 2025-03-03 15:30:34 +08:00
Shiying Chen
888619bccc mention allow-no-subscriptions in missing subscriptionId error (#512) 2025-02-13 15:45:28 +08:00
Yan Xu
3fcf81c86c Bump braces from 3.0.2 to 3.0.3 (#511)
* Bump braces from 3.0.2 to 3.0.3

Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* remove libicu and update powershell version

* apt install libicu72

* change installation url

* fix typo

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MoChilia <chenshiyingcn@163.com>
Co-authored-by: Shiying Chen <shiyingchen@microsoft.com>
2025-02-13 13:22:44 +08:00
Shiying Chen
6047d58862 replace the invalid link for github action doc (#510) 2025-02-13 11:20:07 +08:00
6 changed files with 64 additions and 17 deletions

View File

@@ -266,10 +266,10 @@ jobs:
run: |
apt-get update
apt-get install -y wget
wget https://mirror.it.ubc.ca/ubuntu/pool/main/i/icu/libicu72_72.1-3ubuntu3_amd64.deb
dpkg -i libicu72_72.1-3ubuntu3_amd64.deb
wget https://github.com/PowerShell/PowerShell/releases/download/v7.4.3/powershell_7.4.3-1.deb_amd64.deb
dpkg -i powershell_7.4.3-1.deb_amd64.deb
wget https://ftp.debian.org/debian/pool/main/i/icu/libicu72_72.1-3_amd64.deb
dpkg -i libicu72_72.1-3_amd64.deb
wget https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell_7.5.0-1.deb_amd64.deb
dpkg -i powershell_7.5.0-1.deb_amd64.deb
- name: Check Powershell Version
shell: pwsh

View File

@@ -679,7 +679,7 @@ Internally in this action, we use azure CLI and execute `az login` with the cred
### GitHub Action
[GitHub Actions](https://help.github.com/articles/about-github-actions) gives you the flexibility to build an automated software development lifecycle workflow.
[GitHub Actions](https://docs.github.com/actions) gives you the flexibility to build an automated software development lifecycle workflow.
### GitHub Actions for deploying to Azure

View File

@@ -245,7 +245,7 @@ describe("LoginConfig Test", () => {
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Ensure subscriptionId is supplied.");
testValidateWithErrorMessage(loginConfig, "Ensure 'subscription-id' is supplied or 'allow-no-subscriptions' is 'true'.");
});
test('validate without subscriptionId and allowNoSubscriptionsLogin=true', async () => {

14
package-lock.json generated
View File

@@ -1278,11 +1278,13 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -1638,7 +1640,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1839,6 +1843,8 @@
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3125,6 +3131,8 @@
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -8,6 +8,7 @@ export class AzureCliLogin {
loginConfig: LoginConfig;
azPath: string;
loginOptions: ExecOptions;
azVersion: string;
constructor(loginConfig: LoginConfig) {
this.loginConfig = loginConfig;
@@ -30,7 +31,12 @@ export class AzureCliLogin {
await this.executeAzCliCommand(["version"], true, execOptions);
core.debug(`Azure CLI version used:\n${output}`);
try {
this.azVersion = JSON.parse(output)["azure-cli"];
}
catch (error) {
core.warning("Failed to parse Azure CLI version.");
}
await this.registerAzurestackEnvIfNecessary();
await this.executeAzCliCommand(["cloud", "set", "-n", this.loginConfig.environment], false);
@@ -108,7 +114,20 @@ export class AzureCliLogin {
}
async loginWithUserAssignedIdentity(args: string[]) {
args.push("--username", this.loginConfig.servicePrincipalId);
let azcliMinorVersion = 0;
try {
azcliMinorVersion = parseInt(this.azVersion.split('.')[1], 10);
}
catch (error) {
core.warning("Failed to parse the minor version of Azure CLI. Assuming the version is less than 2.69.0");
}
//From Azure-cli v2.69.0, `--username` is replaced with `--client-id`, `--object-id` or `--resource-id`: https://github.com/Azure/azure-cli/pull/30525
if (azcliMinorVersion < 69) {
args.push("--username", this.loginConfig.servicePrincipalId);
}
else {
args.push("--client-id", this.loginConfig.servicePrincipalId);
}
await this.callCliLogin(args, 'user-assigned managed identity');
}

View File

@@ -79,11 +79,16 @@ export class LoginConfig {
this.mask(this.federatedToken);
}
catch (error) {
core.error(`Please make sure to give write permissions to id-token in the workflow.`);
core.error("Failed to fetch federated token from GitHub. Please make sure to give write permissions to id-token in the workflow.");
throw error;
}
let [issuer, subjectClaim] = await jwtParser(this.federatedToken);
core.info("Federated token details:\n issuer - " + issuer + "\n subject claim - " + subjectClaim);
try {
let [issuer, subjectClaim, audience, jobWorkflowRef] = await jwtParser(this.federatedToken);
core.info("Federated token details:\n issuer - " + issuer + "\n subject claim - " + subjectClaim + "\n audience - " + audience + "\n job_workflow_ref - " + jobWorkflowRef);
}
catch (error) {
core.warning(`Failed to parse the federated token. Error: ${error}`);
}
}
validate() {
@@ -99,7 +104,7 @@ export class LoginConfig {
}
}
if (!this.subscriptionId && !this.allowNoSubscriptionsLogin) {
throw new Error("Ensure subscriptionId is supplied.");
throw new Error("Ensure 'subscription-id' is supplied or 'allow-no-subscriptions' is 'true'.");
}
}
@@ -114,5 +119,20 @@ async function jwtParser(federatedToken: string) {
let tokenPayload = federatedToken.split('.')[1];
let bufferObj = Buffer.from(tokenPayload, "base64");
let decodedPayload = JSON.parse(bufferObj.toString("utf8"));
return [decodedPayload['iss'], decodedPayload['sub']];
}
const JWT_CLAIM_ISSUER = 'iss';
const JWT_CLAIM_SUBJECT = 'sub';
const JWT_CLAIM_AUDIENCE = 'aud';
const JWT_CLAIM_JOB_WORKFLOW_REF = 'job_workflow_ref';
const requiredClaims = [
JWT_CLAIM_ISSUER,
JWT_CLAIM_SUBJECT,
JWT_CLAIM_AUDIENCE,
JWT_CLAIM_JOB_WORKFLOW_REF
];
for (const claim of requiredClaims) {
if (!decodedPayload[claim]) {
throw new Error(`The claim '${claim}' is missing from the token payload`);
}
}
return [decodedPayload[JWT_CLAIM_ISSUER], decodedPayload[JWT_CLAIM_SUBJECT], decodedPayload[JWT_CLAIM_AUDIENCE], decodedPayload[JWT_CLAIM_JOB_WORKFLOW_REF]];
}