Commit signing: one coherent story for humans, agents, and the git plugin
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Filed from a concrete friction point, but the scope is the design question behind it.
The friction that surfaced it
Agent sessions in this repo run with commit.gpgsign=true pointed at a 0-byte key file and no private key, so every branch commit is unsigned and a stop hook flags each one as "will show Unverified" with a suggested fix (--reset-author) that cannot help — the identity is already right; the signature is what's missing. Today's working answer is: branch commits stay unsigned, squash-merge lets GitHub sign the commit that lands, main stays Verified. That works, but it's a convention held in people's heads, not a decision written anywhere — and it quietly means branch history is unattestable, which matters more as agents author more of it.
What a coherent answer has to cover
Three distinct surfaces want one story, because they share the same primitives (SSH/GPG/x509 signatures, allowed-signers, forge verification) but different trust models:
- Humans locally — a maintainer's own key, verified by the forge. The easy case; the story just has to not get in its way.
- Agents, locally and remote — the interesting case. What does a signature from an agent mean? Options with very different affordances:
- No agent signing; forge signs on squash-merge (today's answer — make it explicit, and make the hook stop demanding what the environment cannot do).
- A per-environment ephemeral key, so a signature attests "this specific session's environment produced this," not a durable identity.
- Keyless/OIDC-backed signing (sigstore/gitsign-style), which is the closest analogue to how flowstate already treats workload identity: short-lived, issuer-attested, no long-lived material to leak. This rhymes with the existing identity/JIT-federation substrate and is probably the direction that fits the system's own principles.
- The
gitplugin — flowstate workflows will create commits (git.commit_push, in flight). Signing there is a task capability question with the repo's own rules applied:- Key material is a secret: reference in, resolved only inside the activity, never in history, containment-shape tested (invariant 7).
- Deterministic commits (timestamps as inputs → identical sha on retry → idempotent push) interact with signing: signatures over identical content with a deterministic scheme stay stable; anything nondeterministic in the signature envelope breaks the retry-idempotence property. This constraint should be stated in the task's docs and pinned by a test.
- The verification direction may matter more than the signing direction: a workflow that acts on a repo's contents may want
verify: true— refuse to proceed on commits that don't match an allowed-signers set. That's fail-closed policy, which is the house shape.
Decisions this issue should produce
- A written policy for this repo's own branches: unsigned-branch/signed-squash as the explicit norm, or provisioned agent keys — and the stop hook updated to match, so it stops prescribing an impossible fix.
- Whether agent-authored commits should carry environment-attested (ephemeral/OIDC) signatures, and what a verifier is entitled to conclude from one.
- Scope for the git plugin:
sign:(key-as-secret-ref) andverify:/allowed-signers as task inputs, with the determinism constraint documented, or explicitly deferred with the reason recorded.
Not urgent — nothing is broken; squash-merge keeps main Verified. Filed so the nuance lives somewhere other than a session transcript.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the stop hook and the git.commit_push entry point, including the referenced invariant 7 and any existing task documentation or tests. The work is done when the repository policy for branch and agent signatures is written, the hook behavior matches it, and the git plugin’s signing, verification, allowed-signers, and determinism scope is explicitly decided and tested or deferred.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github
- Domain
- security, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100