Skip to content

Commit

Permalink
Support for AZURE_CREDENTIALSSecretName setting (microsoft#1115)
Browse files Browse the repository at this point in the history
Fixes microsoft#1098

And also fixes an issue, after the federated credential PR that
`$script:keyvaultconnectionExists` is set in one script and tested in
another.

---------

Co-authored-by: freddydk <[email protected]>
  • Loading branch information
freddydk and freddydk authored Jun 26, 2024
1 parent 564f8d7 commit 3ecb65a
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 26 deletions.
8 changes: 7 additions & 1 deletion Actions/AL-Go-Helper.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2403,11 +2403,17 @@ function InstallAzModuleIfNeeded {
InstallModule -name $name -minimumVersion $minimumVersion
}

$script:AzConnected = $false

function ConnectAz {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'GitHub Secrets come in as plain text')]
param(
[PsCustomObject] $azureCredentials
)
if ($script:AzConnected) {
return
}
InstallAzModuleIfNeeded -name 'Az.KeyVault'
try {
Clear-AzContext -Scope Process
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue
Expand All @@ -2431,7 +2437,7 @@ function ConnectAz {
Write-Host "Selecting subscription $($azureCredentials.SubscriptionId)"
Set-AzContext -SubscriptionId $azureCredentials.SubscriptionId -Tenant $azureCredentials.TenantId -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
}
$script:keyvaultConnectionExists = $true
$script:AzConnected = $true
Write-Host "Successfully connected to Azure"
}
catch {
Expand Down
1 change: 1 addition & 0 deletions Actions/ReadSecrets/ReadSecrets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ try {
$result = Invoke-RestMethod -Method GET -UseBasicParsing -Headers @{ "Authorization" = "bearer $ENV:ACTIONS_ID_TOKEN_REQUEST_TOKEN"; "Accept" = "application/vnd.github+json" } -Uri "$ENV:ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
$json += @{ "clientAssertion" = $result.value }
$secretValue = $json | ConvertTo-Json -Compress
MaskValue -key "$secretName with federated token" -value $secretValue
}
catch {
throw "$SecretName doesn't contain any ClientSecret and AL-Go is unable to acquire an ID_TOKEN. Error was $($_.Exception.Message)"
Expand Down
42 changes: 25 additions & 17 deletions Actions/ReadSecrets/ReadSecretsHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,29 @@ Param(
)

$script:gitHubSecrets = $_gitHubSecrets | ConvertFrom-Json
$script:keyvaultConnectionExists = $false
$script:isKeyvaultSet = $script:gitHubSecrets.PSObject.Properties.Name -eq "AZURE_CREDENTIALS"
$script:escchars = @(' ','!','\"','#','$','%','\u0026','\u0027','(',')','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':',';','\u003c','=','\u003e','?','@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\',']','^','_',[char]96,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','{','|','}','~')

. (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve)

function GetAzureCredentialsSecretName {
$settings = $env:Settings | ConvertFrom-Json
if ($settings.PSObject.Properties.Name -eq "AZURE_CREDENTIALSSecretName") {
return $settings.AZURE_CREDENTIALSSecretName
}
else {
return "AZURE_CREDENTIALS"
}
}

function GetAzureCredentials {
$secretName = GetAzureCredentialsSecretName
if ($script:gitHubSecrets.PSObject.Properties.Name -eq $secretName) {
return $script:gitHubSecrets."$secretName"
}
return $null
}


function MaskValue {
Param(
[string] $key,
Expand Down Expand Up @@ -68,10 +85,10 @@ function GetGithubSecret {

function GetKeyVaultCredentials {
$creds = $null
if ($script:isKeyvaultSet) {
$jsonStr = $script:gitHubSecrets.AZURE_CREDENTIALS
$jsonStr = GetAzureCredentials
if ($jsonStr) {
if ($jsonStr -contains "`n" -or $jsonStr -contains "`r") {
throw "Secret AZURE_CREDENTIALS cannot contain line breaks, needs to be formatted as compressed JSON (no line breaks)"
throw "Secret for Azure KeyVault Connection ($(GetAzureCredentialsSecretName)) cannot contain line breaks, needs to be formatted as compressed JSON (no line breaks)"
}
try {
$creds = $jsonStr | ConvertFrom-Json
Expand All @@ -84,7 +101,7 @@ function GetKeyVaultCredentials {
$creds.TenantId | Out-Null
}
catch {
throw "Secret AZURE_CREDENTIALS is wrongly formatted. Needs to be formatted as compressed JSON (no line breaks) and contain at least the properties: clientId, clientSecret, tenantId and subscriptionId."
throw "Secret for Azure KeyVault Connection ($(GetAzureCredentialsSecretName)) is wrongly formatted. Needs to be formatted as compressed JSON (no line breaks) and contain at least the properties: clientId, clientSecret, tenantId and subscriptionId."
}
$keyVaultNameExists = $creds.PSObject.Properties.Name -eq 'keyVaultName'
$settings = $env:Settings | ConvertFrom-Json
Expand All @@ -111,20 +128,11 @@ function GetKeyVaultSecret {
[PsCustomObject] $keyVaultCredentials,
[switch] $encrypted
)

if (-not $script:isKeyvaultSet) {
if ($null -eq $keyVaultCredentials) {
return $null
}

if (-not $script:keyvaultConnectionExists) {
InstallAzModuleIfNeeded -name 'Az.KeyVault'
try {
ConnectAz -azureCredentials $keyVaultCredentials
}
catch {
throw "Error trying to get secrets from Azure Key Vault. Error was $($_.Exception.Message)"
}
}
ConnectAz -azureCredentials $keyVaultCredentials

$secretSplit = $secretName.Split('=')
$envVar = $secretSplit[0]
Expand Down
2 changes: 1 addition & 1 deletion Actions/Sign/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Sign apps with a certificate stored in Azure Key Vault
| :-- | :-: | :-- | :-- |
| shell | | The shell (powershell or pwsh) in which the PowerShell script in this action should run | powershell |
| parentTelemetryScopeJson | | Specifies the parent telemetry scope for the telemetry signal | {} |
| azureCredentialsJson | Yes | Azure Credentials secret | |
| azureCredentialsJson | Yes | Azure Credentials secret (Base 64 encoded) | |
| timestampService | | The URI of the timestamp server | http://timestamp.digicert.com |
| digestAlgorithm | | The digest algorithm to use for signing and timestamping | SHA256 |
| pathToFiles | Yes | The path to the files to be signed |
Expand Down
4 changes: 2 additions & 2 deletions Actions/Sign/Sign.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '', Justification = 'GitHub Secrets are transferred as plain text')]
param(
[Parameter(HelpMessage = "Azure Credentials secret", Mandatory = $true)]
[Parameter(HelpMessage = "Azure Credentials secret (Base 64 encoded)", Mandatory = $true)]
[string] $AzureCredentialsJson,
[Parameter(HelpMessage = "The path to the files to be signed", Mandatory = $true)]
[String] $PathToFiles,
Expand Down Expand Up @@ -34,7 +34,7 @@ try {
Write-Host "::endgroup::"

# Get parameters for signing
$AzureCredentials = ConvertFrom-Json $AzureCredentialsJson
$AzureCredentials = ConvertFrom-Json ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($AzureCredentialsJson)))
$settings = $env:Settings | ConvertFrom-Json
if ($settings.keyVaultName) {
$AzureKeyVaultName = $settings.keyVaultName
Expand Down
2 changes: 1 addition & 1 deletion Actions/Sign/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ inputs:
required: false
default: powershell
azureCredentialsJson:
description: Azure Credentials secret
description: Azure Credentials secret (Base 64 encoded)
required: true
pathToFiles:
description: The path to the files to be signed
Expand Down
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Issue 1083 SyncMode for custom deployments?
- Issue 1109 Why filter deployment settings?
- Fix issue with github ref when running reusable workflows
- Issue 1098 Support for specifying the name of the AZURE_CREDENTIALS secret by adding a AZURE_CREDENTIALSSecretName setting

### Dependencies to PowerShell modules

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ jobs:
with:
shell: ${{ inputs.shell }}
gitHubSecrets: ${{ toJson(secrets) }}
getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets'
getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets,AZURE_CREDENTIALS'

- name: Determine ArtifactUrl
uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@main
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
uses: microsoft/AL-Go-Actions/Sign@main
with:
shell: ${{ needs.Initialization.outputs.githubRunnerShell }}
azureCredentialsJson: ${{ secrets.AZURE_CREDENTIALS }}
azureCredentialsJson: '${{ fromJson(steps.ReadSecrets.outputs.Secrets).AZURE_CREDENTIALS }}'
pathToFiles: '${{ inputs.project }}/.buildartifacts/Apps/*.app'
parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ jobs:
with:
shell: ${{ inputs.shell }}
gitHubSecrets: ${{ toJson(secrets) }}
getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets'
getSecrets: '${{ inputs.secrets }},appDependencyProbingPathsSecrets,AZURE_CREDENTIALS'

- name: Determine ArtifactUrl
uses: microsoft/AL-Go-Actions/DetermineArtifactUrl@main
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
uses: microsoft/AL-Go-Actions/Sign@main
with:
shell: ${{ needs.Initialization.outputs.githubRunnerShell }}
azureCredentialsJson: ${{ secrets.AZURE_CREDENTIALS }}
azureCredentialsJson: '${{ fromJson(steps.ReadSecrets.outputs.Secrets).AZURE_CREDENTIALS }}'
pathToFiles: '${{ inputs.project }}/.buildartifacts/Apps/*.app'
parentTelemetryScopeJson: ${{ needs.Initialization.outputs.telemetryScopeJson }}

Expand Down

0 comments on commit 3ecb65a

Please sign in to comment.