jfrog/setup-jfrog-cli

Provide the token as output of OIDC authentication

zemirco opened this issue ยท 7 comments

Is your feature request related to a problem? Please describe.

First of all thank you very much for the OIDC integration. It's really great and we can finally sleep at night as we don't have to worry about access token rotation and misuse. That's awesome ๐ŸŽ‰

We're already using it in production but as we roll out the feature to more and more teams we're also seeing the first issues. It works really fine for Docker, e.g.

    - name: Use JFrog cli via actions
      uses: jfrog/setup-jfrog-cli@v3
      with:
        version: latest
        oidc-provider-name: devops
        oidc-audience: ...
      env:
        JF_URL: ...

    - name: Ping the JFrog server
      run: jf rt ping

    - name: Build Docker image
      run: jf docker build -t ...

    - name: Scan Docker image
      run: jf docker scan ...

    - name: Push Docker image
      run: jf docker push ...

Now we also want to use it for Terraform. So far our GitHub Action looks like this

      - name: set up terraform
        uses: hashicorp/setup-terraform@v3
        with:
          cli_config_credentials_hostname: ...
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}

      - name: terraform fmt
        id: fmt
        run: terraform fmt -check
        continue-on-error: true

      - name: terraform init
        id: init
        run: terraform init

As you can see we're using Access Tokens that we provide as secrets to the workflow. We would like to change that and use the OIDC integration. However we couldn't make it work as we don't have any token :) You're creating the token in the background but you're not providing it to us. We also heard from other teams that they're having problem with Python/Peotry where the tooling needs the token.

Describe the solution you'd like to see

Provide the access token as an output of the setup-jfrog-cli action. Before we started your latest version we've created our own composite action that looked similar to this.

name: JFrog OIDC Action
description: Composite GitHub Action handling JFrog OpenID Connect

outputs:
  token:
    description: JFrog Artifactory Access Token
    value: ${{ steps.token.outputs.token }}

runs:
  using: composite
  steps:
    - name: Get id token
      shell: bash
      run: |
        ID_TOKEN=$(curl --silent \
          --header "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
          "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq --raw-output .value)
        echo "ID_TOKEN=${ID_TOKEN}" >> $GITHUB_ENV

    - name: Exchange token with access
      shell: bash
      id: token
      env:
        ID_TOKEN: ${{ env.ID_TOKEN }}
      run: |
        ACCESS_TOKEN=$(curl --silent \
          --request POST "https://.../access/api/v1/oidc/token" \
          --header "Content-type: application/json" \
          --data "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"$ID_TOKEN\", \"provider_name\": \"awesome-repo\"}" | jq --raw-output .access_token)
        echo "token=${ACCESS_TOKEN}" >> $GITHUB_OUTPUT

This action provides the token as an output and our internal teams were able to use it similar like this.

name: build

jobs:
  build:

    runs-on: ubuntu-latest

    environment: jfrog

    steps:
    - name: Get JFrog access token
      id: token
      uses: .../jfrog-oidc-action@main

    - name: debug
      run: echo token ${{ steps.token.outputs.token }}

Describe alternatives you've considered

No response

Additional context

No response

@zemirco
Appreciate your input! It's great to know the feature is effective for you. The JFrog CLI already has support for Terraform and Python commands. Feel free to utilize these commands using the JFrog CLI. If there's anything you feel is missing, do let us know!

Thank you for the feedback, I really appreciate it.

Can you please still provide the token as an output for all technologies and processes that currently aren't supported by the JFrog CLI?

Right now we're using JFrog as our Terraform backend for storing the state.

https://jfrog.com/help/r/jfrog-artifactory-documentation/terraform-backend-repository

That is not related to "Packaging and Publishing Terraform Modules" as described in the link you've provided. What we need is support for the terraform GitHub Action as seen in my first comment.

      - name: set up terraform
        uses: hashicorp/setup-terraform@v3
        with:
          cli_config_credentials_hostname: ...
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} # <-- IMPORTANT

Do you have an idea how we could solve this problem?

Maybe one more argument for adding this feature. GitHub does the same with their create-github-app-token action.

https://github.com/actions/create-github-app-token

Here is the code from one of their examples.

on: [issues]

jobs:
  hello-world:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/create-github-app-token@v1
        id: app-token
        with:
          app-id: ${{ vars.APP_ID }}
          private-key: ${{ secrets.PRIVATE_KEY }}
      - uses: peter-evans/create-or-update-comment@v3
        with:
          token: ${{ steps.app-token.outputs.token }} # <--- here they're using the token from the previous step
          issue-number: ${{ github.event.issue.number }}
          body: "Hello, World!"

Also in the docs they've described the output

https://github.com/actions/create-github-app-token?tab=readme-ov-file#outputs

And in their action.yaml you see their definition

https://github.com/actions/create-github-app-token/blob/main/action.yml

outputs:
  token:
    description: "GitHub installation access token"

For what it's worth, you can try using the jf cli to emit a new token (jf atc), since jf gets authenticated through this action.

Sadly, in my experience, that will lead you to this bug: jfrog/jfrog-cli#2490

Since you would be doing this in a GitHub action, it may not matter that you break jf's auth after that.

@zemirco @StephenWithPH
Following your feedback we merged and released #151.

Example usage:

- name: Setup JFrog CLI
  id: setup-jfrog-cli
  uses: jfrog/setup-jfrog-cli@v4
  env:
    JF_URL: ${{ secrets.JFROG_PLATFORM_URL }}
  with:
    oidc-provider-name: ${{ env.OIDC_PROVIDER_NAME }}

- name: Authenticate Docker
  uses: docker/login-action@v3
  with:
    registry: ${{ secrets.JFROG_PLATFORM_URL }}/docker
    username: ${{ steps.setup-jfrog-cli.outputs.oidc-user }}
    password: ${{ steps.setup-jfrog-cli.outputs.oidc-token }} 

This feature is now included in the latest v4 release.
We would appreciate your feedback on this.

@yahavi ... this works great! Thank you! ๐ŸŽ‰