Setting Up the Foundation: The Git Setup
General Git Security Considerations
There are some security considerations that you should take into account when using GitLab, GitHub, or any other Git repository hosting service, cloud-based or self-hosted. Some are intuitive, like maintaining the confidentiality of your code and creating private repositories; others may not be so obvious.
Access Control and Unauthorized Access
Effective access control is important to make sure that only authorized personnel have the capability to modify, merge, or delete code. Follow the principle of least privilege: grant repository access to users based strictly on their roles and responsibilities. Regularly review permissions and revoke access immediately when it is no longer necessary.
Another good practice is using SAML or OpenID Connect (OIDC) for authentication. This allows you to manage user access through your identity provider, which can simplify the process of managing user permissions. This is not suitable for everyone, but when you have a large team, it can be a good option.
If you are self-hosting your Git repository, consider using a virtual private network (VPN) to restrict access to the Git server. Never deploy your Git server to the public internet without a VPN. IP whitelisting is another option, but it can be cumbersome to manage, especially if users have dynamic IP addresses.
When using cloud-based Git providers, it's essential to carefully evaluate their security posture. Look at their certifications, audit reports, and historical security incidents. Ultimately, your trust should depend on concrete measures, transparent security practices, and a demonstrated commitment to keeping your data secure.
In all cases, adding two-factor authentication (2FA) to your account reduces the risk of unauthorized access.
Branch Protection
Branch protection helps prevent unauthorized or accidental changes. Define rules to restrict direct pushes to sensitive branches (such as master or main) and mandate pull requests with peer reviews. Consider implementing required status checks to verify that code passes defined tests before merging.
Tags and Releases
Using tags to mark release points can be a valuable practice. Tags are immutable by design, and this immutability ensures consistency in your codebase history, which enhances security by preventing unauthorized or accidental modifications. Implement strict policies on who can create or delete tags, ensuring these permissions are tightly controlled and audited.
Releases, often tied to tags, provide clear, stable references for deployment or distribution. Make sure your release process is structured and automated where possible, and that released versions are properly signed or authenticated to guarantee their integrity. Adopting a consistent release naming convention helps simplify tracking, management, and auditing. Additionally, maintain a changelog for each release to clearly document changes, security updates, and bug fixes, enabling easier assessment and quick response in case vulnerabilities are identified.
Unsigned Commits and Commit Signing
When you're granted write permissions to a Git repository, the repository owners trust that your contributions won't be harmful. By default, Git commits aren't cryptographically signed, meaning anyone with write permissions can easily impersonate other contributors. For instance, impersonating another developer - let's name them Sofia - is straightforward:
git config --global user.email "sofia@restqr.com"
git config --global user.name "Sofia"
git commit -m "This is a commit from Sofia"
Any commit made would appear as if Sofia authored it. This default trust model might be sufficient in many scenarios, but it introduces a serious security risk. Malicious actors who gain access to your credentials could inject harmful code while attributing those changes to someone else. To mitigate this risk, commits should be cryptographically signed using a GPG key. This guarantees the commit's integrity and authenticity.
As an example, let's create a GPG key pair for signing commits. You can start by verifying that you have a GPG key pair.
gpg --list-secret-keys
In case you don't have a GPG key pair, we will generate one. Start by creating a key settings file after exporting the following variables:
export REAL_NAME=""
export EMAIL=""
Generate the key pair using the following command:
gpg --full-gen-key --batch <( \
echo "Key-Type: 1"; \
echo "Key-Length: 4096"; \
echo "Subkey-Type: 1"; \
echo "Subkey-Length: 4096"; \
echo "Expire-Date: 0"; \
echo "Name-Real: $REAL_NAME"; \
echo "Name-Email: $EMAIL"; \
echo "%no-protection"; )
The above command will generate a key pair with the following characteristics:
- The key length is 4096 bits.
- The key will not expire. This is not the recommended option, but you need to adapt the command and set the expiration date in a real environment.
- The key will be associated with your real name and email address.
- The
%no-protectionoption is used to generate a key without a passphrase. This is also not recommended for production environments but is fine for testing purposes.
ℹ️ The
--batch
DevSecOps in Practice
A Hands-On Guide to Operationalizing DevSecOps at ScaleEnroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!
