Skip to content

Signing & Verification

TheCorporation uses two distinct layers of cryptographic integrity:

  1. SHA-256 document content hashing — implemented in v2, protects formation documents from stale-signature attacks.
  2. Ed25519 git commit signing — designed and specified, planned for v2 but not yet implemented.

Every formation Document carries a content_hash field — a SHA-256 hex digest of the document content at creation or last amendment.

When a signer submits a signature, they must include document_hash_at_signing. The system rejects the signature if this hash does not match the current content_hash:

// Document::sign rejects stale hashes
if signature.document_hash_at_signing != self.content_hash {
return Err(DocumentError::HashMismatch {
expected: self.content_hash.clone(),
actual: signature.document_hash_at_signing.clone(),
});
}

This ensures:

  • A signer cannot sign a document they have not seen.
  • A document cannot be amended after a signature is collected without invalidating the signature.
  • The audit record is tamper-evident: the hash stored in the receipt proves what content was approved.

This applies to all formation documents: certificates of incorporation, bylaws, articles of organization, operating agreements, and incorporator actions.

The design for Ed25519 SSH commit signatures is complete and specified below. The feature is not yet implemented in v2. All commits are unsigned in the current release.

When commit signing is configured, every state-changing git commit will be signed:

  1. The backend builds the commit buffer (tree, parent, author, message)
  2. The commit message gets a CommitActor trailer appended (identity metadata)
  3. The buffer is signed with the Ed25519 private key via SSH signature format
  4. The signed commit is written with the standard gpgsig header

The result is a commit that git log --show-signature can verify with standard tooling.

Every signed commit will include an identity trailer block in the commit message:

Issue 10,000 shares of Common Stock to Jane Smith
---
workspace_id: ws_abc123
entity_id: ent_def456
scopes: equity-write
timestamp: 2026-02-27T14:30:00Z
signer_fingerprint: SHA256:xYz...
FieldPurpose
workspace_idWhich workspace authorized this commit
entity_idWhich entity this commit affects
scopesWhat permissions were used
timestampWhen the operation was authorized
signer_fingerprintSHA-256 fingerprint of the signing key

For system-initiated commits (migrations, automated maintenance), the actor will be a sentinel system identity.

Commits will be signed using the SSH signature format (same as git commit -S with SSH keys):

-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg...
-----END SSH SIGNATURE-----

This is stored in the commit’s gpgsig header, compatible with git log --show-signature and GitHub’s signature verification.

Terminal window
# View signatures in log
git log --show-signature
# Set up an allowed signers file for verification
echo "* namespaces=\"git\" $(cat signing_key.pub)" > ~/.ssh/allowed_signers
git config gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
# Verify a specific commit
git verify-commit HEAD
Terminal window
# Generate a key (if you don't have one)
ssh-keygen -t ed25519 -f corp_signing_key -N ""
# Configure the backend
export COMMIT_SIGNING_KEY="$(cat corp_signing_key)"

The backend will accept Ed25519 private keys in OpenSSH PEM format. Only Ed25519 will be supported — RSA, ECDSA, and other key types will be rejected.

FeatureStatusWhat it protects
SHA-256 content hashingImplementedFormation documents cannot be signed stale
Ed25519 commit signingPlannedEvery git commit is cryptographically attributed

SHA-256 hashing is the difference between “we recorded a signature” and “we can prove what was signed.” Ed25519 commit signing will make the entire git audit trail cryptographically verifiable — the difference between “we have an audit trail” and “we have a cryptographically verifiable audit trail.”