The Flaw in 'Verified' Commits: Why GitHub/GitLab Fall Short on Supply Chain Security
Software supply chain attacks have become a significant concern, highlighting the critical need for robust security measures at every stage of development. A fundamental aspect of securing code integrity is commit signing, which aims to verify the authorship and authenticity of changes. However, a critical gap exists in how major Git platforms like GitHub and GitLab implement and enforce commit signing, leaving organizations vulnerable to sophisticated attacks that can bypass existing "Verified" badges.
This issue stems from the platforms' inability to enforce specific signing keys, allowing attackers to inject malicious code into repositories under the guise of legitimate, verified commits. This post explores the limitations of current commit signing protections, the features missing from popular platforms, and the significant burden placed on development teams to compensate for these security shortcomings.
The Illusion of "Verified" Commits
GitHub and GitLab offer a "Require signed commits" feature, which, on the surface, appears to enhance security by ensuring that all commits pushed to a repository are signed by a key associated with the committer's account. However, this protection is fundamentally flawed. If an attacker compromises a developer's laptop or their GitHub/GitLab account, they can simply add a new signing key to that account. With this new, unauthorized key, the attacker can then push malicious commits, which will still receive the coveted "Verified" badge.
This scenario creates a significant blind spot: the "Verified" badge, intended as a mark of trust, becomes a potential vector for supply chain attacks. Organizations relying solely on this feature are left with a false sense of security, as malicious code can seamlessly integrate into their codebase, appearing legitimate.
Critical Gaps in Platform Features
The core problem lies in the lack of granular control and enforcement mechanisms within GitHub and GitLab. Specifically, these platforms currently do not offer:
- Organization-level allowlists for approved signing keys: There is no built-in way for an organization to specify and enforce a list of only approved signing keys (e.g., hardware-backed YubiKeys issued by the organization) that are permitted to sign commits.
- Rejection of pushes based on the signing key itself: Platforms cannot be configured to automatically reject a push if the commit is signed by a key that is not on an approved allowlist, even if it's associated with a legitimate user account.
- Built-in, granular auditing of key access: Organizations are left to stream and parse audit logs themselves to understand who has accessed what, making it difficult to detect unauthorized key additions or usage efficiently.
These missing features mean that even with "Require signed commits" enabled, the integrity of the Git history remains susceptible to compromise through a single compromised developer account.
Limitations of Current Workarounds
Faced with these platform limitations, many organizations resort to workarounds, such as:
- Re-verifying signatures in Continuous Integration (CI) pipelines: This involves adding a step in CI to re-check commit signatures against an internal allowlist.
- Blocking deployments based on unapproved keys: Deployments are halted if CI detects commits signed by unauthorized keys.
- Self-hosting Git with pre-receive hooks: Custom hooks are implemented on self-hosted Git instances to enforce signing key policies before commits land in the repository.
While these workarounds provide some level of detection or prevention, they all share a critical flaw: the malicious commit still lands in the repository. CI catches it after the fact, meaning the compromised code has already been integrated into the codebase, even if it's prevented from being deployed. This "after the fact" detection is insufficient for true supply chain security, where the goal is to prevent malicious code from ever entering the trusted repository history.
The Burden on Organizations
The absence of these fundamental security features forces organizations, particularly smaller development shops, to undertake significant, resource-intensive efforts to secure their software supply chain. This includes:
- Issuing hardware security keys (e.g., YubiKeys) to every developer: A substantial logistical and financial undertaking.
- Building custom verification and audit pipelines: Developing bespoke systems to enforce key policies and monitor activity.
- Streaming audit logs to a Security Information and Event Management (SIEM) system: Requiring additional infrastructure and expertise for log analysis and alerting.
- Upgrading to enterprise tiers for basic visibility: Often incurring higher costs for features that should be standard security offerings.
This level of effort for what is perceived as "table stakes" security is a source of significant frustration, diverting resources from core development and innovation.
The Call for Better Platform Support
The current situation highlights a critical disconnect between the security needs of modern development and the offerings of leading Git platforms. While platforms like GitHub invest heavily in features like AI-powered coding assistants, fundamental security mechanisms that prevent "Verified" supply chain attacks remain unaddressed. Organizations need platforms to provide robust, built-in capabilities for:
- Enforcing specific, organization-approved signing keys.
- Rejecting pushes that do not meet these key requirements at the gate.
- Offering transparent and actionable audit trails for key management and usage.
Without these capabilities, the threat of a single compromised developer account leading to a "Verified" supply chain attack remains a tangible and pressing concern for development teams worldwide. Securing the integrity of the Git log and history should be a top priority for platform providers.