github-actionsbuilding-github-actionsgithub-secretgithub-actions-reusable-workflows

Unable to access repository secrets in reusable workflows


I have a scan tool that is being run manually using workflow_dispatch event. Now I want to use it automatically for all other repos. So I went with reusable workflows. But I'm getting issues there. I have referred to the github docs also but didn't find anything helpful. The issue is that I'm not able to access the repository secrets defined in the called workflow repository.

Why repository secrets are stored in the called Workflow? Well it's the scanning tool and it needs to be run both manually and also on commits. So the secrets are defined in that repository only. The secrets are required like personal access token for cloning the repo that is calling (caller workflow present) the scantool(called workflow) and various other secrets like for sending the scan report to email.

So I have added both the workflows. I just want to access the repository secrets in the called workflow.

Caller Workflow -

name: scan workflow
on: 
  push:
    branches: '**'

jobs:
  calling-scanner:
    uses: org/repo-name/.github/workflows/main.yml@main
    with:
      repo: ${{ github.event.repository.name }}
      branch: ${{ github.ref_name }}
    secrets: inherit

Called Workflow -

name: scanning-tool
on:
  workflow_call:
    inputs:
        repo:
          description: 'Repo Name'     
          required: true
          type: string
        branch:
          description: 'Branch name'     
          required: true
          type: string


jobs:
  deploy:
    runs-on: [ ubuntu-latest]
    steps:
      - name: checkout
        uses: "actions/checkout@v3"
      - name: Python Dependency Installation
        uses: "py-actions/py-dependency-install@v3.0.0"
        with:
          path: requirements.txt
      - name: setup python
        uses: "actions/setup-python@v3.1.2"
        with:
          python-version: 3.8
      - name: Cloning the Git Repo to be Scanned
        run: git clone -b "${{ inputs.branch }}" "https://github-username:${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/org/${{ inputs.repo }}.git"

Error -

remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/org/TestDemo.git/'
Error: Process completed with exit code 128.

NOTE -

I'm able to run the scan tool workflow manually with the same credentials. It isn't the credential problem as I have even created it for the second time. Still it shows me the same error. That means it is not able to access the secrets.


Solution

  • There may be two issues here:

    First, even inheriting the secrets from the main workflow, you still need to configure the secrets the reusable workflow will use in the workflow_call configuration, as stated in the documentation: Using inputs and secrets in a reusable workflows.

    Therefore, as you use the ${{ secrets.PERSONAL_ACCESS_TOKEN }} in the reusable workflow, your workflow_call trigger should look like this:

    name: scanning-tool
    on:
      workflow_call:
        inputs:
            repo:
              description: 'Repo Name'     
              required: true
              type: string
            branch:
              description: 'Branch name'     
              required: true
              type: string
        secrets:
            PERSONAL_ACCESS_TOKEN:
              required: true
    

    Second, as stated in the documentation shared above:

    Workflows that call reusable workflows in the same organization or enterprise can use the inherit keyword to implicitly pass the secrets.

    Therefore, if your repository isn't part of an organization or enterprise, or if your secret isn't an ORGANIZATION secret, you'll have to pass the secret explicitly from the caller workflow:

    name: scan workflow
    on: 
      push:
        branches: '**'
    
    jobs:
      calling-scanner:
        uses: org/repo-name/.github/workflows/main.yml@main
        with:
          repo: ${{ github.event.repository.name }}
          branch: ${{ github.ref_name }}
        secrets:
          PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}