如何在 Azure DevOps 中获取密钥保管库机密输出

How to get keyvault secret output in Azure DevOps

我有秘密的 kv dbname = "DatabaseName".

在 Azure DevOps 中,我使用两个任务,一个是从 Key Vault 读取机密,另一个是 Azure Powershell,我的代码行 Write-Host $(dbname)

日志中的输出是 ***

我想得到 DatabaseName 作为输出。

我唯一找到的是

$DWH = "$(dbname)"
Write-Host "$($DWH.ToCharArray() -join ' ' )"

输出为D a t a b a s e N a m e

是否有可能获得 DatabaseName 而不是 ***D a t a b a s e N a m e

恐怕你得不到你想要的。

出于安全原因,您不能直接在日志中显示秘密。它就是这样设计的。

但不影响您的使用。例如,我刚刚从 Azure Keyvault 下载了机密,我可以在下一个 PowerShell 任务中检查它们:

结果

根据docs,微软屏蔽了日志中的秘密变量,所以你不能正常打印。

您可以安装 Read Secrets from Key Vault 扩展,从 Key Vault 中读取秘密并将它们存储在 常规 变量中(而不是像 Microsoft 内置的秘密变量在任务中)。

根据documentation,可以拆分秘密并输出子串:

We make an effort to mask secrets from appearing in Azure Pipelines output, but you still need to take precautions. Never echo secrets as output. Some operating systems log command line arguments. Never pass secrets on the command line. Instead, we suggest that you map your secrets into environment variables.

We never mask substrings of secrets. If, for example, "abc123" is set as a secret, "abc" isn't masked from the logs. This is to avoid masking secrets at too granular of a level, making the logs unreadable. For this reason, secrets should not contain structured data. If, for example, "{ "foo": "bar" }" is set as a secret, "bar" isn't masked from the logs.

这里是 bash 中的一个例子,它可以被转移到 Powershell:

- task: Bash@3
  inputs:
    targetType: inline
    script: |
      # let's say the secret is Passw0rd

      # Direct output is masked:
      echo $MYSECRET
      # OUTPUTS "***"
    
      # Concatenated output is masked:
      echo "ABC$MYSECRET DDD"
      # outputs "ABC*** DDD"

      
      # Experimenting with substrings:
      firstPart=${MYSECRET::-2}
      secondPart=${MYSECRET: -2}

      # Substrings are displayed:
      echo $firstPart
      # outputs "Passw0"

      echo $secondPart
      # outputs "rd"

      # Substrings concatenated with other strings are displayed:
      echo "$firstPart-$secondPart"
      # outputs "Passw0-rd"

      # Directly concatenated substrings are masked:
      echo "$firstPart$secondPart"
      # outputs "***"

      # Secrets can be written to a file:
      echo "$MYSECRET" > test.txt

      # Secrets are even masked when being displayed as part of a file:
      cat test.txt
      # outputs "***"
    env:
      MYSECRET: $(my_secret) # This is defined in a variable group

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: 'test.txt' # This pipeline artifact contains the secret unmasked
    artifact: 'TestArtifact'
    publishLocation: 'pipeline'
  displayName: 'Publish PipelineRunData artifact'

因此我们有两种选择来获取秘密:

  1. 部分输出秘密并手动连接
  2. 下载管道工件

从安全角度来看可能并不理想,但了解系统的局限性非常重要:有权修改管道的人可能会访问管道使用的秘密。