Best practices for managing developer teams in GitHub Orgs
Keshav MalikKeshav is a full-time Security Engineer who loves to build and break stuff.He is constantly looking for new and exciting technologies and enjoys working with diverse technologies in his spare time. He loves music and plays badminton whenever the opportunity presents itself. |
There's a lot to love about GitHub, and the organizational structure it can give you is definitely one of them. When you share your code with other developers, make it public, or collaborate with a large team (or even a small one), the circle expands faster than you would imagine. Like it or not, a managed hierarchy of access and well-thought rules become imperative for the sustainability and security of your projects.
What could go wrong if you do not manage access? It's a legitimate question considering you trust the people you collaborate with. Well, all it takes is an honest intern who rewrites the history in your master branch to wreak havoc. Let us say it is safe to have a managed organizational structure, and that's what we'll talk about.
In this blog post, I will guide you through the best practices for managing developer teams in GitHub Orgs and provide recommendations to help you secure your GitHub organization.
What is an organization in GitHub?
A GitHub organization is a shared platform where you can put one or more repositories and share controlled access with members and collaborators who can perform specific tasks. These organizations can be companies, non-profit organizations, some coalitions, or independent developers working together on a project for fun. An unlimited number of people can collaborate in an organization across multiple projects.
Usually, an organization has five levels of role-based permissions:
- Owner: has complete control of the organization along with full administrative access. They can determine the team's access level to the project code.
- Billing manager: can manage payment settings for the organization. This includes setting up payment methods, managing subscriptions, and viewing invoices.
- Member: is granted role-based access to control what they can see and do within the organization. Depending on their role, they may access the repositories or projects.
- Moderator: have all the permissions granted to members by default. On top of that, they can block or unblock outside collaborators, set interaction limits, and hide comments on public repositories that belong to the organization.
- Outside collaborator: for a contractual member who's granted access to one or more repositories to perform specific tasks but doesn't have the full array of permissions granted to the members.
What is a team in GitHub?
Teams are groups of members that reflect the organization's structure with cascading access permissions. The teams are maintained by organization owners and team maintainers who can manage the level of access granted to a team and add or remove members. Teams have pages where you can see the members, child teams, the team profile picture, etc.
Managing a team's access to repositories in GitHub
The owners can give a team access to a repository, remove the access, or modify the permission level to a specific repository based on the need.
Here is an example with a nested team “Engineering” with two nested teams “Frontend” and Backend”:
In this example, granting Everyone
write access to a repository means Frontend
and Backend
also get that access (quite logical!).
If a team has direct access to a repository, the access can be simply removed. However, if a team has inherited access from a parent team, then the maintainers have to remove the access for the parent team to remove access for the child team.
8 Best Practices for Managing Teams in GitHub
Now that we have somewhat established organizations and teams in GitHub let's jump right into the practices that make it easier to manage teams safely and sustainably.
Configure the Organization
Creating an organization on GitHub is extremely simple; it takes just a few clicks. But you should take the time to configure the organization based on the group's specific needs. This could mean restricting access to certain repositories, setting up review cycles, or modifying other settings to strengthen the organization's security. This will help to keep things organized and make it easier for team members to find the information they need.
One Branch for Each Feature or Bug
One of the key advantages of a GitHub organization is allowing an unlimited number of developers to work on different projects simultaneously. Having a branch for each bug or feature helps you make the most out of this advantage, allowing multiple people to work on various features without worrying about overwriting the code written by someone else. This also keeps things well organized.
Create Nested Teams
As an organization owner, you can create child teams or nested teams that inherit the permissions from their parent teams (see above). It simplifies access management, as adding or removing permissions for the parent teams automatically means doing the same for the child teams.
When working with a large number of groups, having nested teams simplify communication.
Nested teams can also be given different permissions than their parent teams so that you can tailor the team's access to your organization's needs.
Assign Code Owners
The success of a project relies heavily on code reviews. Code owners are a special type of GitHub user responsible for reviewing and approving code changes in a repository. Code owners can be assigned to specific files or directories and will be notified whenever a change is made to those files. This makes pull requests safer, removes the confusion pertaining to ownership and reviews, and ensures the smooth functioning of a team.
Rebasing the Feature Branches
As we have discussed earlier, creating a branch for each feature or bug is a good practice. But if a team is working on a bunch of features simultaneously, it creates a complicated graph of branches that becomes very difficult to track. To avoid that, the ideal practice is to rebase the feature branches with the master branch.
Rebasing can help resolve merge conflicts more efficiently and make it easier to track changes and keep your codebase up to date.
Squash Commits Before Merging
Commits are like milestones in the journey of a Git project. Squashing commits is a way of rewriting the commit history before you share it with your team. It keeps the commit history clean and makes it easier to associate a bug with a specific commit when it comes to testing or debugging.
Setup Pre-Merge & Post-Merge Jobs with GitHub Repositories
If you're using GitHub for your project development, you can easily set up pre-merge and post-merge jobs to run automatically on your repositories.
This also helps to ensure that the code integrates properly and that any potential conflicts are resolved before they cause problems. Pre-merge jobs can be used to run tests and verify that the code compiles correctly. Post-merge jobs can be used to deploy the code to a staging environment for further testing.
Use Secret Scanning Tools
Secret scanning tools like GitGuardian or gitleaks can help you avoid accidentally leaking secrets like API keys and passwords through your GitHub repositories. These tools work by scanning your repositories and pull requests for potentially sensitive information and then alerting you so you can take action to remove or protect the information.
GitGuardian is free for individuals and teams smaller than 25, and you can install it through the GitHub Marketplace here.
Using a secret scanning tool is a good first step in preventing accidental leaks, but it's also important to be aware of the potential risks and to review your code regularly to ensure that no sensitive information is accidentally left exposed.
Track Progress using GitHub Projects
It is essential to keep track of team progress. This can be done by creating a GitHub project board and adding issues and milestones. This feature allows you to create Kanban-style boards for your repositories to see what's being worked on and what is still pending. You can also add notes and tags to your cards to keep all the relevant information in one place. Tracking progress using GitHub Projects is a great way to keep your project organized and on track.
Best practices to secure your GitHub Organization at a glance
To keep your GitHub Organization secure, it is essential to follow best practices. Some of these best practices include:
Backup & restore for your repos
As a best practice, it is always recommended that you have a backup and recovery plan for critical repositories and ever-changing metadata. This will help ensure that you can recover your data in the event of a disaster and that your metadata is always up-to-date.
Supervise access controls
One of the most crucial security steps is setting access controls on an as-needed basis. Make sure that no one has more permissions than they need to have. This will help to prevent unauthorized access to sensitive information. You should also have a process in place for revoking access when someone no longer needs it.
MFA for all
Enforce multi-factor authentication for all members of the GitHub organization, moderators & billing managers. MFA (multi-factor authentication) adds an extra layer of security to your account by requiring you to enter a code from your mobile phone or another device in addition to your password. This makes it much harder for threat actors to gain access to your account, even if they have your password.
Security policies
Organizations on GitHub have several different security settings that can be adjusted to fit the organization's needs. It is essential to review these settings regularly and audit your member's activity to ensure that your organization's data is safe.
To sum it up
GitHub organizations are fantastic if you can maintain a few habits and imbibe some practices into the way your teams function. The responsibility is shared between the owners and the team members. As the owner, you can create nested teams, set security policies, and assign code owners to make things easier. Then if the team members can pull their share of the weight by being responsible for squashing the commits, rebasing the branches, and testing code, everything falls into place.