How to get the permissions each collaborator has on a GitHub repository?

How to get the permissions each collaborator has on a GitHub repository?

Ever encountered a scenario where you needed to check some extra permissions only to find out that you do not have maintainer or admin access? Also, you are unable to find out who the owner of the repo is from the repository UI.

GitHub API is to the rescue here. As long as one has “push” permissions to a repository, one can make use of the GitHub API to get the list of collaborators on the repo and their permissions on the repository. While there are REST API and GraphQL API available, in this post, we will make use of the REST APIs and the Postman tool to get the list of collaborators for each repository in an organization and the permissions they have on the repository.

In Postman

create two variables: one for your organization name and another for your github access token. In my code, I named the variables ORG_NAME and BEARER_TOKEN. Logic:

  1. Get the list of repositories under an org
  2. For each of these repos, get the list of collaborators
  3. For each of the collaborator, get their permissions
  4. Log this in Postman console in the format — Repository, collaborator, permission.

I chose “JavaScript” as the language in the “Tests” tab, wrote the below script and clicked “Send” to run the request.

// Set variables for the GitHub API URL and organization nam
const orgName = pm.collectionVariables.get("ORG_NAME");
const apiUrl = "https://api.github.com/orgs/" + orgName + "/repos";
const bearerToken = pm.collectionVariables.get("BEARER_TOKEN");

// Set authentication headers with your GitHub access token
const headers = {
  "Accept": "application/vnd.github+json",
  "X-GitHub-Api-Version": "2022-11-28",
  "User-Agent": "PostmanRuntime/7.30.1"
};

// Create an empty array to hold the data
data = [];

// Send a GET request to the GitHub API to retrieve the list of repositories for the organization
pm.sendRequest({
  url: apiUrl,
  method: 'GET',
  headers: headers
}, function (err, res) {
  if (err) {
    console.log(err);
    return;
  }
  //console.log('List of Repos in Org Successful')

  // Parse the response body as JSON
  const buff = Buffer.from(res.stream);
  const repositories = JSON.parse(buff);
  
  // Loop through each repository and retrieve the list of collaborators and their permissions
  repositories.forEach(function(repo) {
    const repoName = repo.name;
    const repoCollaboratorsUrl = `https://api.github.com/repos/${orgName}/${repoName}/collaborators`;

    // Send a GET request to the GitHub API to retrieve the list of collaborators for the repository
    pm.sendRequest({
      url: repoCollaboratorsUrl,
      method: 'GET',
      auth: {
   type: "bearer",
   bearer: [
    {
     key: "token",
                    value: bearerToken,
     type: "string"
    }
   ]
  },
      header: headers
    }, function (err, res) {
      if (err) {
        console.log(err);
        return;
      }
      //console.log('List of Collaborators successful');
      const buff1 = Buffer.from(res.stream);
      const collaborators = JSON.parse(buff1);
    
      // Loop through each collaborator and retrieve their permissions
      collaborators.forEach(function(collaborator) {
        const collaboratorName = collaborator.login;
        const collaboratorPermissionsUrl = `https://api.github.com/repos/${orgName}/${repoName}/collaborators/${collaboratorName}/permission`;
        //console.log('Sending request for permissions');
        pm.sendRequest({
            url: collaboratorPermissionsUrl,
            method: 'GET',
            auth: {
                type: "bearer",
                bearer: [
                    {
                        key: "token",
                        value: bearerToken,
                        type: "string"
                    }
                ]
            },
            headers: headers
        }, function (err, res) {
            if (err) {
                console.log(err);
                return;
            }
        
        const resbody = Buffer.from(res.stream);
        const permissions = JSON.parse(resbody);

        data.push({
            Repository: repoName,
            Collaborator: collaboratorName,
            Permissions: permissions.permission
        });
        //console.log(repoName, collaboratorName, permissions.permission )
        if (data.length === repositories.length * collaborators.length) {
            // Convert the data array to a CSV string
            const csvString = convertToCsv(data);
            console.log(csvString);
        }
        });
      });
    });
  });
});

// Function to convert an array of objects to a CSV string
function convertToCsv(data) {
    const header = Object.keys(data[0]).join(",");
    const rows = data.map(function(d) {
        return Object.values(d).join(",");
    });
    return header + "\n" + rows.join("\n");
}e        

To view just the output, before running the request, on the Postman tool, turn on the Hide Network button so that you do not see the whole list of calls made, but only the console logs you printed.

Challenges faced: It wasn’t straightforward to pass the authentication method in the headers section of the request. It had to be sent separately as auth field as mentioned in the script.

You are a change agent in so many ways.. keep it coming. and continue to make our world a better place for those who come after us

Like
Reply

Are you planning to make this public? Might be helpful for others who need to solve the same issue :)

Like
Reply

To view or add a comment, sign in

More articles by Rakesh Devalapally

  • Take Control of your Time

    Recently, I came across a post on LinkedIn by Austin Belcak, founder of Cultivated Culture, talking about how he…

Others also viewed

Explore content categories