← All posts
git security tooling

Signing Git Commits Using 1Password and the GitHub CLI

April 12, 2026

Most developers skip commit signing because GPG is a pain to set up and maintain. Since Git 2.34, you can sign commits with SSH keys instead, and 1Password makes this close to effortless: it stores the private key in your vault, signs through its built-in SSH agent, and prompts for Touch ID when you commit. GitHub shows the same green “Verified” badge for SSH signatures as it does for GPG, so you get the same result with far less friction.

How SSH Commit Signing Works

Traditional commit signing uses GPG. You generate a GPG keypair, register the public key with GitHub, and configure Git to sign with gpg. It works, but GPG key management is its own world of complexity.

SSH commit signing is the alternative. Git 2.34 (released November 2021) added native support for signing commits and tags with SSH keys. The cryptographic mechanism is different, but the result is the same: a signature that GitHub can verify against a public key you’ve registered on your account.

1Password plugs into this by acting as the SSH agent. When Git needs to sign a commit, it asks the SSH agent for a signature. The 1Password agent receives that request, prompts you for biometric authorization (Touch ID, Windows Hello), performs the signing inside its own process, and returns the signature. The private key never leaves 1Password.

Prerequisites

Before starting, you’ll need:

Generate an SSH Key in 1Password

Open the 1Password desktop app and create a new SSH key:

  1. Select New Item > SSH Key
  2. Select Add Private Key > Generate New Key
  3. Choose Ed25519 as the key type
  4. Click Save

Ed25519 is the right default here. The keys are smaller and signing is faster than RSA, with equivalent security at the key sizes that matter.

You now have a private key stored in your vault and a public key you can copy out. You’ll need the public key in two later steps.

Enable the 1Password SSH Agent

The SSH agent makes this work. It intercepts SSH operations (including commit signing) and routes them through 1Password with biometric authorization.

  1. Open 1Password > Settings (Cmd+,) > Developer
  2. Select Set Up SSH Agent
  3. Under the agent settings, choose “Ask approval for each new application and terminal session” for the authorization prompt behavior

Then tell your SSH client to use the 1Password agent. Add this to ~/.ssh/config:

Host *
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"

Note: That path is macOS-specific. Check 1Password’s SSH agent docs for the Windows and Linux equivalents.

Make sure 1Password is set to start at login and stay in the menu bar (Settings > General), otherwise the agent won’t be available when you need it.

Configure Git for SSH Signing

There are two ways to do this.

The easy way: Open the SSH key item in the 1Password desktop app, click the ... menu, select Configure Commit Signing, and choose Edit Automatically. 1Password writes the correct config to your ~/.gitconfig with the right paths for your OS.

The manual way: Add the following to your ~/.gitconfig:

[gpg]
format = ssh
[gpg "ssh"]
program = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign"
[user]
signingkey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...
[commit]
gpgsign = true
[tag]
gpgSign = true

Four settings, each doing one thing:

| Setting | Purpose | | --- | --- | | gpg.format = ssh | Tells Git to use SSH signatures instead of GPG | | gpg.ssh.program | Points Git to 1Password’s signer binary for the signing operation | | user.signingkey | Your SSH public key (copy it from the 1Password item) | | commit.gpgsign = true | Auto-sign every commit without needing the -S flag |

With commit.gpgsign = true, you don’t need to remember git commit -S. Every commit gets signed automatically, and 1Password prompts for Touch ID each time.

Register the Signing Key on GitHub

GitHub needs your public key registered as a signing key to verify your commits. The gh CLI makes this a one-liner, but you’ll need to be authenticated first. If you haven’t already, run:

Terminal window
gh auth login

This walks you through a browser-based OAuth flow to authenticate the CLI with your GitHub account.

Now copy the public key from the 1Password item, save it to a temporary file, and add it:

Terminal window
gh ssh-key add /tmp/signing_key.pub --title "1Password Signing Key" --type signing

The --type signing flag is what distinguishes this from an authentication key. GitHub treats them separately: authentication keys authorize push/pull over SSH, signing keys verify commit signatures.

If you also use this key for SSH authentication (pushing and pulling over SSH instead of HTTPS), add it a second time as an authentication key:

Terminal window
gh ssh-key add /tmp/signing_key.pub --title "1Password Auth Key" --type authentication

You can verify both keys are registered:

Terminal window
gh ssh-key list

Clean up the temp file when you’re done:

Terminal window
rm /tmp/signing_key.pub

Set Up gh for Git Authentication

This step is separate from signing but completes the workflow. If you use HTTPS remotes for push and pull, gh auth setup-git configures Git to use the GitHub CLI as a credential helper:

Terminal window
gh auth setup-git

This tells Git to delegate HTTPS authentication to gh, so you don’t need a personal access token stored in your system keychain. You already ran gh auth login in the previous step, so the CLI is already authenticated.

Authentication and signing are independent concerns. gh handles auth. 1Password handles signing. They don’t overlap.

Test It

Make a commit and watch for the Touch ID prompt:

Terminal window
git commit --allow-empty -m "test: verify commit signing"

1Password should pop up a biometric authorization dialog. After you approve, the commit is signed.

Push the commit and check it on GitHub. You should see the green “Verified” badge next to the commit message. Clicking the badge shows the SSH key fingerprint and confirms the signature is valid.

If you don’t see the badge, double-check that the public key in user.signingkey matches the one you registered on GitHub, and that you added it with --type signing.

A Note on AI Agents and Commit Signing

If you use AI coding agents that have terminal access, commit signing with 1Password creates a side effect: the agent can’t make commits without your physical presence.

When an agent runs git commit, Git asks the SSH agent for a signature. 1Password receives that request and pops up a Touch ID prompt. The agent has no way to approve that prompt programmatically. The commit fails if you don’t physically authorize it.

This turns commit signing into a lightweight approval gate. Every commit the agent tries to make requires you to see it happening and actively approve it with your fingerprint.

There are caveats, though. 1Password’s authorization has configurable scopes, and session reuse can weaken this. If you set authorization to “per application” and you already approved Terminal earlier in the session, the agent running in that same Terminal instance may inherit the existing approval. Set authorization to “per application and terminal session” so each new terminal tab requires its own biometric prompt.

The bigger gap is that an agent with shell access could run git -c commit.gpgsign=false commit to bypass signing entirely. Client-side config is a default, not a hard constraint. If your agent supports hooks (Claude Code and Copilot both do), you can add a pre-command hook that rejects any git invocation containing commit.gpgsign=false before it reaches the shell. That closes the override path without relying on the agent to follow instructions. The real enforcement still has to happen on the server: enable “Require signed commits” on your protected branches in GitHub so unsigned commits are rejected on push. Pair this with vigilant mode on your GitHub account to flag anything unsigned as “Unverified.”

1Password’s biometric prompt gives you client-side friction. Branch protection rules give you server-side enforcement. Together they make it hard for an automated process to land unsigned commits on protected branches without you knowing about it.