jfrog/setup-jfrog-cli

OIDC integration does not work with Docker when the Identity Mapping is set to Group as the Token Scope on Artifactory's side

derekscp opened this issue · 2 comments

Describe the bug

When you have set the Artifactory OIDC integration to Group in Token Scope it will result in a the username of the format "oidc-provide/identity-mapping" on Artifactory's side but this integration will input the integration as "identity-mapping" this results in a docker pull failing because of the difference in expected usernames.

It fails with the error, "Wrong username was used" when trying to perform a docker login.

Current behavior

Docker pull will fail because the username is not the one that Artifactory expects.

As there is not a way to assign the username when using the token (JF_USER does not work), you will have to instead change the Token Scope to a user instead. You can assign that user only the needed group.

Reproduction steps

  1. Set up the OIDC integration in Artifactory to use Group as the Token Scope.
image
  1. Trigger a github action workflow that utilizes the OIDC token or authentication.
    Note that this happens both with the JF_ACCESS_TOKEN (when utilizing the rest endpoint (access/api/v1/oidc/token) to retrieve the OIDC token) and also with the OIDC Authorization provided by this project. As an example in the following I just used OIDC Authorization method as it is shorter:
name: GitHub Actions Demo
on: [push]

permissions:
  contents: read
  id-token: write


jobs:
  build:
    runs-on: ubuntu-latest
    env:
      OIDC_AUDIENCE: 'jfrog-github'
      OIDC_PROVIDER: 'github'
      JFROG_CLI_LOG_LEVEL: 'DEBUG'
    steps:
      - name: Setup JFrog CLI
        uses: jfrog/setup-jfrog-cli@v4
        env:
          JF_URL: ${{ vars.JF_URL }}
        with:
          oidc-provider-name: ${{ env.OIDC_PROVIDER }}
          oidc-audience: ${{ env.OIDC_AUDIENCE }}
      - name: Check Access Token
        run: |
          jf config show
          jf config ex
      - name: Pull Docker image
        run: jf docker pull ${{ vars.JF_URLBASE}}/docker-docker/hello-world
  1. Perform a docker pull and note the error:
Run jf docker pull ***/docker-docker/hello-world
18:50:20 [Debug] JFrog CLI version: 2.53.2
18:50:20 [Debug] OS/Arch: linux/amd64
18:50:20 [Debug] Sending HTTP GET request to: https://***/artifactory/api/system/version
18:50:20 [Debug] Artifactory response: 200 
18:50:20 [Debug] Sending HTTP GET request to: https://***/artifactory/api/system/version
18:50:20 [Debug] Usage Report: Sending info...
18:50:20 [Debug] Sending HTTP GET request to: https://***/artifactory/api/system/version
18:50:20 [Debug] Artifactory response: 200 
18:50:20 [Debug] Artifactory response: 200 
18:50:20 [Debug] JFrog Artifactory version is: 7.84.6
18:50:20 [Debug] Sending HTTP POST request to: https://***/artifactory/api/system/usage
18:50:20 [Debug] Using access-token details in docker-login command.
Error response from daemon: Get "https://***v2/": unknown: Wrong username was used
18:50:21 [Debug] docker login while assuming proxy-less failed: exit status 1
Error: 1 [Error] docker login failed for: ***.
docker image must be in the form: registry-domain/path-in-repository/image-name:version.
Error: Process completed with exit code 1.

Expected behavior

I expect this JFCLI integration to correctly input the username to what Artifactory expects.

Or less ideally allow the JF_USER to be set when utilizing JF_ACCESS_TOKEN or when using the OIDC Authorization.
i.e.

        with:
          oidc-provider-name: ${{ env.OIDC_PROVIDER }}
          oidc-audience: ${{ env.OIDC_AUDIENCE }}

Setup JFrog CLI version

jfrog/setup-jfrog-cli@v4

JFrog CLI version

2.53.2

Workflow operating system type and version

