Pular para o conteúdo
ecdsa.com
Git commit signing with GnuPG 2Git

Mensagem de erro

gpg: signing failed: Inappropriate ioctl for device

Também aparece como

  • [GNUPG:] FAILURE sign 83918950

O Git o imprime abaixo de “error: gpg failed to sign the data”. Com `--status-fd`, o gpg também emite `[GNUPG:] FAILURE sign 83918950` (o código numérico de erro do GPG para essa condição).

Git commit signing with GnuPG 2 — pinentry has no terminal

O que significa

A chave de assinatura é protegida por uma frase secreta, o gpg-agent iniciou um pinentry de terminal para pedi-la e o pinentry não conseguiu abrir um terminal. “Inappropriate ioctl for device” é o `ENOTTY` do sistema operacional: o stdin não é um TTY e `GPG_TTY` não indica nenhum. A chave e a configuração estão corretas; só o pedido da frase secreta falhou.

Por que acontece

Como corrigir

  1. 1.

    Exportar GPG_TTY

    Adicione a variável ao perfil do shell; atualize o agente em execução com `updatestartuptty` se ele tiver sido iniciado em outro terminal.

    bash
    # ~/.bashrc or ~/.zshrc
    export GPG_TTY=$(tty)
    # if gpg-agent was started before, tell it about the current terminal
    gpg-connect-agent updatestartuptty /bye
  2. 2.

    Usar um pinentry gráfico

    `pinentry-mac`, `pinentry-gnome3` ou `pinentry-qt` mostram uma caixa de diálogo, o que funciona também em IDEs.

    bash
    # macOS (Homebrew): a GUI pinentry works for IDEs and GUI Git clients too
    brew install pinentry-mac
    echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
    gpgconf --kill gpg-agent
  3. 3.

    Pinentry loopback para automação

    Com `allow-loopback-pinentry`, o gpg pode ler a frase secreta de um arquivo. Use uma chave dedicada ao CI e só para assinatura, nunca uma chave pessoal.

    bash
    # CI: a dedicated signing key; passphrase supplied non-interactively via loopback pinentry
    echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf && gpgconf --kill gpg-agent
    cat > /usr/local/bin/gpg-ci <<'EOF'
    #!/bin/sh
    exec gpg --batch --pinentry-mode loopback --passphrase-file "$GPG_PASSPHRASE_FILE" "$@"
    EOF
    chmod +x /usr/local/bin/gpg-ci
    git config --global gpg.program gpg-ci

Erros relacionados

Ver toda a base de erros de assinatura