1

I want to sign my Docker images with cosign but instead of manually managing my private key for each repo I want to use a keyvault (azure).

This works perfectly on my local pc:

cosign sign --key azurekms://<myvault>.vault.azure.net/<key-name> <my-image>

Now I want to automate it in GitHub Actions. I build the image, log into the registries, log into azure (using (OIDC) with a Azure service principal using a Federated Identity Credential), and run cosign. And it fails with:

cosign sign --key  azurekms://MyKeyVault.vault.azure.net/MyKeyName myimage@digest
Error: public key: public key: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://***.vault.azure.net/keys/MyKeyName/?api-version=7.1: StatusCode=400 -- Original Error: adal: Refresh request failed. Status Code = '400'. Response body: {"error":"invalid_request","error_description":"Identity not found"} Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net
main.go:74: error during command execution: public key: public key: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://***.vault.azure.net/keys/MyKeyName/?api-version=7.1: StatusCode=400 -- Original Error: adal: Refresh request failed. Status Code = '400'. Response body: {"error":"invalid_request","error_description":"Identity not found"} Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net

The login into azure works and I can run az keyvault key list without a problem. But cosign does not work. Can someone help?

This is my GH Action workflow:

name: Docker-Build
on:
  push:

permissions:
  id-token: write
  contents: read
  packages: write

jobs:
  build:

    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Install cosign
        uses: sigstore/cosign-installer@v3

      - name: Setup Docker buildx
        uses: docker/setup-buildx-action@v2

      - name: Log into registry DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.MY_DOCKERHUB_USER }}
          password: ${{ secrets.MY_DOCKERHUB_TOKEN }}

      - name: Log in with Azure
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: Build and push Docker image
        id: build-and-push
        uses: docker/build-push-action@v4
        with:
          tags: ${{ github.actor }}/myimage:${{ github.ref_name }}

      - name: Sign the published Docker image
        run: |
          # Works
          az keyvault key list --id {{ secrets.COSIGN_KEY_STORE }}
          # Does not work
          cosign sign --key ${{ secrets.COSIGN_KEY_STORE }} ${{ github.actor }}/myimage@${{ github.ref_name }}

I tried using a service principal with secrets and OpenID Connect (OIDC) with a Azure service principal using a Federated Identity Credential - no differance. I also changed the scopes and use the az cli (which works)

I'm beyond ideas right now

hegerdes
  • 28
  • 5
  • Seems like cosign can't use the authenticated session setup my az-login right now which is a bummer because than you can not use the Federated Identity Credential setup which is a secret/password-less setup. Hope it gets added. Answer form @BMitch fixes it – hegerdes May 27 '23 at 21:25
  • I'm sure they'd like a passwordless login supported. The issue/PR would probably need to be against the sigstore project. – BMitch May 27 '23 at 21:36
  • I really wanted it to work without a password. I know for a fact that there is a chained-credential client setup for azure-sdk. So I looked into the code and found that they do infact support auth with the CLI See: https://github.com/sigstore/sigstore/blob/1d364091f84230e251d425313e87b8cdd78a971f/pkg/signature/kms/azure/client.go#LL141C27-L141C44. But you have to explicitly set AZURE_AUTH_METHOD=cli Would be nice if you can add it to your answer – hegerdes May 27 '23 at 22:17
  • Great find, I've updated the answer. – BMitch May 27 '23 at 23:29

1 Answers1

0

From the code you found, there's an undocumented variable, AZURE_AUTH_METHOD=cli, to set that will change the authentication from using environment variables to using the CLI:

      - name: Sign the published Docker image
        env:
          AZURE_AUTH_METHOD: cli
        run: |
          cosign sign --key ${{ secrets.COSIGN_KEY_STORE }} ${{ github.actor }}/myimage@${{ github.ref_name }}

Original answer:

Cosign needs the following environment variables defined:

  • AZURE_TENANT_ID
  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET

Reference: https://docs.sigstore.dev/cosign/kms_support/#azure-key-vault

I believe that would look something like:

      - name: Sign the published Docker image
        env:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
        run: |
          cosign sign --key ${{ secrets.COSIGN_KEY_STORE }} ${{ github.actor }}/myimage@${{ github.ref_name }}
BMitch
  • 231,797
  • 42
  • 475
  • 450