Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Cannot get repo #126

Open
jamesgeddes opened this issue Apr 9, 2024 · 6 comments
Open

Bug: Cannot get repo #126

jamesgeddes opened this issue Apr 9, 2024 · 6 comments

Comments

@jamesgeddes
Copy link

Hi All,

I am setting up a github bot for use with github actions, but it cannot access the repos API endpoint.

Here are the permissions that the bot is set to (way too permissive, I know, but I am just testing).

FireShot Capture 001 - GitHub Apps - GedBot - github com

Here is my test action workflow

name: "test_gh_api"

on:
  workflow_dispatch:
  push:

permissions:
  id-token: write
  contents: write
  pull-requests: write
  packages: write
  actions: write
  checks: write


jobs:

  call_api:
    name: "Call GH API"
    runs-on: ubuntu-latest

    steps:
      - name: Generate GedBot token
        id: generate_token
        uses: actions/create-github-app-token@v1
        with:
          app-id: ${{ secrets.GEDBOT_APP_ID }}
          private-key: ${{ secrets.GEDBOT_PRIVATE_KEY }}

      - name: Checkout the code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ steps.generate_token.outputs.token }}

      - name: Test GH API
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
        run: |
          echo "Running curl"
          curl --request GET \
            --header "Accept: application/vnd.github+json" \
            --header "Authorization: Bearer GITHUB_TOKEN" \
            --header "X-GitHub-Api-Version: 2022-11-28" \
            --url "https://api.github.com/repos/geddesfamily/estate-config"
          echo "Running GH CLI"
          gh api repos/geddesfamily/estate-config
          gh api repos/geddesfamily/estate-config/branches

I can confirm that geddesfamily/estate-config does exist.

This returns


Run echo "Running curl"
Running curl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
{
100    90  100    90    0     0   1437      0 --:--:-- --:--:-- --:--:--  1451
  "message": "Bad credentials",
  "documentation_url": "https://docs.github.com/rest"
}
Running GH CLI
gh: Not Found (HTTP 404)
{"message":"Not Found","documentation_url":"https://docs.github.com/rest/repos/repos#get-a-repository"}
Error: Process completed with exit code 1.

I feel like this covers all bases to mitigate the risk of the problem being cause by my idiocy, however it is always a possibility!

Is this a bug in the token gen step?

@jamesgeddes
Copy link
Author

Interestingly, explicitly generating the JWT and IAT, without using actions/create-github-app-token does work.

      - name: Generate JWT
        run: |
          set -o pipefail
          
          app_id=${{ secrets.GEDBOT_APP_ID }} # App ID as first argument
          pem="${{ secrets.GEDBOT_APP_PEM_FILE }}" # file path of the private key as second argument
          
          now=$(date +%s)
          iat=$((${now} - 60)) # Issues 60 seconds in the past
          exp=$((${now} + 600)) # Expires 10 minutes in the future
          
          b64enc() { openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'; }
          
          header_json='{
              "typ":"JWT",
              "alg":"RS256"
          }'
          # Header encode
          header=$( echo -n "${header_json}" | b64enc )
          
          payload_json='{
              "iat":'"${iat}"',
              "exp":'"${exp}"',
              "iss":'"${app_id}"'
          }'
          # Payload encode
          payload=$( echo -n "${payload_json}" | b64enc )
          
          # Signature
          header_payload="${header}"."${payload}"
          signature=$(
              openssl dgst -sha256 -sign <(echo -n "${pem}") \
              <(echo -n "${header_payload}") | b64enc
          )
          
          # Create JWT
          JWT="${header_payload}"."${signature}" >> $GITHUB_ENV
          printf '%s\n' "JWT: $JWT"
          echo "JWT=$JWT" >> $GITHUB_ENV

      - name: set_IAT
        run: |          
          jq --version
          echo "JWT=$JWT"
          IAT_RESPONSE=$(curl --request POST \
            --url "https://api.github.com/app/installations/$GITHUB_APP_INSTALLATION_ID/access_tokens" \
            --header "Accept: application/vnd.github+json" \
            --header "Authorization: Bearer ${{ env.JWT }}" \
            --header "X-GitHub-Api-Version: 2022-11-28")
          echo "IAT_RESPONSE=$IAT_RESPONSE"
          IAT=$(echo $IAT_RESPONSE | jq '.token')
          printf '%s\n' "IAT: $IAT"
          echo "IAT=$IAT" >> $GITHUB_ENV

      - name: get_response
        run: |
          echo $IAT
          response=$(curl --request GET \
            --url "https://api.github.com/repos/geddesfamily/estate-config/branches" \
            --header "Accept: application/vnd.github+json" \
            --header "Authorization: Bearer ${{ env.IAT }}" \
            --header "X-GitHub-Api-Version: 2022-11-28")
          echo "response=$response"

returns

Run echo $IAT
"***"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   255  100   255    0     0    765      0 --:--:-- --:--:-- --:--:--   765
response=[
  {
    "name": "main",
    "commit": {
      "sha": "[a wonderful sha]",
      "url": "https://api.github.com/repos/geddesfamily/estate-config/commits/[a wonderful sha]"
    },
    "protected": false
  }
]

Ultimately, I am trying to commit to a repo as the GitHub app, so any suggestions would be appreciated.

@jamesgeddes
Copy link
Author

I have been able to commit to the other repo by explicitly generating the JWT and IAT. Would be good if this was possible in the create-github-app-token action.

@gr2m
Copy link
Contributor

gr2m commented Apr 9, 2024

be default, the token created with actions/create-github-app-token has only access to the repository it is running in. If you need to give it access to other repositories, see the usage examples like https://github.com/actions/create-github-app-token?tab=readme-ov-file#create-a-token-for-all-repositories-in-the-current-owners-installation and below

The only permission you need to check out a repository is contents:write. Note that if you add that permission after the app is installed, you will need to accept the new permissions in the installation settings.

@KittyChiu
Copy link

Repost from Community Discussion:

It seems you have 3 processes going on within the call_api job:

  1. 1st process used checkout, ie you are authenticating git CLI
  2. 2nd process used curl, ie you are authenticating HTTP request
  3. 3rd process tried to execute gh api GitHub CLI without authenticating at all

Unsure why you need to do a curl, but for gh api to work, you need to authenticate with gh auth login first.

@iwollmann
Copy link

@jamesgeddes I'm having the same issue at here, I've tried to set the owners and repositories parameters for the action, add all the correct permissions to the app and even with that nothing works, I've used your approach and it worked like a charm, thanks for that.
Definitely there is some issue or miss using by our end at here, I took a fast look in how the action is implemented and nothing seemed wrong by my eyes, I will try to save some time this week to debug this properly, just FYI, my case is very simple, I'm trying to trigger a workflow in another repository, so I created an APP for my ORG to provide the necessary credentials to do that.

@ellharman
Copy link

ellharman commented Oct 4, 2024

having the same issue - not sure this action currently has support for generating an org-level token

scratch that, covered here: #76 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants