Which scope should I use to ask user for permission to read-only repo (private and public) with Github API? - api

According to GitHub API documentation, I can't get what scope I should use to ask to user to let me download his public/private repo, in read-only manner.
Currently I'm using repo but as you can read in the docs it:
Grants read/write access to code, commit statuses, invitations,
collaborators, adding team memberships, and deployment statuses for
public and private repositories and organizations.
But I don't want to ask to the user the permission to write on his repos!

That was requested in 2015, and two years later, the GitHub Platform Roadmap does mention a "Granular access permissions".
But for now, read-only access is not yet part of the available scopes.
A possible workaround would be to setup a mirror repo, and on each commit on the first original repo, force pushing (overriding) said commit to the second repo (obliterating any write/modification done on that second repo)

Related

GitHub API individual user mirrored permissions to only organization resources

TLDR -
I want users of my employer's organization who install my CLI tool to be able to use it to run commands that use the GitHub rest api that require permissions the user doesn't personally have, while restricting the user from using the CLI tool to perform unintended actions with the elevated permissions needed by the CLI tool. Is there a way to create a CLI tool that 1. uses permissions the users of the CLI tool don't have while at the same time 2. prevents those users from using the CLI tool's elevated permissions to perform unintended actions?
Extended -
I'm building a CLI tool for my employer's organization so that the organization members can automatically create a new branch and simultaneously add branch protection and create a PR. As far as I know, updating branch protection with the GitHub API requires admin access. However, not all of the users who use this CLI tool will personally have those permissions for their user account. But a user in the organization should still be able to use the CLI tool (which uses permissions the user potentially doesn't have).
I thought about using a personal access token so that the users aren't using a single set of centralized credentials (github app creds), but then the CLI tool would have access to at least one of the user's personal repositories and potentially wouldn't have the required permissions required by the CLI tool.
So is there a way to build a tool as a package that can be installed on a users machine that...
has permissions that the user of the tool potentially doesn't have and
prevents the user from doing anything unintended. e.g. the tool (which has admin permissions) can add branch protection rules, but the user shouldn't be able to use the tool's elevated permissions for anything else - e.g. getting the interaction limits for an organization
prevents the user from using the tool in any organization repo they don't have access to.
Ok, that's the gist of it, but I will go into more detail in case that helps.
So currently I'm using a GitHub app and giving it the required permissions (e.g. admin read/write for branch protection rules). I'm using octokit to authenticate to the GitHub API with the GitHub App. To do this, I'm passing in the app id, private key, and the installation id.
package structure
- .env
- authenticate_and_do_stuff.ts
authenticate_and_do_stuff.ts
// authenticate with GitHub app creds
// see https://github.com/octokit/octokit.js#authentication
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: process.env.GITHUB_APP_APP_ID,
privateKey: process.env.GITHUB_APP_PRIVATE_KEY,
installationId: process.env.GITHUB_APP_INSTALLATION_ID,
},
});
// create branch, add branch protection, etc.
octokit.rest.do stuff ...
This isn't ideal because then the user who installs the package needs those environment variables to be authenticated. And once they have those creds, they would be able to use them to do other things they potentially don't have permissions for (e.g. with the admin read/write permission the GitHub app has permissions for). So my thought is to have the user provide the authentication credentials that aren't the Github app credentials. This way, each user is using different credentials they provide. As for the reasons stated above, personal access tokens cannot be used. So the ideal situation is as follows -
A user installs the package - npm i my-github-cli-tool.
- node_modules
|
--- my-github-cli-tool
|
--- authenticate_and_do_stuff.ts
|
- some_custom_app_file.ts
- .env.cli_tool
They generate credentials and put them into a custom env file e.g. .env.cli_tool.
They use the CLI tool to create a new branch in an organization repo they have access to, create the branch protection rules (with the admin read/write access that the user doesn't have, but the credentials in step 2 has).
If the user tries to alter the cli tool or use the credentials in step 2 to use it to access repos they don't have access to or perform other actions with the admin read/write permissions, they shouldn't be able to.
If I stick with using the GitHub app, the source code on the user's machine has to get the credentials somehow. And those credentials need to have elevated permissions that the user might not have. So if these credentials are exposed to the source code on the user's machine, doesn't that mean the user can just grab those credentials and use them for nefarious purposes?

How to use Github Personal Access Token in Jenkins

I can ask this question in many ways, like
How to configure Jenkins credentials with Github Personal Access Token
How to clone Github repo in Jenkins using Github Personal Access Token
So this is the problem
The alternate solution that I am aware of
SSH connection
username password configuration in Jenkins. However,
use of a password with the GitHub API is now deprecated.
But My question is how to setup Github connection with Jenkins using Personal Access Token
[UPDATE]
The new solution proposed by git is
https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/
Which says:
Beginning August 13, 2021, we will no longer accept account passwords
when authenticating Git operations and will require the use of
token-based authentication, such as a personal access token (for
developers) or an OAuth or GitHub App installation token (for
integrators) for all authenticated Git operations on GitHub.com. You
may also continue using SSH keys where you prefer.
What you need to do:
https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/#what-you-need-to-do-today
Basically, change the add URL as
https://<access token>#github.com/<userName>/<repository>.git
Something like this
https://<access token>#github.com/dupinder/NgnixDockerizedDevEnv.git
and set the credentials to none.
Thanks to #Gil Stal
[OLD Technique]
After many discussion on multiple threads from Stackoverflow
I found one thread that is useful.
Refer to this answer:
https://stackoverflow.com/a/61104603/5108695
Basically
Personal access token can be used as a password, as far as Jenkins is concerned at least. I added new credentials to the credential manager.
Go to Jenkins
Go to credentials > System > Global credentials > Add credentials a page will open.
In Kind drop-down select Username and password.
In User put a non-existing username like jenkins-user or user.
Add Personal Access Token in the password field
Now start configuring your project.
source code management tab, select new configured credentials from Drop-down near credential Under Repository URL
So this is how we can configure or setup Authentication between Jenkins and Github using Personal Access Token
References:
Git Clone in Jenkins with Personal Access Token idles forever
Change jenkins pipeline to use github instead of gitlab
The accepted answer wont work anymore because of this: https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations.
You will need to:
Change the URL of the repo to: https://<access token>#github.com/<user-name>/<repo-name>.git (Replace every <...> with the real parameters)
Set the credentials to none.
As of August 2021 the answer posted by Dupinder Singh is accurate. The only thing I would add is that if you are part of a team, the url format appears to be a bit different. This is what worked for me:
https://<access token>#github.com/<team>/<repo>.git
for example
https://ghp_6dh3jdk394jsmbh299jjdg20fh87hd83ksk39#github.com/MyKuleTeam/KuleGuyCode.git
Note that if you use a personal access token you don't need to have any github credentials stored in jenkins.
As for credentials for Jenkins Github Plugin, please be aware only Personal access tokens are now accepted by this plugin.
To generate such a token, follow the Github docs (e.g. here). Don't save it, it can be regenerated in Github and updated in Jenkins if lost or when migrating to a different server.
To add the token do Jenkins credentials store, go to <JENKINS_URL:PORT>/credentials/store/system/domain/_/newCredentials and select Kind "Secret text" (not the default "Username and password"), then paste the token as Secret and choose some ID.
Testing: the credential should appear on the list of Credentials at <JENKINS_URL:PORT>/credentials/ and be selectable from the drop-down list at <JENKINS_URL:PORT>/configure/, where pressing the "Test connection" button should display "Credentials verified for user <GITHUB_USER>".
More info: see the Github plugin docs.
Caveats: Git Plugin has its long-standing issues, so if the newly created "Secret text" does not appear in your pipelines, try if this solution helps (with "the user who triggered the build" considered safer than "SYSTEM"):
client-and-managed-masters/why-credentials-are-not-listed-in-the-git-scm-section
There is (yet another) way to do this as of 2020/04 which is supposed to be superior to personal access tokens. The best part is that you can continue using a username/password-style credential, and the plugin will handle authenticating with GitHub in the background.
Benefits include:
Larger rate limits - The rate limit for a GitHub app scales with your organization size, whereas a user based token has a limit of 5000 regardless of how many repositories you have.
User-independent authentication - Each GitHub app has its own user-independent authentication. No more need for 'bot' users or figuring out who should be the owner of 2FA or OAuth tokens.
Improved security and tighter permissions - GitHub Apps offer much finer-grained permissions compared to a service user and its personal access tokens. This lets the Jenkins GitHub app require a much smaller set of privileges to run properly.
Access to GitHub Checks API - GitHub Apps can access the the GitHub Checks API to create check runs and check suites from Jenkins jobs and provide detailed feedback on commits as well as code annotation
Links:
https://www.jenkins.io/blog/2020/04/16/github-app-authentication/
https://github.com/jenkinsci/github-branch-source-plugin/blob/master/docs/github-app.adoc

Set branch permissions for a group via Azure Repos API

I need to restrict permissions for certain branches across 50 repos for specific user groups in azure repos. This is to say, a particular group of users cannot force push to the master branch but can other branches.
This is easy enough to do in the interface, but requires going to 50+ repos and manually performing this task. I've been reading through the Azure repos API documentation and I'm struggling to see how I go about setting this?
As explained in the blog post https://jessehouwing.net/azure-devops-git-setting-default-repository-permissions/:
tfssecurity /a+ "Git Repositories" repoV2/<Team Project GUID>/<repository guid>/refs^heads^<branch name>/ "ForcePush" <memberIdentity> DENY /collection:https://dev.azure.com/{organization}
The repository guids can be found out via REST API, where GitRepository.id contains the guid:
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/list?view=azure-devops-rest-5.1#examples
See https://learn.microsoft.com/en-us/azure/devops/server/command-line/tfssecurity-cmd?view=azure-devops for more information about how to specifiy member identity.
You can use below rest api to set branch permission fors for group.
POST https://dev.azure.com/{orgname}/{projectid}/_api/_security/ManagePermissions?__v=5
Here is a sample of request body.
{"updatePackage":
"{\"IsRemovingIdentity\":false,
\"TeamFoundationId\":\"{teamfoundationId}}\",
\"DescriptorIdentityType\":\"Microsoft.TeamFoundation.Identity\",
\"DescriptorIdentifier\":\"{DescriptorIdentifier}}\",
\"PermissionSetId\":\"2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87\",
\"PermissionSetToken\":\"repoV2/{projectId}}/{repoId}}/refs^heads^{branchname}}/\",
\"RefreshIdentities\":false,
\"Updates\":
[{\"PermissionId\":1,\"PermissionBit\":32768,\"NamespaceId\":\"2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87\",
\"Token\":\"repoV2/{projectId}/{repoId}/refs/heads/{branchId}/\"}],
\"TokenDisplayName\":null}"}
Note
\"PermissionId\":1, means set the permission to Allow,
\"PermissionId\":2, means set the permission to Deny,
\"PermissionId\":1, means set the permission to Not Set.
\"PermissionBit\":32768 is the Bypass policies when completing pull requests permission.
\"PermissionBit\":128 is the Bypass policies when pushing permission.
\"PermissionBit\":4 is the Contribute policies when pushing permission.
\"PermissionBit\":2048 is the Edit polices permission.
\"PermissionBit\":8 is the Fource push permission.
\"PermissionBit\":8192 is the Manage permissions.
\"PermissionBit\":4096 is the remove other's lock permission.
Addition
There are too many parameters in the request body, you can get there parameters by offical documentations. Or I recommand you to get these parameters by using Network Tool to manual cathch them.

Access to api from gitlab webhooks

I need to develop a bunch of my own web hooks (or services maybe) for auto deploy, report into project management systems, etc.
But data posted to web hook don't have much information to fill my needs.
For example, I've received simple push event, how can I know is it force push or not? Okay, I have 2 treeishes, let's look at repository and check this push — oops, need user token to do it. Sad.
What is the right method to access gitlab api from web hooks? Probably I've missed something important? I'm really confused.
Upd1:
Let's try to find a solution. Possibilities
Imagine we can have a user who can read all projects in gitlab. But
that user should be connected to each project to have an access. Ok
;-(
What about to read repo by pusher? We can't because we need to use his private token to do this.
Maybe some internal functionality to read all repos or something? Sure not.
So. Maybe database? Nope. Because we need to clone repo at first and can't save data in DB anyway with refreshing caches.
I think we need a security token and maybe many checkboxes with access permissions for each joined web hook or an app (service).
Please feel free to share your ideas.
I've remembered partial solution. So scenario will be like that:
Create web service with your web hook.
Create a ssh key on the same host for some special (usually owner of web hook service) user to have an access to repos.
Add ssh key created at previous step as deploy key.
Finally: Register your webhook and add your deploy key for that hook to project — repeat it for each project what need this hook.
You have event listener (your web hook service), and you have access to that repository (ssh/git).
But still that solution doesn't have access to API itself.
Probably, there is also an another solution.
Create custom admin user with a big random password and some synthetic name like HookBot or something, remember private_token of that user;
Register your web hook;
Use api access to add your deploy key with HookBot (untested);
Use sudo api to get sources or something else. Just mimicry to pusher's account (sudo -u {author_id}) and go on, read repo, work with it, etc.
Maybe some another solutions? More legit?

Can I see the hooks in a repository I don't own?

I want to know if a Github repository has defined a certain service hook (Webhook URL) but I am not the owner of the repos (though I am a collaborator).
Is there a way to do that via the API (or any other programmatic way)?
If it helps, the repository in question may sometimes belong to an individual and sometimes to an organization.
I confirm the OP's conclusion:
It does not work. If I authenticate as the owner of the repo, it does work.
That means the List query (GET /repos/:owner/:repo/hooks) won't work if you are not owner (or admin for an organization) of a repo.
The Hooks GitHub API does mention:
The Repository Hooks API allows repository admins to manage the post-receive hooks for a repository.
Update February 2014: "New scopes for managing repository hooks"
You now can see hooks for a repo you don't own, provided the owner set the right scope:
Many third party services need to set up hooks in order to act upon events in your repositories.
We’ve introduced three new scopes that provide more granular access to your repository hooks without allowing access to your repository contents:
read:repo_hook grants read access to hooks in public or private repositories.
write:repo_hook grants read and write access to hooks in public or private repositories.
admin:repo_hook grants read, write, and delete access to hooks in public or private repositories.