(last updated 2024-02-18, Christopher Allen [email protected] Github/Twitter/Bluesky: @ChristopherA)
The Open Integrity project, an initiative of Blockchain Commons, demonstrates how Git repositories can serve as a cryptographic root of trust, ensuring integrity, provenance, and accountability in software development. By combining Git's native signing capabilities with structured cryptographic verification and auditing processes, this proof-of-concept creates tamper-resistant and independently verifiable software and data stores.
This approach enables:
- Immutable proof-of-origin for software artifacts
- Verifiable commit authenticity from both authors and committers
- Tamper detection throughout repository history
- Immutable signature chains ensuring that past commits remain cryptographically verifiable
- Platform-independent verification that works across any Git hosting service
Through this project, Blockchain Commons advances its mission of developing open, interoperable, and secure digital infrastructure. This proof-of-concept specifically focuses on establishing cryptographic roots of trust that can operate independently of any single platform or authority.
Git is a powerful distributed version control system, but its default configuration lacks cryptographic enforcement of commit authenticity, history integrity, and repository provenance. While Git efficiently tracks changes, it does not provide built-in mechanisms to prevent forged authorship, unauthorized modifications, or tampering with repository history.
Without cryptographic trust, repositories face several risks:
- Commit authorship can be forged. Any user can configure Git with a fake name and email, making it appear as though someone else authored a commit.
- Unsigned commits provide no cryptographic proof of origin. Git does not enforce commit signing, meaning anyone can claim authorship without cryptographic verification.
- Unsigned commits can be merged into signed repositories. Even if a Git hosting service enforces commit signing, unsigned commits can still be merged from branches without triggering a verification warning or failure.
- Commit history can be rewritten. Unless explicitly protected, Git allows history to be altered or deleted, making it possible for attackers—or even well-intentioned users—to modify past commits without detection.
- Feature branches may be deleted after merging. Once a branch is merged and deleted, it may be impossible to verify whether the original commits were properly signed before merging.
These weaknesses undermine confidence in the long-term trustworthiness and verifiability of a repository, impacting both open-source projects and enterprise software development.
These problems can be solved using Git's existing infrastructure. By combining Git's native support for SSH key signing (which provides ~128-bit security through modern cryptographic signatures), its hooks system for enforcing policies, and its ability to track metadata through commit messages, notes and configuration files, we can create a robust trust framework.
The Open Integrity project implements this framework through a structured set of scripts and processes that integrate seamlessly with standard Git workflows. It requires no modifications to Git itself and relies solely on Git's native SSH-based cryptographic tools. This practical approach ensures that repositories maintain cryptographic integrity throughout their entire history while remaining fully compatible with existing Git hosting platforms, and without the need for proprietary tools or external dependencies.
A Git repository's first commit is a critical trust anchor, yet Git does not require it to be signed or immutable. This creates vulnerabilities such as:
- Unsigned first commits allow repository forgery. Without a cryptographic signature, anyone can create a repository and claim it as authoritative.
- No built-in method to verify repository origin. If a repository is cloned and altered, there is no cryptographic link to its original creator.
- First commits can be rewritten. An attacker can modify a repository's history, effectively changing its origin without detection.
Open Integrity introduces the Inception Commit, a specially crafted empty commit that serves as a cryptographic foundation. This commit includes both a Ricardian Contract establishing trust rules and a cryptographic signature. While Git uses SHA-1 (which has known cryptographic weaknesses), the Inception Commit mitigates these risks through:
- Constrained content: An empty commit (containing no files) with minimal metadata reduces the attack surface for SHA-1 collisions (~80-bit security)
- SSH signing: Even if a hash collision were achieved, an attacker would still need to forge a valid SSH signature (~128-bit security)
- Deterministic state: The empty tree hash is predictable and easily verified
Assuming your git config --global
configuration is correctly set up (see the test snippet in Open_Integrity_Script_Snippets.md
), this command (for the ZSH shell) will create a new repository and sign its initial Inception Commit according to Open Integrity specifications.
eval "$(
cat <<'EOF'
zsh_git_inception() {
[ -d "$(pwd)/new_open_integrity_repo/.git" ] && echo "❌ Repo already exists." && return 1
mkdir -p "$(pwd)/new_open_integrity_repo" && git -C "$(pwd)/new_open_integrity_repo" init > /dev/null
SIGNING_KEY="$(git config --global user.signingkey)"
GIT_AUTHOR_NAME="$(git config --global user.name)"; GIT_AUTHOR_EMAIL="$(git config --global user.email)"
GIT_COMMITTER_NAME="$(ssh-keygen -E sha256 -lf "$SIGNING_KEY" | awk '{print $2}')"
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; GIT_AUTHOR_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"; GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
GIT_COMMITTER_NAME="$GIT_COMMITTER_NAME" GIT_COMMITTER_EMAIL="$GIT_COMMITTER_EMAIL" \
GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" GIT_COMMITTER_DATE="$GIT_COMMITTER_DATE" \
git -C "$(pwd)/new_open_integrity_repo" -c gpg.format=ssh -c user.signingkey="$SIGNING_KEY" \
commit --allow-empty --no-edit --gpg-sign \
-m "Initialize repository and establish a SHA-1 root of trust" \
-m "Signed-off-by: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" \
-m "This key also certifies future commits' integrity and origin. Other keys can be authorized to add additional commits via the creation of a ./.repo/config/verification/allowed_commit_signers file. This file must initially be signed by this repo's inception key, granting these keys the authority to add future commits to this repo including the potential to remove the authority of this inception key for future commits. Once established, any changes to ./.repo/config/verification/allowed_commit_signers must be authorized by one of the previously approved signers."
[ $? -eq 0 ] && echo "✅ Repo initialized!" || echo "❌ Commit failed. Check Git settings."
}
zsh_git_inception
EOF
)"
This establishes an immutable foundation for all future commits:
🔹 Commit: #a3306ef [🏁 Inception Commit] (Signed ✅)
├─ Message: "Initialize repository and establish a SHA-1 root of trust"
├─ Signed by: @a61TkTtL... (🏁 Alice using Device 1 <[email protected]>)
├─ Empty: true (no files added)
├─ SHA-1 Protection: Constrained content + SSH signature
└─ Verification: Platform-independent
Git does not natively track who is authorized to sign commits, leading to these risks:
- Any developer with push access can commit, regardless of trust status.
- There is no built-in way to enforce commit signer governance.
- Compromised keys can continue to sign commits indefinitely.
- Git does not provide an auditable way to delegate or revoke commit signing permissions.
To mitigate these issues, Open Integrity implements two verification paths:
-
Direct Inception Key Authority:
- Only the holder of the inception key can commit to protected branches (like main)
- Other developers can author commits in feature branches
- The inception key holder must verify and commit these changes to protected branches
- All commits in protected branches are verified directly against the inception key
-
Delegated Authority:
- Established through a trust transition commit signed by the inception key
- Configures a local allowed_commit_signers file within the repository
- Creates an unbroken chain of trust from inception through subsequent authorizations
- Each modification to allowed_commit_signers must be signed by an authorized key
Delegation is implemented through the Allowed Commit Signers File:
# Configure allowed commit signers verification
git config --local gpg.ssh.allowedSignersFile .repo/config/verification/allowed_commit_signers
# Install pre-receive hook for validation
cat > .git/hooks/pre-receive <<'EOF'
#!/bin/sh
while read oldrev newrev refname; do
verify_authorized_signer $newrev
done
EOF
This Allowed Commit Signers file establishes the trust hierarchy, beginning with a transition from the Inception Key:
🔹 Commit: #b24d9c1 [🔑 New Allowed Commit Signers File] (Signed ✅)
├─ Message: "Added second device key for Alice"
├─ Signed by: @a61TkTtL... (🏁 Alice using Device 1 <[email protected]>)
└─ New Authorized Commit Signers:
- 🏁 Inception Key explicitly not included for future commits
- + @a61TkTtL... (Alice using Device 1 <[email protected]>)
- + @f84PmWnY... (Alice using Device 2 <[email protected]>)
After this point, only keys listed in the Allowed Signers file can make commits. As trust expands, additional commit signers can be added by any authorized key:
🔹 Commit: #f75e3b9 [🔑 Added Bob and Charlie as Signers] (Signed ✅)
├─ Message: "Added Bob and Charlie to allowed commit signers"
├─ Signed by: @a61TkTtL... (Alice using Device 1 <[email protected]>)
└─ New Authorized Commit Signers found:
- @a61TkTtL... (Alice using Device 1 <[email protected]>)
- @f84PmWnY... (Alice using Device 2 <[email protected]>)
- + @b73RkKpQ... (Bob using Work Laptop <[email protected]>)
- + @c58XmWpL... (Charlie using Home PC <[email protected]>)
Git does not provide a way to manage key expiration or revocation, creating risks such as:
- A compromised SSH key remains valid indefinitely.
- Old keys remain trusted unless manually removed.
- Revoked keys are not automatically rejected by Git.
- If a key is revoked, Git does not automatically reject future commits signed by it.
Open Integrity can enforce structured key rotation using Git's native timestamping and notes features:
# Record key authorization with timestamp
git notes --ref=key-history add -m "Authorized: $(date -u +"%Y-%m-%dT%H:%M:%SZ") $keyid"
When a key is revoked:
🔹 Commit: #c3d7f12 [🔄 Key Rotation: Removed Alice's Second Device] (Signed ✅)
├─ Message: "Revoked second device key"
├─ Signed by: @f84PmWnY... (Alice using Device 2 <[email protected]>)
├─ Authorized Commit Signers changed:
- 🗑️ @f84PmWnY... (Alice using Device 1 <[email protected]>) is no longer authorized.
- @f84PmWnY... (Alice using Device 2 <[email protected]>)
- @b73RkKpQ... (Bob using Work Laptop <[email protected]>)
- @c58XmWpL... (Charlie using Home PC <[email protected]>)
If someone attempts to use a revoked key:
🔹 Commit: #e9a1b78 [❌ Invalid Signature - Not Authorized!]
├─ Message: "Fix security vulnerability"
├─ Signed by: @a61TkTtL... (Alice using Device ` <[email protected]>)
├─ 🚨 ERROR: Commit was signed using a previously revoked key!
└─ ❌ ERROR: Commit was not merged into main
Git's separation between commit authors and committers creates additional verification challenges:
- Author attribution can be claimed without proof. While Git records both the author and committer of changes, it doesn't verify that the stated author actually wrote or approved the changes.
- Contributor agreements can't be cryptographically enforced. Many projects require contributors to sign agreements, but Git provides no way to verify that authors consented to these terms.
- Committers can modify author attribution. When merging changes, committers can alter the author field without detection.
- Rebase and squash operations lose author signatures. Common Git workflows can strip away proof of original authorship, making it impossible to verify after the fact.
Open Integrity ensures both authorship authenticity and committer authorization by:
- Requiring cryptographic signatures from both authors and committers
- Preserving author signatures through merge operations
- Maintaining a verifiable chain of consent for repository agreements stored in configuration files
- Detecting any unauthorized modifications to authorship claims
Git's merge process creates specific challenges for maintaining both author authenticity and committer authorization. When merging changes:
- Author signatures are not required or verified. Changes can be merged without proof that the stated author approved them.
- Committer authority isn't linked to author consent. Authorized committers can merge changes without verifying author approval.
- Feature branches may be deleted after merging, erasing verification records.
- Squash and rebase merges strip both author and committer signatures, losing the chain of proof.
Open Integrity enforces a dual-signature model through merges:
# During merge, verify both author and committer signatures
git merge feature-branch --verify-signatures \
--require-author-signature \
--require-committer-authorization
# Preserve both signature chains
git notes --ref=signatures add -m "$(git verify-commit HEAD)" $commit
Merges maintain full verification records for both parties:
🔹 Commit: #fa34d76 [🔀 Merge Commit with Verified Author] (Signed ✅)
├─ Message: "Merge feature-branch: Added authentication layer"
├─ Committer: @c58XmWpL... (Charlie using Home PC <[email protected]>)
├─ Author: @e83TkLqM... (Eve using Dev Machine <[email protected]>)
├─ Author Signature: Verified ✓ (signed 2024-02-10T15:30:00Z)
├─ Committer Authorization: Verified ✓ (in allowed_signers since 2024-01-15)
└─ Signatures stored: ./config/verification/signatures
If author signatures are lost during a squash/rebase:
🔹 Commit: #g61x3p4 [⚠️ Merge Commit with Lost Author Signature] (Signed ✅)
├─ Message: "Merge feature-branch: Database optimization"
├─ Committer: @b73RkKpQ... (Bob using Work Laptop <[email protected]>)
├─ Author: @e83TkLqM... (Eve using Dev Machine <[email protected]>)
├─ ⚠️ WARNING: Original author signature not found
├─ Committer Authorization: Verified ✓
└─ ⚠️ Recommended Action: Author to re-sign changes
# Commit Signed By Status Message Special Event
------------------------------------------------------------------------------------------
0 #a3306ef @a61TkTtL... ✅ Initialize repository... 🏁 Inception Commit
1 #d74f9b2 @a61TkTtL... ✅ Fix typo in README
2 #b24d9c1 @a61TkTtL... ✅ Initial allowed_commit... 🔑 Initial Commit Signers File
3 #f75e3b9 @b73RkKpQ... ✅ Refactor logging system
4 #c3d7f12 @c58XmWpL... ✅ Rotate out Alice from... 🔄 Key Rotation (🗑️ Removed Alice)
5 #fa34d76 @c58XmWpL... ✅ Merge feature-branch... 🔀 Verified Author Signature (✔️)
6 #g61x3p4 @b73RkKpQ... ⚠️ Merge feature-branch... ⚠️ Lost Author Signature
7 #e9a1b78 @a61TkTtL... ❌ Fix security vulnerab... 🚨 Unauthorized Signature
🔹 **Total Commits Checked:** 8
✅ **Commits with Valid Signatures:** 6
❌ **Commits with Unauthorized Signers:** 1
🔄 **Key Rotation Events:** 1 (Alice removed)
🔀 **Merge Commits with Verified Authors:** 1
⚠️ **Merge Commits with Lost Author Signatures:** 1
While the Minimal Viable Architecture (MVA) of Open Integrity secures local repository trust through commit authenticity, signer governance, key rotation, and merge verification, additional opportunities can further strengthen resilience, governance, and decentralized trust.
Currently, Open Integrity relies on manually maintained lists of authorized signing keys, but this model does not account for broader authentication sources. There is no distributed way to verify commit signers across multiple independent trust networks.
To expand trust verification, Open Integrity could integrate multi-source key authentication:
# Future: Verify key against multiple sources
verify_key() {
# Check local allowed_signers
if ! check_local_authorization "$keyid"; then
return 1
fi
# Query GitHub's SSH key API
if ! verify_github_key "$keyid" "$username"; then
return 1
fi
# Check Web of Trust attestations
if ! verify_wot_attestations "$keyid"; then
return 1
fi
# Verify cross-repository attestations
if ! verify_repo_attestations "$keyid"; then
return 1
fi
# Verify hardware-backed keys
if ! verify_hardware_key "$keyid"; then
return 1
fi
return 0
}
This approach enables cross-repository trust validation, with enhanced security through:
- Git platform authentication services (GitHub, GitLab, etc.)
- Integration with platform key stores (macOS Keychain, Windows Certificate Store)
- Support for hardware security modules (FIDO/YubiKey, TPM)
- Cross-platform key verification without compromising independence
Open Source Git repositories are typically tied tightly to centralized hosting providers like GitHub or GitLab. If a repository is removed, censored, or lost due to platform failure, it may become inaccessible. Open Integrity could introduce decentralized archival and recovery mechanisms:
# Future: Push to decentralized storage
git push ipfs://QmHash... # Store on IPFS
git push bt://InfoHash... # Store on BitTorrent
# Future: Verify repository integrity
git verify-integrity ipfs://QmHash... \
--inception-commit a3306ef \
--trust-root @a61TkTtL...
# Future: Emergency key recovery using SSKR
git key recover --shares 2 \
--threshold 3 \
--recovery-method sskr
# Future: Automated key rotation during compromise
git key rotate-emergency \
--revoke compromised-key \
--activate backup-key \
--notify all-signers
This ensures repositories remain resilient through:
- Distributed storage across multiple networks
- Threshold-based key recovery using SSKR
- Automated emergency response procedures
- Secure key revocation workflows
While Open Integrity ensures cryptographic trust within a repository, individual developers have no way to cryptographically prove authorship across multiple repositories. Git provides no built-in mechanism to cryptographically assert a developer's identity and contributions across multiple repositories.
Open Integrity could establish personal cryptographic roots of trust:
# Future: Create developer trust root
git trust-root init "Alice" \
--key @a61TkTtL... \
--device "Device 1" \
--email [email protected]
# Future: Cross-repository attestation
git attest-contribution \
--repo alice/alice \
--commit abc123 \
--sign @a61TkTtL...
Git repositories currently rely solely on the initial commit hash for uniqueness, which presents challenges.
- Repositories can be cloned and rehosted under different names
- No cryptographic link between copies of the same repository
- No way to verify authenticity when repositories move between platforms
- Two different repositories can share the same commit history if they originated from the same base commits, forging new commits.
Open Integrity could solve this through a unique identity model:
# Future: Generate globally unique repository identifier
git repo generate-id \
--inception-commit a3306ef \
--initial-signer @a61TkTtL...
# Future: Verify repository authenticity across platforms
git verify-repo-uniqueness \
--id "repo:a3306ef:@a61TkTtL..." \
--verify-history
This ensures repositories maintain their identity regardless of location:
🔹 Repository Identity Verification
├─ Unique ID: repo:a3306ef:@a61TkTtL...
├─ Inception Commit: #a3306ef
├─ Initial Signer: @a61TkTtL...
├─ Creation Date: 2024-02-12T14:30:00Z
└─ Verification: Independent of hosting location
Open Integrity could introduce full W3C DID integration:
# Future: Generate W3C-compliant repository DID
did:repo:git:$(git rev-parse HEAD):$(git config user.signingkey)
# Future: Verify repository identity
git verify-repo-id did:repo:git:a3306ef:@a61TkTtL...
An example W3C Controller Document for a git repository from a DID Resolver:
{
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:repo:deedb3380e3e75266a009ee43b1dec54619f1b0f",
"verificationMethod": [
{
"id": "did:repo:deedb3380e3e75266a009ee43b1dec54619f1b0f#ssh-key-1",
"type": "SshPublicKey",
"controller": "did:repo:dbe44e2f99347b403b8b649605dd718bf5a69614?serviceEndpoint=https%3A%2F%2Fgithub.com%2FChristopherA%2FChristopherA"
"publicKeySsh": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC2O9n9I7RK1DXvnd7+eKYT+0Cr1bCJvdN/pdkb7625S"
}
],
"authentication": [
{
"id": "did:repo:deedb3380e3e75266a009ee43b1dec54619f1b0f#ssh-key-1",
"type": "SshPublicKey",
"controller": "did:repo:dbe44e2f99347b403b8b649605dd718bf5a69614?serviceEndpoint=https%3A%2F%2Fgithub.com%2FChristopherA%2FChristopherA"
"publicKeySsh": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC2O9n9I7RK1DXvnd7+eKYT+0Cr1bCJvdN/pdkb7625S",
"proofPurpose": "authenticationCommitOnly" // Indicating restricted use specifically for commit authentication
}
]
}
Git's current distribution model relies on centralized hosting platforms or direct peer connections. Open Integrity could leverage existing peer-to-peer networks for resilient, decentralized distribution:
# Future: Publish repository updates to BitTorrent's MainlineDHT
git publish-update mainlinedht \
--update-type key-rotation \
--signed-by @a61TkTtL... \
--dht-key "repo:a3306ef:updates"
# Future: Subscribe to repository updates
git subscribe-updates mainlinedht \
--repo did:repo:git:a3306ef \
--verify-signatures \
--trust-root @a61TkTtL...
Example distributed update:
🔹 Repository Update via MainlineDHT
├─ Type: Key Rotation Event
├─ DHT Key: repo:a3306ef:updates
├─ Signed By: @a61TkTtL... (Alice using Device 1)
├─ Timestamp: 2024-02-12T14:30:00Z
├─ Content: New authorized key @h92MnPq...
└─ Verification: Independent of hosting platform
This approach enables:
- Real-time distribution of trust updates across the network
- Resilient update delivery without central servers
- Efficient use of existing DHT infrastructure
- Independent verification of update authenticity
Git repositories require different levels of trust for commits, tags, and releases. Open Integrity could manage these distinct privileges through separate authorized signer lists:
# Future: Configure role-based signing authorities
git trust configure-roles \
--commit-signers .repo/config/verification/allowed_commit_signers \
--tag-signers .repo/config/verification/allowed_tag_signers \
--release-signers .repo/config/verification/allowed_release_signers
Example role configuration:
🔹 Repository Signing Roles
├─ Commit Signers: Regular developers making changes
| └─ @a61TkTtL..., @b73RkKpQ..., @c58XmWpL...
├─ Tag Signers: Release managers marking versions
| └─ @d94NmRs..., @e82PkQt...
└─ Release Signers: Security team signing binaries
└─ @f71MnPp..., @g63LkOr...
Open Integrity could standardize repository trust through manifest files that balance transparency with developer privacy using commitments, elided data, or zk-proofs:
# Future: Create repository trust manifest
git trust init-manifest \
--governance threshold-2-of-3 \
--privacy elision-enabled \
--audit structured-transparency
# Future: Multi-party authorization using FROST
git trust authorize-change \
--signers required-2-of-3 \
--protocol frost \
--preserve-privacy
Example trust manifest capabilities:
🔹 Repository Trust Manifest
├─ Governance: Threshold 2-of-3 signing
├─ Privacy: Elidable commit metadata
├─ Authorization: FROST threshold signatures
├─ Audit: Privacy-preserving trails
└─ Verification: Independent assessment
While Git is decentralized, most verification processes depend on platform-specific tools like GitHub or GitLab. Open Integrity ensures platform-independent verification:
# Future: Independent repository audit
git audit-repo \
--trust-root @a61TkTtL... \
--allowed-signers-file .github/allowed_signers \
--verification-period "2024-01-01/2024-12-31" \
--privacy-preserving
Example audit output:
🔹 Repository Audit Report: 2024-01-01 to 2024-12-31
├─ Total Commits: 247
├─ Valid Signatures: 245
├─ Invalid/Missing Signatures: 2
├─ Key Rotation Events: 3
├─ Merge Commits (Verified): 15
├─ Merge Commits (Lost Author Signatures): 1
├─ Privacy: All sensitive data properly elided
├─ Trust Chain: All keys affirmed from Inception (#a3306ef) to head (#3f9245bc)
└─ Endorsements: Security review by key @bf8640d1 (Rebecca <[email protected]>)
Open Integrity establishes cryptographic trust in Git repositories by securing commit authenticity, key governance, and repository provenance. The MVA provides immediate benefits through local verification, while future enhancements will enable a broader trust ecosystem for software development. Together, these create a self-sovereign, platform-independent trust framework for verifiable software provenance.