Is there a Github API OAuth scope that allows you to check a user has access to a private repo *without* also granting access to repo code? - github-api

I'm building an OAuth app to work with Github. I need to know, via token scopes, whether an authenticated user has access to a repo (public or private) so that I can restrict access accordingly in my app.
I explicitly do not want access to repo code from my app because a) I want users and companies to have confidence to use it with private repos and b) the app doesn't need to know, so I'd like to keep it least-privilege.
I'm struggling to find an OAuth scope that will allow the app to query whether a user has access to a specific repo without also needing to ask my users to grant the app permission to access their code.
The nearest I've found is repo:status. However that requires me to guess a branch name, which is usually main or master, but there's no guarantee.
Is there a better way?

Related

OAuth2 - Can a trusted Client access User resources with Client Credentials flow

Looking at this explanation of the client credentials grant type from the OAuth website:
The Client Credentials grant type is used by clients to obtain an access token outside of the context of a user.
This is typically used by clients to access resources about themselves rather than to access a user's resources.
In case the client is a trusted app (internally developed), is it ok for it to access users' resources?
Technically, the app isn't the "resource owner" of these resources, but because it's a "super" app, developed internally, it should be able to access them, for the sake of implementing the organization's business requirements.
For example - think of your user in Google. The Google maps app creates resources owned by you (e.g places you "saved" on the map). Then, some Google daemon app with "super" permissions, can access those resources you created, in order to process them and show you relevant ads.
Does that make sense?
Thanks!
Simon.
Yes, that’s a fairly typically scenario in my opinion.
There are a few additional best practices to consider for your trusted client like storing secrets in a key vault, rotating the secret on a schedule, limiting and logging administrator access, etc.

How to allow a public app to connect to the GitHub API v4 without an access token?

I have decided to try to manage releases of one of my apps on GitHub as with GitHub Actions, I can build on Mac, Linux and Windows and automatically push the artifacts to the GitHub Releases page, where anyone can go and download the app from.
However, I want my app to self-update, so the app itself also needs to be able to query what's the latest version in the repo releases, and then download the relevant asset for the user's OS... which I thought would be a non-issue... however, there's no way to access the GitHub API v4 without either an OAuth app or a personal access token.
I don't want an OAuth app because the users of my app are absolutely not expected to be GitHub customers. So I tried to use a personal access token whose only scope was access to public release assets (which, again, is a public resource anyone can go and manually download).
As this token can't do anything you or anyone else can't do manually, even without a GitHub account, I thought it would be fine to put the token in the source code of my application, but GitHub revokes the token when it detects it on a commit.
Is there a good way to work around this? Should I put the token in a GitHub secret and then try to replace a placeholder with it during compilation?? I wanted to avoid that as that makes it hard for me to test the app locally, and also, it doesn't solve anything as anyone can easily decompile the app and find the token there (supposing GitHub would not detect the secret is present in the "processed" sources during compilation).
Any suggestions would be appreciated.
however, there's no way to access the GitHub API v4 without either an OAuth app or a personal access token.
The GitHub API v3 does support unauthenticated calls, but it's limited to 60 requests/hr per IP address: https://developer.github.com/v3/#rate-limiting
For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the user making requests.
The Latest Release API docs will show you what information is returned, but I suspect you'll need to make a secondary call to List Assets for a release to know the files the client needs to download.
If that's not satisfactory (e.g. you know you'll have many clients try to update using the same IP address), and you'd like to ensure they aren't being rate-limited, read on for a different approach.
Is there a good way to work around this?
How I would tackle this is by deploying a small web service (e.g. Heroku dyno) that your app can will call without needing authentication, which then performs the actual lookup for the latest version (using a PAT that gets embedded as an environment variable) and returns a simple JSON response that the client will understand.
Benefits:
no token embedded in client
development mode can even call same service
add logic to service that the client would perform to simplify your app
e.g. call /latest/beta or /latest/stable to indicate it's looking for a specific channel
perform both API calls and return the assets that the client needs
can update token in service whenever necessary (e.g. to refresh token) without changing client
can cache response to reduce risk of being rate-limited
Downsides:
more moving parts to manage in your overall architecture
need to worry about uptime of the service if there are lots of clients connecting
this can be offset by making the client resilient to failure cases

