octokit / octokit.rb

Ruby toolkit for the GitHub API
http://octokit.github.io/octokit.rb/
MIT License
3.84k stars 1.13k forks source link

[BUG]: OAuth token auth applies a different Authorization header than using curl or postman #1634

Closed auramix closed 11 months ago

auramix commented 1 year ago

What happened?

I've been trying to get Octokit client to auth with an OAuth access token on behalf of my Github App, but have found that although the same call to https://api.github.com/orgs/my_org/repos succeeds using curl and postman it fails with a 401 Bad Credentials with Octokit.

octoclient = Octokit::Client.new(:access_token => token) repos = octoclient.org_repos("my_org")

In order to debug I used Charles proxy to inspect the traffic and noticed that while postman and curl make the call with the header Authorization: <my_access_token>, Octokit is sending the header Authorization: token <my_access_token>. So far I have not seen any other inconsistency in the call so I believe this might be what's causing the client calls to 401.

For further reference, I'm running version 6.1.1 of the client and not the latest because my application relies on dependabot-common whose latest version doesn't support >=7.0

Versions

6.1.1

Relevant log output

No response

Code of Conduct

github-actions[bot] commented 1 year ago

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

nickfloyd commented 1 year ago

Hey @auramix Thanks for reaching out and sorry for the trouble that you're running into.

So the pattern Authorization: token <my_access_token> is a valid implementation when using PATs - have a look at the docs here on that.

Note: In most cases, you can use Authorization: Bearer or Authorization: token to pass a token. However, if you are passing a JSON web token (JWT), you must use Authorization: Bearer.

I've got another report of intermittent 401s when using tokens in the .NET SDK here. It makes me wonder if the two are related. The implementation has been the same for some time now.

Would you happen to be able to tell me what type of token you're using - JWT, PAT, etc?

auramix commented 12 months ago

Thanks, @nickfloyd .

I was using my Github App's client secret for the token. As I mentioned, this works when using the github api via curl and postman although it isn't the recommended way to auth. Octokit ruby docs state that authenticating a Github app should use JWT, but I wasn't able to get that to work for some reason, not with curl, postman, or the ruby client-- I get a 401, and unfortunately haven't been able to debug and find out why.

auramix commented 11 months ago

@nickfloyd -- Wanted to ask for some advice on ways to debug auth with JWT for Github Apps using the Ruby client since that is the suggested way. Here is what I'm doing:

private_key = OpenSSL::PKey::RSA.new(private_pem)

# Generate the JWT
payload = {
  # issued at time, 60 seconds in the past to allow for clock drift
  iat: Time.now.to_i - 60,
  # JWT expiration time (10 minute maximum)
  exp: Time.now.to_i + (10 * 60),
  # GitHub App's identifier
  iss: <app_id_goes_here>
}

jwt = JWT.encode(payload, private_key, "RS256")
token = <token_value_goes_here>
client = Octokit::Client.new(:bearer_token => jwt)
repos = client.org_repos("my_org").select{ |repo| repo[:archived] == false}

I've also checked that I have the correct repository permissions set for my Github App. Not sure what's going on here.

auramix commented 11 months ago

I was able to auth but I had to first find the app installation id via find_app_installations() and then call create_app_installation_access_token(installation_id). Only then can you set the access_token on the client and make calls-- using a JWT to auth as the Github App doesn't work, by itself. This should probably be documented somewhere in the auth section as going by the current example leads to 401s.

nickfloyd commented 11 months ago

Hey @auramix,

Apologies for the delay on this one and thank you for hunting it down. We'll make a task to go through the docs on these auth methods to make sure no one else runs into the roadblocks that you did.