sorin
sorin

Reputation: 170310

How to use reusable GitHub workflows and keep secrets in a single place?

While reusable GitHub workflows do help with maintenance of GitHub Actions in general, reducing a lot of copy/paste from one repository to another, they still seem to have one big issue: dealing with secrets.

When implementing an action like "post to Slack", or "post to matrix/IRC", you will need some secrets for the bot account, and if you want to reuse this action in 50 repositories you can imagine while managing secrets in each repository does not scale.

I am looking for a solution to this problem that does not involve deploying secrets to all repositories using an action, some way to centralize them.

Keep in mind that reusable workflows work across organizations and I already have some of them shared across 4+ organizations. So configuring organization level secrets is not a solution either, also for other reasons: they can easily be exposed because they are available to any workflow (as opposed to environment based ones).

Upvotes: 31

Views: 37661

Answers (5)

deepak
deepak

Reputation: 3172

this worked for me. Pass env as a explicit variable and secrets too. https://colinsalmcorner.com/consuming-environment-secrets-in-reusable-workflows/#attempt-3-pass-the-environment-and-secrets

Upvotes: 0

Craig Wayne
Craig Wayne

Reputation: 5060

Just gonna use Docker login fuctionality as an example

Suppose you have the following two secrets:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_PERSONAL_ACCESS_TOKEN

your main workflow file

main.yml

name: Main
permissions:
  id-token: write
  contents: read

jobs:
  build_job:
    name: "Build & Test"
    runs-on: ubuntu-latest
  
    steps:
      - uses: actions/checkout@v4

      - name: Do build things
        run: |
          echo "building...";

  my_reusable_workflow_job:
    needs: [ build_job]
    uses: './.github/workflows/_reusable_workflow.yml'
    secrets: inherit

_reusable_workflow.yml

name: "Reusable Workflow"
  
# means that it will only run in github actions when called from another workflow
on:
  workflow_call: 

jobs:
  reusable_job:
    name: "Login into Docker Hub"
    runs-on: ubuntu-latest
    steps:
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PERSONAL_ACCESS_TOKEN }}

DOCS: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idsecrets

Upvotes: 2

Benjamin W.
Benjamin W.

Reputation: 52102

This exact scenario is addressed in the GitHub roadmap issue GitHub Actions secrets improvements for Reusable workflows:

With this current improvement, teams managing reusable workflows can refer to the secrets from the called (source) repos. These secrets are available only in the reusable workflow run context within in the caller (target) repos.

Unfortunately, as of March 2024, the issue is scheduled for "Future"; there are columns up to Q4 2024.

Upvotes: 10

VonC
VonC

Reputation: 1323095

Check if the new (May 2022) keyword secrets: inherit can help:

GitHub Actions: Simplify using secrets with reusable workflows

GitHub Actions simplifies using secrets with reusable workflows with the secrets: inherit keyword.

Previously when passing secrets to a reusable workflow, you had to pass each secret as a separate argument.

Now you can simply pass the secrets: inherit to the reusable workflow and the secrets will be inherited from the calling workflow.

Learn more about reusable workflows in GitHub Actions and jobs.<job_id>.steps[*].uses.

In the reusable workflow, reference the input or secret that you defined in the on key in the previous step.

If the secrets are inherited using secrets: inherit, you can reference them even if they are not defined in the on key.

jobs:
 reusable_workflow_job:
   runs-on: ubuntu-latest
   environment: production
   steps:
     - uses: ./.github/workflows/my-action
       with:
         username: ${{ inputs.username }}
         token: ${{ secrets.envPAT }}

In the example above, envPAT is an environment secret that's been added to the production environment. This environment is therefore referenced within the job.

Note: Environment secrets are encrypted strings that are stored in an environment that you've defined for a repository.
Environment secrets are only available to workflow jobs that reference the appropriate environment.
For more information, see "Using environments for deployment."

Again, see jobs.<job_id>.steps[*].uses for additional examples.


As noted by wkhatch in the comments:

I don't believe this syntax is correct for using a reusable workflow, but is correct for using reusable actions.
You cannot call a reusable workflow as a step, but you can with an action.

Upvotes: 26

Brendan Lafond
Brendan Lafond

Reputation: 11

Organization secrets can help with this problem, but it's not an ideal solution for all use cases. Your situation is similar to a situation I had with implementing SAST. Rather than having each team setup the job manually and incorrectly set failure levels or forget to output to SARIF and upload, I just created a reusable job. The challenge is the API credentials weren't available from the called workflow repository secrets. I can work around this with org secrets. I have other use cases, where it's much more difficult to use an org secret and still enforce good behavior.

Upvotes: 1

Related Questions