GitHub Repository Security

While using a paid account on github, we currently have a private repository which is forked only by contributors that work within the same network.
What is the best way to ensure that the code remains private? In other words, how can the organization restrict reading/cloning/downloading of the repository (or its forks) by a computer off network?
Thank you in advance for your help!
If you're using a version hosted on github.com, then there's no technical way to restrict access to that private repository based on the network from which the connection comes. If you need that functionality, you'll need to self-host with GitHub Enterprise Server, which is the on-premises version. You can then limit access to that server to only people on your network.
You could also enable SAML single sign-on and only allow access to GitHub if the SAML authentication comes from your network. However, do be aware that once a user has logged in, the SAML session is cached, so a user could log in while on your network and then take their laptop somewhere else and still access things. That also wouldn't prevent actually cloning a repository with a token or a key, however.
If your goal is solely to ensure that the code remains private and you generally trust your employees, you could try techniques like requiring 2FA for all employees, which makes it harder for people to compromise accounts.

Signing into my Gitlab CE installation with my app's login

I have a nodejs webapp with many users with a custom login process. I would like gitlab to accept that authentication and not force users to create a new app. What is the best way to accomplish this?
I would go for OAuth 2.0 Single Sign On (SSO). Below you can find the architecture diagram taken from here. As you can see the client is redirected to log in in the OAuth2 provider to get a valid token for authentication. The OAuth2 server must be configured for the application requesting access including the secret, the client id and the callback URL.
You can configure GitLab CE to sign in with almost any OAuth2 provider. Only be careful with the limitations:
It can only be used for Single Sign on, and will not provide any other access granted by any OAuth provider (importing projects or users, etc)
It only supports the Authorization Grant flow (most common for client-server applications, like GitLab)
It is not able to fetch user information from more than one URL
It has not been tested with user information formats other than JSON
You also need to configure your node js web application as an OAuth2 server. There are npm availables with the source code here.
Recommendation
I would install some open source Identity Management to separate the user management from your webapp, provides better integration with other third parties and forget about encryption and other stuff you need to take care in your webapp. There are multiple options such as KeyCloak for instance.
You have to define a dedicated user , and use the private_token of this user to login for ALL users that will use your application.
The restricition would imply all users will have the same rights ....
The other solution is to use the Private Token of the user at login. In this case , only the rights of these particular users will be used.

GitHub API - private or forked repositories not listing nor comparing

In my GitHub account I have a few public repositories that I created plus several private repositories forked from repositories in my organization.
My problems are
a) GET /user/repos is only listing the public personally created repositories regardless of the 'type' parameter
b) COMPARE calls on the forked repositories is returning 404
I'm logging in using Oauth 2.
Is there something that I am missing?
Thanks
If I understand correctly, the situation you're describing is as follows:
You belong to an organization. (Let's call it "#your-organization".)
#your-organization has at least one private repository. (Let's call it "your-organization/private-repo".)
You have a fork of that repository in your personal account (e.g., gulliver-smith/private-repo).
You're using an OAuth token to authenticate with the GitHub API.
When you access GET /user/repos, the response does not include your fork (e.g., gulliver-smith/private-repo).
When you access GET /repos/gulliver-smith/private-repo/compare/:base...:head, you get a 404.
If that's right, there are a few things you'll want to verify:
Ensure that your OAuth token has repo scope. If your token does not have repo scope, you'll observe the behavior described above. To verify the scopes associated with your token, look at the X-OAuth-Scopes response header.
$ curl -I https://api.github.com/ -H "Authorization: token REDACTED" | grep ^X-OAuth-Scopes
X-OAuth-Scopes: admin:org, admin:public_key, delete_repo, gist, notifications, repo, user
If you're using a token that belongs to an OAuth application, the organization may have third-party application restrictions enabled. If so, you can ask the organization's administrators to approve the OAuth application so that the app can access the organization's repositories on your behalf.

Resources