google-github-actions / auth

A GitHub Action for authenticating to Google Cloud.
https://cloud.google.com/iam
Apache License 2.0
969 stars 196 forks source link

Local testing #401

Closed lpezet closed 8 months ago

lpezet commented 8 months ago

TL;DR

Supporting local testing, like using Nektos' act to test workflows locally.

Disclaimer: 1) In the WIF case, I don't fully comprehend how ACTIONS_ID_TOKEN_REQUEST_TOKEN is generated by Github. And maybe there's an easy way to work with it (generate one? that would sound like a security flaw...no?), and 2) I also do not understand the other possible setups with google-github-actions/auth.

Detailed design

When using Workload Identity Federation, the usual setup is something like:

steps:
      - uses: actions/checkout@v3
      - id: 'auth'
        uses: 'google-github-actions/auth@v2'
        with:
          create_credentials_file: true # optional
          token_format: 'access_token'
          workload_identity_provider: ${{ secrets.WORKLOAD_ID_PROVIDER_NAME }}
          service_account: ${{ secrets.WORKLOAD_ID_SA_EMAIL }}

Now the problem then comes when testing such workflow locally.

Considering the following:

  1. Everything is setup correctly in Github (i.e. WIF works just fine). This is irrelevant here but just want to make sure we're not focusing on fixing something that doesn't need fixing.
  2. A simple workflow, such as:
    name: Test Me Locally
    on:
    push:
    pull_request:
    jobs:
    simple-job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - id: 'auth'
        uses: 'google-github-actions/auth@v2'
        with:
          create_credentials_file: true
          token_format: 'access_token'
          workload_identity_provider: ${{ secrets.WORKLOAD_ID_PROVIDER_NAME }}
          service_account: ${{ secrets.WORKLOAD_ID_SA_EMAIL }}
      - name: Simple gcloud action
        run: |
          gcloud storage ls gs://my-bucket --project=my-project
  3. When testing locally, I'd like to avoid having to change (manually or not) the content of that workflow. The goal is really to reduce the amount of changes between a local environment and Github, to make the tests as meaningful as possible. If X is the configuration needed on Github for a workflow to pass, testing X-n configuration, where n is as small as possible, it still meaningful. I can focus on the n changes if my workflow is still not working. In layman terms, don't ask me to switch from WIF to service account keys for the sake of testing.
  4. A clear (?) understanding that google-github-actions/auth's goal is to provide an environment where credentials are available for tools like gcloud to function.

It would be very useful to test my workflow as such:

act --env GOOGLE_SOME_CREDS_MAYBE_ACCESS_TOKEN=some_value push

Additional information

In this specific situation, the problem lies with https://github.com/google-github-actions/auth/blob/main/src/main.ts#L108, where ACTIONS_ID_TOKEN_REQUEST_TOKEN and ACTIONS_ID_TOKEN_REQUEST_URL are not provided (the URL one could easily be provided though).

One solution could be to tweak the if() logic at https://github.com/google-github-actions/auth/blob/main/src/main.ts#L100. Change the existing logic:

# https://github.com/google-github-actions/auth/blob/main/src/main.ts#L100
if (workloadIdentityProvider) {
  ...deal with oidc token...
  client = new WorkloadIdentityFederationClient({ ... })
else {
  ..do with credentials JSON...
  client = new ServiceAccountKeyClient({ ... })
}

to something like this:

const env_creds = process.env.GOOGLE_SOMETHING
...
if (env_creds) { // must be first to "override" the WIF
  ...deal with creds provided as environment variable...
  client = new ?????({ ... })
} else if (workloadIdentityProvider) {
  ...deal with oidc token...
  client = new WorkloadIdentityFederationClient({ ... })
else {
  ..do with credentials JSON...
  client = new ServiceAccountKeyClient({ ... })
}

Security-wise, it's not worse than service keys (it's actually an impractical middle ground between WIF and service account keys, if someone really really wanted to use this beyond local testing, in Github that is).

github-actions[bot] commented 8 months ago

Hi there @lpezet :wave:!

Thank you for opening an issue. Our team will triage this as soon as we can. Please take a moment to review the troubleshooting steps which lists common error messages and their resolution steps.

sethvargo commented 8 months ago

Hi @lpezet - thank you for opening an issue. act is not officially supported by GitHub, and I'm opposed to adding specific logic for ecosystem tooling. OIDC is not specific to Google Cloud (AWS, Azure, and other IDPs support federated identity), so it would be better to raise this issue to act and have the act runtime serve the OIDC URLs and tokens.

In your case, you could probably inject CLOUDSDK_AUTH_ACCESS_TOKEN and add an if conditional in your workflow to skip the auth action if that envvar is defined.

lpezet commented 8 months ago

It's not really about act. I used it only as an example. My actual case is actually when using Terraform and Google Provider. I'll skip google-github-actions/auth as you mentioned, and figure out a different way then. Thanks.