Github actions Current runner version: '2.316.0' Operating System Ubuntu 22.04.4 LTS

JFrog Artifactory version (if relevant)

7.84.6

JFrog Xray version (if relevant)

No response

The latest release of JFrog CLI, version 2.56.1, and Setup JFrog CLI 4.0.2 should have resolved this issue.
@derekscp, please feel free to reopen if the problem persists.

Hello,

I have a very similar issue using jf npm install.

Setup JFrog CLI
  Obtaining an access token through OpenID Connect...
  Downloading JFrog CLI from https://releases.jfrog.io/artifactory/jfrog-cli/v2/2.58.2/jfrog-cli-linux-amd64/jfrog
  /opt/hostedtoolcache/jf/2.58.2/x64/jf config add setup-jfrog-cli-server --url https://xxx.jfrog.io --interactive=false --overwrite=true --access-token ***
  15:33:27 [Debug] JFrog CLI version: 2.58.2
  15:33:27 [Debug] OS/Arch: linux/amd64
  15:33:27 [Debug] Trace ID for JFrog Platform logs: xxx
  15:33:27 [Debug] Locking config file to run config AddOrEdit command.
  15:33:27 [Debug] Creating lock in: /home/runner/.jfrog/locks/config
  15:33:27 [Debug] config file is released.
  15:33:27 [Debug] Releasing lock: /home/runner/.jfrog/locks/config/jfrog-cli.conf.lck.[14](https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx/job/xxx?pr=xxx#step:2:15)82.1718724807446860885
 
Run jf npm-config --repo-resolve=security-prod-npm
  jf npm-config --repo-resolve=security-prod-npm
  shell: /usr/bin/bash -e {0}
  env:
    OIDC_AUDIENCE: xxx-xxx
    OIDC_PROVIDER: setup-jfrog-cli
    JFROG_CLI_LOG_LEVEL: DEBUG
    JFROG_CLI_ENV_EXCLUDE: *password*;*secret*;*key*;*token*;*auth*;JF_ARTIFACTORY_*;JF_ENV_*;JF_URL;JF_USER;JF_PASSWORD;JF_ACCESS_TOKEN
    JFROG_CLI_OFFER_CONFIG: false
    JFROG_CLI_BUILD_NAME: CI
    JFROG_CLI_BUILD_NUMBER: 105[2](https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx/job/xxx?pr=xxx#step:6:2)
    JFROG_CLI_BUILD_URL: https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx
    JFROG_CLI_USER_AGENT: setup-jfrog-cli-github-action/4.1.0
    JFROG_CLI_BUILD_PROJECT: security
    JFROG_CLI_COMMAND_SUMMARY_OUTPUT_DIR: /home/runner/work/_temp
15:[3](https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx/job/xxx?pr=xxx#step:6:3)3:31 [Debug] JFrog CLI version: 2.58.2
15:33:31 [Debug] OS/Arch: linux/amd6[4](https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx/job/xxx?pr=441#step:6:4)
15:33:31 [Debug] Trace ID for JFrog Platform logs: xxx
1[5](https://github.com/xxx-xxx/xxx/actions/runs/xxx/job/xxx?pr=441#step:6:5):33:31 [Info] npm build config successfully created.
 
Run jf npm install --module=xxx-xxx
15:33:31 [Debug] JFrog CLI version: 2.58.2
15:33:31 [Debug] OS/Arch: linux/amd64
15:33:31 [Debug] Trace ID for JFrog Platform logs: b4f85fa9221f9b7c
15:33:31 [Debug] Preparing to read the config file /home/runner/work/xxx-xxx/xxx-xxx/.jfrog/projects/npm.yaml
15:33:31 [Debug] Found resolver in the config file /home/runner/work/xxx-xxx/xxx-xxx/.jfrog/projects/npm.yaml
15:33:31 [Debug] Preparing prerequisites...
15:33:31 [Debug] Usage Report: Sending info...
15:33:31 [Debug] Using npm executable: /opt/hostedtoolcache/node/[20](https://github.com/xxx-xxx/xxx-xxx/actions/runs/xxx/job/xxx?pr=xxx#step:7:21).14.0/x64/bin/npm
15:33:31 [Debug] Running 'npm --version' command.
15:33:31 [Debug] Sending HTTP GET request to: https://xxx.jfrog.io/artifactory/api/system/version
15:33:31 [Debug] npm '--version' standard output is:
10.7.0
15:33:31 [Debug] Artifactory response: 200 
15:33:31 [Debug] JFrog Artifactory version is: 7.87.3
15:33:31 [Debug] Sending HTTP POST request to: https://xxx.jfrog.io/artifactory/api/system/usage
15:33:31 [Debug] Working directory set to: /home/runner/work/xxx-xxx/xxx-xxx
15:33:31 [Debug] Sending HTTP GET request to: https://xxx.jfrog.io/artifactory/api/system/version
15:33:31 [Debug] Artifactory response: 200 
15:33:31 [Debug] JFrog Artifactory version is: 7.87.3
15:33:31 [Debug] Sending npm auth request
15:33:31 [Debug] Sending HTTP GET request to: https://xxx.jfrog.io/artifactory/api/npm/auth
15:33:32 [Warn] The server response: 500 
{
  "errors": [
    {
      "status": 500,
      "message": "User must have a username"
    }
  ]
}

The workflow file:

name: CI

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/ci.yml"
      - "apps/**"
      - "packages/**"
      - "package.json"
      - "package-lock.json"
      - "turbo.yaml"

  pull_request:
    branches:
      - main
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - ".github/workflows/ci.yml"
      - "apps/**"
      - "packages/**"
      - "package.json"
      - "package-lock.json"
      - "turbo.yaml"

permissions:
  actions: read # for detecting the GitHub Actions environment.
  id-token: write # for creating OIDC tokens for signing.
  packages: write # for uploading attestations.
  contents: read

jobs:
  build:
    name: Lint and build

    timeout-minutes: 15

    runs-on: ubuntu-latest

    permissions:
      actions: read # for detecting the GitHub Actions environment.
      id-token: write # for creating OIDC tokens for signing.
      packages: write # for uploading attestations.
      contents: read

    env:
      OIDC_AUDIENCE: 'xxx-xxx'
      OIDC_PROVIDER: 'setup-jfrog-cli'
      JFROG_CLI_LOG_LEVEL: 'DEBUG'

    steps:
      - name: Setup JFrog CLI
        id: setup-jfrog-cli
        uses: jfrog/setup-jfrog-cli@7c95feb32008765e1b4e626b078dfd897c4340ad # v4.1.2
        env:
          JF_URL: "https://xxx.jfrog.io"
          JF_PROJECT: "security"
        with:
          oidc-provider-name: ${{ env.OIDC_PROVIDER }}
          oidc-audience: ${{ env.OIDC_AUDIENCE }}
          version: 2.58.2

      - name: Check Access Token
        run: |
          jf config show
          jf config ex

      - name: Check out code
        uses: actions/checkout@v4

      - name: Setup Node.js environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "npm"

      - name: JF config
        run: jf npm-config --repo-resolve=security-prod-npm

      - name: Install dependencies
        run: jf npm install --module=xxx-xxx

      - name: Lint
        run: npm run lint

      - name: Build
        run: jf npm run build --module=xxx-xxx

      - if: always()
        name: Xray Scan
        run: |
          jf bs

      - if: always()
        name: publish build info
        run: |
          jf rt build-publish

When we look at the official blog post that announced the OIDC support, we see that the demo used "Admin" as token scope. When we use Admin, the job indeed works. That being said, it's looks very non-least-privileges-friendly.

Could someone have a look, and document the mapping required to:

  • Resolve dependencies
  • Scan with X-Ray
  • Publish build infos
    ?

So far, I did not succeed at creating a Workflow that has least privileges from which I can do a poetry install or a npm install.

Thank you for the help!