Wilson Mar bio photo

Wilson Mar

Hello!

Email me Calendar Skype call

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Sign git commits and tags (for non-repudiation) in GitHub using GPG, Vault, Yubikey, Keybase

US (English)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Cyrillic Russian   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean

Overview

The contribution of this article is a logical ordering of deep-dive concepts presented in a succint way, as a hands-on narrated scenic tour. “PROTIP” flags advice from hard-won experience such as relevant keyboard shortcuts and things to remember, available only here for you.

git-signing-ale-413x262

“If you … want to verify that commits are actually from a trusted source, Git has a few ways to sign and verify work using GPG.” -git-scm.com/show-ref command

Decisions: Variations

This workflow can seem complicated because there are several options: tooling variations (described below):

  • Operating system of local machine (macOS, Windows, Linux flavors)
  • Install a GUI app and/or Command-line program to sign keys
  • Download installer from publisher web page or run package manager (Homebrew, Chocolately)

  • The secret-keeping service (macOS Keychain, GPG, Yubikey, Keybase.io, employer-specified, etc.)
  • Sign every commit or just git tag each release?

The workflow:

  1. Make decisions about install variations
  2. Install apps and programs locally
  3. Configure emails and set up GitHub to require signing
  4. Generate and list keys
  5. Add public GPG key to GitHub
  6. Sign Git commits and merges
  7. Sign Git Tags
  8. Import key to GPG on another host

BONUS: Since we’re using GPG, here are also notes about signing of whole files using GPG and getting Facebook to encrypt notification emails it sends you.https://www.cnet.com/how-to/how-to-make-facebook-send-you-encrypted-notification-emails/


Install client utilities

The alternatives:

Enterprises would use a centrally administered system to install for all users, such as:

Desired “Self-Serve” Workflow:

Here’s the workflow I would like to see. It’s not so much self-service as a tool for administrators. Anyway…

Before someone starts a job/project, a trusted administrator (the boss) specifies on a “self-service” portal what should be installed on each worker’s laptop, such as the client utilities which should be installed for his/her specific job based on RBAC (Role-Based Access Control) or Attribute-based Access Control (ABAC) policies.

The app generates the certificate pairs, stores them in Vault, installs them on GitHub, and saves the keys on the worker’s laptop. This provides a more trusted chain than each employee generating their own key pair.

Then all a new working developer needs to do is, on a pre-configured laptop, make a change and do a git tag or add and commit with a tag, then push.

Email address in GitHub

We want to configure GitHub to use your primary email in the form such as:

john_doe+github@gmail.com

The extra “+github” confuses simple attempts.

  1. Be at a browser profile you want to use. (I click on my avatar on Chrome to setup a profile for each email address I use - one for personal Gmail, another for work)

  2. In your browser, open a new tab to view your GitHub Profile Email page:

    https://github.com/settings/emails

  3. If your primary email does not have “+github”, type your address with the extra “+github” in the Add email address field, then click “Add”.

  4. If you are using Gmail or another email system that processes “+github” emails, for “Primary email address”, select that as your primary email.

    IMPORTANT PROTIP: The email specified to GPG should match that reply email in GitHub.

    Alternatively, highlight your “no reply” email address under the “Primary email address” heading. Example:

    12345678+johndoe@users.noreply.github.com

    Press command+C to copy it to your Clipboard.

    In your notes, press command+V to save that for use to Sign Commits (below).

Install on macOS GUI app GPG-Suite

Instead of VIDEO: downloading from website and clicking manually:

  1. Install silently with one command after installing Homebrew:

    brew install --cask gpg-suite

    (its previous name was gpgtools, as in the website gpgtools.com)

  2. Type your password when prompted.

    ==> Caveats
    Cask gpg-suite installs files under /usr/local. The presence of such
    files can cause warnings when running `brew doctor`, which is considered
    to be a bug in Homebrew Cask.
     
    ==> Downloading https://releases.gpgtools.org/GPG_Suite-2021.1_105.dmg
    ######################################################################## 100.0%
    ==> Installing Cask gpg-suite
    ==> Running installer for gpg-suite; your password may be necessary.
    Package installers may write to any location; options such as `--appdir` are ignored.
    installer: Package name is GPG Suite
    installer: Upgrading at base path /
    installer: The upgrade was successful.
    🍺  gpg-suite was successfully installed!
    
  3. Verify folder created during installation (include the quotes because the folder contains a space character):

    ls -al "/Applications/GPG Keychain.app/Contents/"
    total 16
    drwxr-xr-x   8 root  admin   256 May 14 18:37 .
    drwxr-xr-x   3 root  admin    96 May 14 18:37 ..
    drwxr-xr-x   3 root  admin    96 May 14 18:37 Frameworks
    -rw-r--r--   1 root  admin  3354 May 14 18:37 Info.plist
    drwxr-xr-x   3 root  admin    96 May 14 18:37 MacOS
    -rw-r--r--   1 root  admin     8 May 14 18:37 PkgInfo
    drwxr-xr-x  43 root  admin  1376 May 14 18:37 Resources
    drwxr-xr-x   3 root  admin    96 May 14 18:37 _CodeSignature
    

    To remove the app later, simply delete folder “GPG Keychain.app”, which would make certs disappear too. That’s why we will later save the certs to a location off your laptop.

  4. Open the app from Terminal:

    open "/Applications/GPG Keychain.app"

    Alternately, pinch 4 fingers together on the Touchpad and type enough of “GPG Keychain” for the icon to appear for you to click:

    git-signing-gpg-suite

  5. Click here to skip to Verify GPG (below).

    Gen GPG using macOS GPG-Suite

  6. Click “Show secret keys only” to ignore the Pub (Public) keys there by default.
  7. If there are green boxes marking your email from a previous session, you need to revoke it before creating a new key for that email.

  8. To generate a GPG key pair click “+ New” for the pop-up dialog.
  9. Click “Advanced options” to select Key Type “RSA (sign only)”.

    git-signing-mac-keychain-1540x804.png

  10. Type your name in title case.
  11. Type your email with the extra “+github” such as “wilsonmar+github@gmail.com”.
  12. Define a new password in your password vault, then copy and paste that new password in the two fields.
  13. Make a note of the expiration date (by default four years from current date).
  14. Click “Create Key”.
  15. If you select “No, Thanks!” to upload your public key and do that later from the “Key” menu item.
  16. Press Command+Q to quit the GPG Keychain program.

    Install on macOS CLI utility gnupg2

  17. Open a Terminal. Be at your home user folder.

  18. Execute a Bash script to do the following:

    Alternately, manually install brew (Homebrew)

  19. Upgrade or Install a Git client using Homebrew’s gnupg formulae

    brew upgrade git

    If git was not previously installed, install it:

    brew install git

    Notice the response is for a specific version of MacOS (Mojave in this case):

    ==> Upgrading 1 outdated package:
    git 2.25.0_1 -> 2.32.0
    ==> Upgrading git 2.25.0_1 -> 2.32.0
    ==> Downloading https://ghcr.io/v2/homebrew/core/git/manifests/2.32.0
    ######################################################################## 100.0%
    ==> Downloading https://ghcr.io/v2/homebrew/core/git/blobs/sha256:3c613c84fbc741
    ==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
    ######################################################################## 100.0%
    ==> Pouring git--2.32.0.mojave.bottle.tar.gz
    ==> Caveats
    The Tcl/Tk GUIs (e.g. gitk, git-gui) are now in the `git-gui` formula.
     
    Bash completion has been installed to:
      /usr/local/etc/bash_completion.d
     
    Emacs Lisp files have been installed to:
      /usr/local/share/emacs/site-lisp/git
    ==> Summary
    🍺  /usr/local/Cellar/git/2.32.0: 1,517 files, 41.5MB
    
  20. For information about the brew gpg2 install:

    brew info gnupg2

    The response at time of writing:

    ggnupg: stable 2.3.1 (bottled)
    GNU Pretty Good Privacy (PGP) package
    https://gnupg.org/
    /usr/local/Cellar/gnupg/2.3.1_1 (149 files, 12.4MB)
      Poured from bottle on 2021-06-18 at 18:20:55
    From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gnupg.rb
    License: GPL-3.0-or-later
    ==> Dependencies
    Build: pkg-config ✔
    Required: gettext ✔, gnutls ✔, libassuan ✔, libgcrypt ✔, libgpg-error ✔, libksba ✔, libusb ✔, npth ✔, pinentry ✔, sqlite ✔
    ==> Analytics
    install: 80,503 (30 days), 225,125 (90 days), 862,924 (365 days)
    install-on-request: 74,096 (30 days), 208,203 (90 days), 786,528 (365 days)
    build-error: 0 (30 days)
    
  21. Edit your ~/.bash_profile or ~/.bashrc file to ensure that commands for “gpg” are routed to gpg2:

    alias gpg="gpg2"
    echo -e "\n$(gpg --version | grep gpg)"    # gpg (GnuPG) 2.2.19
    

    PROTIP: The response shows that the installation is specific to each version of macOS:

    ==> Downloading https://homebrew.bintray.com/bottles/gmp-6.2.0.mojave.bottle.tar.gz
  22. Compare response from:

    brew info gpg

    Yeah, the same.

    Verify GPG install version

  23. Verify CLI noted in Wikipediat/Wikiwand.com/en/GNU_Privacy_Guard which states the source at d2qa dev.gnupg.org/source/gnupg

    gpg --version
    gpg (GnuPG/MacGPG2) 2.2.27
    libgcrypt 1.8.7
    Copyright (C) 2021 Free Software Foundation, Inc.
    License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
     
    Home: /Users/wilsonmar/.gnupg
    Supported algorithms:
    Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
    Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
         CAMELLIA128, CAMELLIA192, CAMELLIA256
    Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
    Compression: Uncompressed, ZIP, ZLIB, BZIP2
    
  24. Obtain keys:

    gpg -k

    Response:

    pub   rsa4096 2021-06-20 [SC] [expires: 2025-06-20]
       123456789E91004D4C5D88CAE21961814AC0EF1B
    uid           [ultimate] John Doe <johndoe+github@gmail.com>
    

    MacOS GPG Config

    PROTIP: The command above creates folder $HOME/.gnupg.

  25. Update or Create ~/.gnupg/gpg.conf

    code $HOME/.gnupg/gpg.conf
    

    Visual Studio Code should open with lines such as:

    auto-key-retrieve
    no-emit-version
    
  26. If the use-agent is not there, add it. If it’s there, remove the comment character # from “use-agent” to enable it:

    # Uncomment within config (or add this line)
    # This tells gpg to use the gpg-agent
    use-agent
    
  27. Add the default-key from the steps above:

    default-key 123456789E91004D4C5D88CAE21961814AC0EF1B
    
  28. Save the file. Switch back to the CLI Terminal.

  29. Update permissions on your ~/.gnupg Directory:

    chmod 700 ~/.gnupg
  30. Proceed to Configuration (below)

Linux installers

Package installers on Linux have other package names:

  • yum install gnupg2 on CentOS/RHEL
  • dnf install gnupg2 on Fedora
  • apt install gnupg on Debian/Ubuntu

  1. On macOS, install gnupg2 for the gpg program:

    In the script, if each utility is found, it is re-installed if the REINSTALL flag is set on, which it is by default.

    MY_RUNTYPE="upgrade"
     
    if ! command -v gpg >/dev/null; then
       echo "Installing GPG2 for commit signing..."
       brew install gnupg2
       # See https://www.gnupg.org/faq/whats-new-in-2.1.html
    else
       if [[ "${MY_RUNTYPE,,}" == *"upgrade"* ]]; then
          echo "GPG2 upgrading ..."
          gpg --version | grep gpg  # outputs many lines!
          # To avoid response "Error: git not installed" to brew upgrade git
          brew uninstall --ignore-dependencies gpg2
          brew uninstall gnupg2
          # NOTE: This does not remove .gitconfig file entry.
          brew install gnupg2
       fi
    fi
    
  2. Proceed to Configuration

Install Windows GUI

TODO:

  1. Proceed to Configuration

Install CLI on Windows

  1. Install Chocolatey if you havent’s already.

  2. Install with one command using Chocolatey:

    choco install gpg2 gnupg -y

    Alternately, install Gpg4win GUI using Chocolatey:

    choco install gpg4win

  3. Proceed to Configurations (below).


Configure

At your local command line terminal:

  1. Did you configure a user name and email in Git? View using this command:

    git config --list | grep user
    

    Example response:

    user.name=wilsonmar
    user.email=wilsonmar+github@gmail.com
    user.id=WilsonMar+github@gmail.com
    user.username=hotwilson
    user.signingkey=E62CF51CE3E5A4E8
    
  2. You may not want to do this if you’re configuring for multiple organizations. But if you are working with only one GitHub account, if you haven’t already, while in a Terminal with the present working directory at your local repository, configure you valid GitHub user name and email. For example:

    git config --global user.name "John Doe"
    git config --global user.email "john_doe@gmail.com"
    

    IMPORTANT PROTIP: Any name and email can be specified in Git, which means anyone can impersonate someone else to get a malicious commit PR accepted. This is a big reason organizations ask for cryptographically signing commits in GitHub, which requires that the email specified be validated.

Require Signed Commit on GitHub

GitHub Admins repos can require that commits be signed by specifying branch protection rules for all branches, for a specific branch, or for any branch that matches a name pattern matching a fnmatch syntax such as release for branches containing the word “release”.

See https://help.github.com/en/github/administering-a-repository/about-required-commit-signing


Generate and store keys

There are several places you can store GPG keys:

  • On your local drive (which will be lost if your laptop dies or get lost)
  • Keybase cloud (below)
  • On a Yubikey physical device

  • Hashicorp Vault
  • Azure KeyVault?
  • AWS Key Service (AKS)
  • Google Cloud?


Hashicorp Vault

In a Terminal:

  1. Install Hashicorp Vault program on your Mac:

    brew upgrade vault

    If it’s not already installed:

    brew install vault
  2. Confirm viability by displaying the program’s version, such as:

    vault --version
    Vault v1.7.3 ('5d517c864c8f10385bf65627891bc7ef55f5e827+CHANGES')
  3. If you don’t have a Hashicorp Vault server, follow my instructions to run it (for development/experimentation) locally at:

    https://wilsonmar.github.io/hashicorp-vault

  4. In your $HOME folder, create a file named vaultvalues.env.
  5. Grant run access to it:

    chmod +x vaultvalues.env
  6. Use an editor to customize environment variables, starting with the host name and port of your Hashicorp Vault server in VAULT_ADDR:

    # URL of the Hashicorp Vault server:
    export VAULT_ADDR=https://localhost:8200
     
    # The signing backend endpoint (transit or gpg) and optionally hashing function:
    # to use. Mandatory for signing.
    export VAULT_SIGN_PATH=transit/sign/test/sha2-256
    export VAULT_SIGN_PATH=gpg/sign/test/sha2-256
     
    # The verify backend endpoint (transit or gpg). Mandatory for verifying.
    export VAULT_VERIFY_PATH=transit/verify/test
    export VAULT_VERIFY_PATH=gpg/verify/test
     
    # The SNI to present during the TLS handshake (if different from the Vault HTTP
    # host name). Useful when your Vault is exposed through an AWS private link for
    # example. Optional.
    export VAULT_TLS_SERVER_NAME=hostname.to.use.for.sni.com
    
  7. Run the file to load environment variables:

    cd $HOME
    
  8. Navigate into each repo and

    git config --local gpg.program "${VAULT_SIGN_PATH}"
    
  9. Login to Vault:

    # Login to vault:
    vault login  # referencing $VAULT_ADDR
    

Proceed to Sign Git commits and merges (below)

References:

  • https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work
  • https://docs.github.com/en/github/authenticating-to-github/signing-commits
  • https://withblue.ink/2020/05/17/how-and-why-to-sign-git-commits.html
  • https://medium.com/hashicorp-engineering/securing-github-access-with-hashicorp-vault-c25ab8f5d5ea
  • https://github.com/martinbaillie/vaultsign
  • https://oteemo.com/hashicorp-vault-is-overhyped-and-mozilla-sops-with-kms-and-git-is-massively-underrated/

Keybase cloud

The advantage of using the Keybase app to generate GPG keys is that the keys are stored online at keybase.io, where you’ll be able to retrieve your keys when you don’t have your laptop anymore.

The downside is that it’s possible for Keybase.io to be hacked.

PROTIP: Keybase was acquired by Zoom in 2020. Some are concerned that Zoom will stop support of the product because Zoom only wanted the talent and not fund the free product.

VIDEO explains https://github.com/pstadler/keybase-gpg-github

  1. Go to keybase.io and create an account.

    NOTE: Because Keybase asks for verfification of social media accounts, it may be more comforting for repository owners to know that users went through more hoops to obtain and verify each of their accounts, so the account used is less likely to be a fake. Keybase provides value-added services such as adding encryption around direct messages on Twitter. VIDEO: Keybase also works with the pass utility to manage passwords securely (like Vault).

  2. Install the Keybase app to /Applications/Keybase.app:

    brew install --cask keybase
  3. Sign locally out to the Keybase service:

    keybase login

    It takes a few seconds and returns you to the command prompt.

  4. To avoid error message:

    gpg: WARNING: server 'gpg-agent' is older than us (2.2.20 < 2.2.23)
    gpg: Note: Outdated servers may lack important security fixes.
    gpg: Note: Use the command "gpgconf --kill all" to restart them.
    

    do this:

    gpgconf --kill gpg-agent
  5. Import public keys using Keybase:

    keybase pgp export | gpg --import

    Example response:

    gpg: key 938BBBDEB75FEA21: public key "Wilson Mar <wilsonmar+github@gmail.com>" imported
    gpg: Total number processed: 1
    gpg:               imported: 1
    
  6. Get the private key:

    keybase pgp export --secret | gpg --allow-secret-key --import

    If you see this response:

    ▶ ERROR No matching keys found
    gpg: no valid OpenPGP data found.
    gpg: Total number processed: 0
    

  7. Verify progress:

    gpg --list-secret-keys
  8. Generate a GPG keypair:

    keybase pgp gen --multi

    Example prompts and responses:

    Enter your real name, which will be publicly visible in your new key: Patrick Stadler
    Enter a public email address for your key: patrick.stadler@gmail.com
    Enter another email address (or ≪enter> when done):
    Push an encrypted copy of your new secret key to the Keybase.io server? [Y/n] Y
    ▶ INFO PGP User ID: Patrick Stadler <patrick.stadler@gmail.com> [primary]
    ▶ INFO Generating primary key (4096 bits)
    ▶ INFO Generating encryption subkey (4096 bits)
    ▶ INFO Generated new PGP key:
    ▶ INFO   user: Patrick Stadler <patrick.stadler@gmail.com>
    ▶ INFO   4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06
    ▶ INFO Exported new key to the local GPG keychain
    
  9. Skip to List GPG keys (below).


List GPG keys

List keys to verify that you have indeed generated them.

  1. List what keys have been signed, meaning secret keys (more selective than the gpg -k command):

    gpg --list-secret-keys --keyid-format LONG

    --keyid-format LONG requests showing only those keys where both public and private key pair exists. This is becuase both are required to sign commits and tags. If nothing is returned, there are no keys usable for signing.

    PROTIP: This above command can be used often, so added as Bash shell alias (keyboard shortcut) in https://github.com/wilsonmar/git-utilities/blob/master/aliases.sh so that you can instead just type:

    gsk

    In the response, the first line lists the location where keys are stored (with your own user name instead of “wilson_mar”):

    /Users/wilson_mar/.gnupg/pubring.kbx
    ------------------------------------
    

    PROTIP: File pubring.kbx is the Gnupg program’s “Key Ring” file. See https://kb.iu.edu/d/awiu about keyring management commands.

  2. To list all keys:

    gpg --list-keys

    External (GPG Suite) to openpgp.or

    If you’re working on open-source projects, not for Enterprise internal use, you can install the GPG Suite (UI app) or Keybase.io.

    The Suite can be installed as a Homebrew formula brew install --cask gpg-suite (brew install cask gpgtools no longer exists). The GUI app is installed at “/Applications/GPG Keychain.app”. The first time it runs, this pop-up appears:

    git-signing-gpgtools-upload-828x498.png

    Read about it at GPGTools.org and here.

    pinentry for GPG on MacOS

  3. Edit file (if the file doesn’t exist, create it) to add the path.

    code ~/.gnupg/gpg-agent.conf
  4. On MacOS, install a graphical pinentry application:

    brew install pinentry-mac
  5. Verify where the program was install:

    which pinentry-mac

    Response:

    /usr/local/bin/pinentry-mac
  6. Edit file ~/.gnupg/gpg-agent.conf to contain:

    default-cache-ttl 600
    max-cache-ttl 7200
    pinetry-program /usr/local/bin/pinetry-mac
    
  7. If you are not using a Yubikey, proceed to Generate GPG key pairs.

    Optional Yubikey smart chip

    Instead of storing private keys on your laptop’s hard drive (where a hacker can access from any program running on the computer), security-concious people store their private keys in a separate physical smartcard (OpenGPG card) such as a Yubikey device (one of several).

    Day-to-day, it is good for those who work on multiple machines but want to use a single physical signing key they plug into each machine.

    Note the Yubikey was designed to not be able to export private keys (by hackers or you).

    If your laptop’s USB has been locked down, skip this and move on to generate a key.

    git-siging-yubikey-100x100.jpg PROTIP: If you lose your physical dongle, you’ll need to re-generate all keys.

    Also, keys written to a card can only be used in combination with a PIN code, so that even if a YubiKey is stolen, a thief would not be able to authenticate directly.

    Each YubiKey is its own unique cardno.

  8. In Yubikey Setup Docs, identify your Yubikey (I personally have a 5Ci FIPS for use on MacOS USB-C and iPhone USB/Apple Lightning® Interface: OTP):

    https://www.yubico.com/works-with-yubikey/catalog/#protocol=all&usecase=all&key=yubikey-5ci

    Note that these are internet-based SaaS apps rather than local apps (such as 1Password”.

  9. Click on “GitHub” for these instructions to enable a 2FA app (if you haven’t already),

  10. In a Terminal, install software to manage Yubikey (ykman):

    brew install ykman
    brew install yubikey-personalization
    

    Install of yubikey-personalization issues Warning: ykpers 1.20.0 is already installed and up-to-date.

    QUESTION: How to check for vulnerabilities in the above utilities?

  11. Use a text editor to add inside file ~/.gnupg/gpg.conf “no-tty” so it contains:

    auto-key-retrieve
    no-emit-version
    no-tty
    
  12. Insert your YubiKey and run:

    gpg --card-status

    The response expected is like this:

    Reader ...........: Yubico Yubikey 4 OTP U2F CCID
    Application ID ...: D27312341241342342342342343
    Version ..........: 2.0
    Application type .: OpenPGP
    Version ..........: 3.4
    Manufacturer .....: Yubico
    Serial number ....: 12345678
    Name of cardholder: [not set]
    Language prefs ...: [not set]
    Salutation .......: 
    URL of public key : [not set]
    Login data .......: [not set]
    Signature PIN ....: not forced
    Key attributes ...: rsa2048 rsa2048 rsa2048
    Max. PIN lengths .: 127 127 127
    PIN retry counter : 3 0 3
    Signature counter : 0
    KDF setting ......: off
    Signature key ....: [none]
    Encryption key....: [none]
    Authentication key: [none]
    General key info..: [none]
    

    Configure Yubikey

  13. Initiate the configuration program:

    gpg --card-edit

    The prompt appears:

    gpg/card>
    
  14. Initiate the configuration program:

    gpg/card> admin

    “Admin commands allowed” means you can continue.

  15. Generate:

    gpg/card> generate
  16. Type Y to:

    “Make off-card backup of encryption key? (Y/n) Y

    Response:

    PROTIP: Please note that the factory settings of the PINs are
    PIN = '123456'     Admin PIN = '12345678'
    You should change them using the command --change-pin
    
  17. Change the PIN:

  18. Generate for reals:

    gpg/card> generate
  19. Type n to:

    “Make off-card backup of encryption key? (Y/n) n

    BLOG: if you see these messages:

    gpg: selecting openpgp failed: Operation not supported by device
    gpg: OpenPGP card not available: Operation not supported by device   
    
  20. In the pop-up, type PIN “123456”, which is the default pin.

    Response:

    Please specify how long the key should be valid.
          0 = key does not expire
       <n>  = key expires in n days
       <n>w = key expires in n weeks
       <n>m = key expires in n months
       <n>y = key expires in n years
    
    
    
  21. Type “1y” (for 1 year).

    Response is the time/date of expiration, such as:

    Key expires at Wed Jun 22 10:40:38 2022 MDT
  22. Type “y” to “Is this correct? (y/N)”

    Response:

    GnuPG needs to construct a user ID to identify your key.
     
    Real name: 
    
  23. Type your real name, such as “John Doe”.
  24. Type your Email address: johndoe+github@gmail.com
  25. Type Comment:

  26. Type “O” (for OK):

    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
  27. In the pop-up “Please enter the Admin PIN”, which is by default “12345678”, as above.

  28. In the pop-up “Please unlick the card”, type “123456”, the default.

    The response should be a message such as:

    gpg: key A1D1DC27394AD9D0 marked as ultimately trusted
    gpg: revocation certificate stored as '/Users/johndoe/.gnupg/openpgp-revocs.d/056B29F5E7827C95C3A83B3BC1D1DC27394AD9D0.rev'
    public and secret key created and signed.
    
  29. Change the PIN and Admin PIN:

    gpg/card> passwd

    Response:

    gpg: OpenPGP card no. A1234567890103040006162528900000 detected
     
    1 - change PIN
    2 - unblock PIN
    3 - change Admin PIN
    4 - set the Reset Code
    Q - quit
     
    Your selection? _
    
  30. Type 1 to “change PIN”.
  31. In the pop-up “Please enter the PIN”, type the CURRENT 6-character PIN and press OK.
  32. In the pop-up “New PIN”, retype your PIN and press OK.

    Expected response:

    PIN changed.
     
    1 - change PIN
    2 - unblock PIN
    3 - change Admin PIN
    4 - set the Reset Code
    Q - quit
     
    Your selection? _
    
  33. Type 3 to “change Admin PIN”.
  34. In the pop-up “Please enter the Admin PIN”, type the CURRENT 8-character PIN and press OK.
  35. In the pop-up “New Admin PIN”, retype your PIN and press OK.

    Expected response:

    PIN changed.
     
    1 - change PIN
    2 - unblock PIN
    3 - change Admin PIN
    4 - set the Reset Code
    Q - quit
     
    Your selection? _
    
  36. Type Q to quit out of passwd mode.

  37. List the configuration:

    gpg/card> list
    General key info..: 
    pub  rsa2048/A1D1DC27394AD9D0 2021-06-22 John Doe <johndoe+github@gmail.com>
    sec>  rsa2048/A1D1DC27394AD9D0  created: 2021-06-22  expires: 2022-06-22
                                 card-no: 0006 16252890
    ssb>  rsa2048/123D8F06797B4CD8  created: 2021-06-22  expires: 2022-06-22
                                 card-no: 0006 16252890
    ssb>  rsa2048/12329BE82896FF01  created: 2021-06-22  expires: 2022-06-22
                                 card-no: 0006 16252890
    

    Two “ssb” (sub keys) are generated by the YubiKey 5 FIPS Series keys (one for each level of FIPS certification (FIPS 140-2 Level 1 and FIPS 140-2 Level 2). Both certificates apply to the same keys.

  38. Tell Git the signing key to use, using the key from the previous command (above):

    git config --global user.signingkey=A1D1DC27394AD9D0
  39. Verify the signingkey within the [user] section:

    cat .git/config
  40. Type “quit” to quit out of the program.

    Sub-keys are listed:

    sub   rsa2048 2021-06-22 [A] [expires: 2022-06-22]
    sub   rsa2048 2021-06-22 [E] [expires: 2022-06-22]
    
  41. If you lose your Yubikey, use your Master Key to certify a new signing key, then paste a new public key into GitHub.

    References on Yubikey on macOS Git:

    • https://support.yubico.com/hc/en-us/articles/360013790219-Getting-Started-with-the-YubiKey-on-macOS
    • https://github.com/drduh/YubiKey-Guide
    • https://www.isi.edu/~calvin/yubikeyssh.htm
    • https://hugotunius.se/2018/07/13/yubikey-ssh-authentication.html - 13 Jul 2018
    • https://raymondcheng.net/projects/2018/11/25/git-yubikey.html
    • https://evilmartians.com/chronicles/stick-with-security-yubikey-ssh-gnupg-macos

Install GitKraken app and sign

Git UI clients such as GitKraken can generate GPG keys with its UI.

GitKraken provides a GUI for signing.


Generate GPG key pairs

On a macOS Terminal:

Gen GPG on macOS

PROTIP: In highly secure organizations, keys are generated by a security department and provided to workers.

  1. Generate another key:

    gpg --gen-key

    --generate-key is the long form of the parameter.

    The response:

    gpg (GnuPG/MacGPG2) 2.2.24; Copyright (C) 2020 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
     
    Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
     
    GnuPG needs to construct a user ID to identify your key.
     
    Real name:
    
  2. Enter in the series of prompts:

    Real Name: John Doe
    Email address: john-doe+github@gmail.com
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? _
    

    PRITIP: If you want to use different email addresses on different projects, generate one GPG key for each email address.

  3. Type “O” (capital or lowercase O) to save the entry.

  4. In response to “Please enter the passphrase to protect your new key”:

    git-signed-pass-form

    PROTIP: Save you Passphrase in a secure place (such as in Hashicorp Vault), then copy it to paste in the prompt. This tactic is to ensure that you really can retrieve it when you use the key in a future command.

    REMEMBER: Don’t reuse passwords and passphrases.

  5. Re-enter the key.

  6. Press Enter. Sample long-winded response:

    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    gpg: key 62C414BA89BFBE52 marked as ultimately trusted
    gpg: directory '/Users/wilson_mar/.gnupg/openpgp-revocs.d' created
    gpg: revocation certificate stored as '/Users/wilson_mar/.gnupg/openpgp-revocs.d/0BB29E3C5216420CC50ACF8D62C414BA89BFBE52.rev'
    public and secret key created and signed.
     
    pub   rsa2048 2020-03-01 [SC] [expires: 2022-03-01]
       0BB29E3C5216420CC50ACF8D62C414BA89BFBE52
    uid                      Wilson Mar <john_doe+github@gmail.com>
    sub   rsa2048 2020-03-01 [E] [expires: 2022-03-01]
    

    WARNING: Notice the expiry period is two years from date of creation.

    “rsa2048” is the encryption algorithm used.

    List GPG Keys

  7. List keys to obtain a KeyID:

    gpg --list-secret-keys --keyid-format LONG

    Parse the RESPONSE:

    gpg: checking the trustdb
    gpg: marginals needed: 3  completes needed: 1  trust model: pgp
    gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
    gpg: next trustdb check due at 2022-03-01
    /Users/wilson_mar/.gnupg/pubring.kbx
    ------------------------------------
    sec   rsa2048/62C414BA89BFBE52 2020-03-01 [SC] [expires: 2022-03-01]
       0BB29E3C5216420CC50ACF8D62C414BA89BFBE52
    uid                 [ultimate] John Doe <john_doe+github@gmail.com>
    ssb   rsa2048/7F2026C2A22F2B37 2020-03-01 [E] [expires: 2022-03-01]
    

    NOTE: Only the “[ultimate]” key is used. Ignore the ones marke “[ revoked]”.

  8. Manually highlight and copy the GPG key ID, which is after “rsa2048/” in the sec section, 62C414BA89BFBE52 in the sample above.

    Alternately, use these Bash script lines to parse the key automatically:

    RESPONSE=$( gpg --list-secret-keys --keyid-format LONG | grep sec )
    # secLine="sec rsa2048/62C414BA89BFBE52 2020-03-01 [SC] [expires: 2022-03-01]"
    GPGKeyID=$( echo ${RESPONSE##*/} | cut -d " " -f 1 )
    echo $GPGKeyID
    
  9. To set your GPG signing key in Git, construct a command by substituting the GPG key ID you’d like to use with the value of $GPGKeyID:

    git config --global user.signingkey 62C414BA89BFBE52  #

    No response is expected from the command.

    The command updated the config file within the repo’s .git folder.

  10. Skip to section “Copy Paste GitHub” (below).

    OPTIONAL: Edit GPG key

    In case you want to fix a typo:

  11. Associate an email (value for field uid) with your GPG key, which Git requires by entering the edit-key mode:

    gpg --edit-key 62C414BA89BFBE52

    This results in this prompt:

    gpg>
  12. Specify “adduid” to enter that mode:

    gpg> adduid
  13. Enter in the series of prompts:

    Real Name: John Doe
    Email address: john-doe+github@gmail.com
    Comment: My Git signing key
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
    

    The response is like:

    You selected this USER-ID: 
     "John Doe (My Git signing key) <john_doe+github@gmail.com>"
    
  14. Type “O” (capital or lowercase O) to save the entry.

    Copy and Paste in GitHub

  15. Prepare for pasting of the key generated in this next step by switching to an internet browser of the GitHub page that will receive the public key. After signing in, click your icon at the upper-right, select Settings, SSH and GPG keys:

    https://github.com/settings/keys

  16. Click “New GPG key” for a form to accept the contents of the public GPG key, then press command+Tab to switch back to the Terminal.

  17. Navigate to your .ssh folder:

    cd & cd .ssh
  18. Print the public GPG key, in ASCII armor format so that they can be sent in a standard messaging format such as email. (Otherwise, the output is in binary format).

    gpg --armor --export 62C414BA89BFBE52 >$HOME/mygitsigning.pub

    PROTIP: Redirecting the command output to a file makes it easier and less error-prone than manually highlighting and copying.

  19. Copy the file’s contents to your operating system Clipboard:

    pbcopy < "$HOME/mygitsigning.pub"

    On Windows, pipe file contents to the clip.exe program built in within C:\Windows\system32 *:

    type mygitsigning.pub | clip

    Alternately, open the file using a text editor, select all file contents, and copy to Clipboard.

    The public key contents should include markers “—–BEGIN PGP PUBLIC KEY BLOCK—–” and “—–END PGP PUBLIC KEY BLOCK—–”.

  20. Switch to the GitHub page opened and click on the input field (so the field border turns blue), then press command+V to paste. Click “Add GPG key”.

    PROTIP: IMPORTANT: If you lost your laptop, immediately remove the SSH and GPG keys associated with that laptop.

  21. Check “Flag unsigned commits as unverified” under the “Vigilent Mode” heading:

    github-vigilent-mode-1224322

    Signing Key

  22. Configure Git to use the program for signing:

    git config --global gpg.program gpg
    
  23. Configure Git to use your chosen key for signing (“0A46826A” in the example here):

    git config --global user.signingkey 62C414BA89BFBE52
    
  24. Configure Git to auto-sign ALL Git Tags (called annotations by Git):

    git config --global tag.forceSignAnnotated true
    

    Sign all commits

    PROTIP: Many say it’s not necessary to sign every commit, just the commit designated by a release.

  25. Configure Git to auto-sign ALL commits on ALL repos:

    git config --global commit.gpgsign true
    

    PROTIP: It takes a little more time to sign commits.

  26. Each command above adds an entry in file $HOME/.gitconfig created by the Git client:

    [user]
     name = John Doe
     email = john_doe+github@gmail.com
     signingkey = 62C414BA89BFBE52
    [gpg]
     program = gpg2
    

    git config –global gpg.program gpg2

  27. If you are using Bash, edit you ~/.bash_profile to avoid these error messages:

    error: gpg failed to sign the data
    fatal: failed to write commit object
    

    If using Zsh, edit your ~/.bashrc file.

    Add lines to the bottom of the Shell invocation file:

    test -r ~/.bash_profile && echo 'export GPG_TTY=$(tty)' >> ~/.bash_profile
    echo 'export GPG_TTY=$(tty)' >> ~/.profile
    

    GPG_TTY variable is to avoid errors.

    If using Zsh:

    echo 'export GPG_TTY=$(tty)' >> ~/.profile
    
  28. Confirm:

    echo $GPG_TTY
    

    Your number could be different in this example:

    /dev/ttys001
    
  29. Activate the setting by restarting your Terminal session. If using Bash:

    source ~/.bash_profile
    

    If using Zsh:

    source ~/.bashrc
    

Sign Git Commits & merges

  1. git clone a repo, then edit some file.

  2. Configure for the repo (and each additional repo) the private “no reply” email from above so your email is not exposed publicly:

    git config user.email "12345678+johndoe@users.noreply.github.com"
    
  3. Add the files changed:

    git add .

    This is not recommended by some, but …

  4. To sign a commit, if you didn’t specify signing every time, add command flag capital -S, construct a command replacing “Some message” in the command with your own message:

    GIT_TRACE=1 git commit -a -S -m "Some message"

    A sample response at time of writing:

    03:48:07.999728 exec-cmd.c:139          trace: resolved executable path from Darwin stack: /Library/Developer/CommandLineTools/usr/bin/git
    03:48:08.000435 exec-cmd.c:236          trace: resolved executable dir: /Library/Developer/CommandLineTools/usr/bin
    03:48:08.001587 git.c:418               trace: built-in: git commit -a -S -m 'Some message'
    03:48:08.017126 run-command.c:643       trace: run_command: gpg2 --status-fd=2 -bsau 62C414BA89BFBE52
    03:48:08.153175 run-command.c:643       trace: run_command: git gc --auto
    03:48:08.156446 exec-cmd.c:139          trace: resolved executable path from Darwin stack: /Library/Developer/CommandLineTools/usr/libexec/git-core/git
    03:48:08.157243 exec-cmd.c:236          trace: resolved executable dir: /Library/Developer/CommandLineTools/usr/libexec/git-core
    03:48:08.158689 git.c:418               trace: built-in: git gc --auto
    [master 71ad705] Some message
     1 file changed, 1 insertion(+)
    

    Alternately,

    git commit --amend --no-edit --signoff
  5. After push, switch to an internet browser to see a verified badge next to your commits on GitHub online.

    git-signing-ale-413x262

  6. Verify that green checkmark next to your name on GitHub.

    ???

View Signed Git Log

  1. See signing info with your latest commit in the git log:

    git log --show-signature -1

    The response would include, for example:

    commit 71ad7059817e609b52b29469e1214a56799b33ef (HEAD -> master)
    gpg: Signature made Mon Mar  2 11:07:39 2020 EST
    gpg:                using RSA key 0BB29E3C5216420CC50ACF8D62C414BA89BFBE51
    gpg: Good signature from "John Doe <john_doe+github@gmail.com>" [ultimate]
    Author: John Doe <johndoe+github@gmail.com>
    Date:   Sun Jun 20 22:54:17 2021 -0600
    
  2. To verify signatures during a git merge (and abort if signatures are not verifiable):

    git merge --verifya-signatures other_branch

Sign Git Tags

VIDEO: Git tags are committed and pushed by an additional command.

  1. Construct a command to create a Git tag (such as “v1.5.2”) to the current HEAD:

    GIT_TRACE=1 git tag -a -s v1.5.2 -m 'Signed tag 1.5.2'

    -a (annotation) puts the tag in the repository when pushed to GitHub.

    PROTIP: Git tags are like a branch name. in Semantic Versionioning format. See semver.com.

    GIT_TRACE=1 enables tracing. Example output on macOS:

    03:45:46.646487 exec-cmd.c:139          trace: resolved executable path from Darwin stack: /Library/Developer/CommandLineTools/usr/bin/git
    03:45:46.647227 exec-cmd.c:236          trace: resolved executable dir: /Library/Developer/CommandLineTools/usr/bin
    03:45:46.647782 git.c:418               trace: built-in: git tag -a -s v1.5.2 -m 'Signed tag 1.5.2'
    03:45:46.650392 run-command.c:643       trace: run_command: gpg2 --status-fd=2 -bsau 62C414BA89BFBE52
    

    You are prompted for the GPG key Passphrase.

    Alternately, construct a command to create a Git tag (such as “v1.5.2”) to a previous commit SHA (such as “f3c9f3a”):

    GIT_TRACE-1 git tag v1.5.2 f3c9f3a

    List Git tags

  2. For a list of all version 1 tags:

    git tag -l "v1.*"

    Silencing

    I don’t recommend this, but theoretically you can silence the “you need a Passphrase” prompt by adding in file ~/.gnupg/gpg.conf “batch”. But

    # Connects gpg-agent to the OSX keychain via the brew-installed
    # pinentry program from GPGtools. This is the OSX 'magic sauce',
    # allowing the gpg key's passphrase to be stored in the login
    # keychain, enabling automatic key signing.
    pinentry-program /usr/local/bin/pinentry-mac   
    

    Push by Tag

    PROTIP: REMEMBER: Tags are push of tags are in addition to content commits.

  3. For convenience (in scripts), push all tags to GitHub:

    git push --tags

    Alternately, specify the new Tag like a branch:

    git push origin v1.5.2

    A sample response:

    Enumerating objects: 1, done.
    Counting objects: 100% (1/1), done.
    Writing objects: 100% (1/1), 540 bytes | 540.00 KiB/s, done.
    Total 1 (delta 0), reused 0 (delta 0)
    To github.com:wilsonmar/git-utilities
            * [new tag]         v1.5.2 -> v1.5.2
    
  4. See Tags in GitHub under the Code tab, after clicking the release link above GitHub’s colorful line:

    https://github.com/wilsonmar/git-utilities/releases


Delete Tags

Git tags such as “v1.5.2” are meant to be permanently associated with a particular commit through history.

  1. To delete a Tag locally:

    git tag -d v1.5.2

    Alternately, –delete is the long form of the -d parameter.

    Multiple tags can be specified in one command (separated by spaces).

  2. To delete a Tag in remote (GitHub):

    git push origin -d v1.5.2

    Alternately, the really short form replaces -d with a colon (:):

    git push origin :v1.5.2

    Tags in CI/CD

  3. View the list of tags with their full (40 character) hash using the git show-ref command:

    git show-ref --tags
    

    PROTIP: The above command was added as Bash shell alias (keyboard shortcut) in https://github.com/wilsonmar/git-utilities/blob/master/aliases.sh so that you can instead just type:

    gst
    

    The response is a list of full hashes with the path, such as:

    d4c1e33d1969c8b35938db498a556de25b8c3aa3 refs/tags/v1.5.2
  4. VIDEO: In CI/CD such as Jenkins, get the first among latest tags using the git ref-list command:

    COMMIT_ID=$( git rev-list --tags --date-order | head -1 )
    

    The response is simply a full hash, such as:

    d4c1e33d1969c8b35938db498a556de25b8c3aa3
  5. Extract the Tag based on the hash using the git show-ref command:

    TAG=$( git show-ref --tags | grep "${COMMIT_ID}" | awk -F / '{print $NF}' )
    

    The variable is used to specify the version in a Docker Build, Push, then Kubernetes apply, such as:

    docker build -t "$DOCKER_ACCOUNT/$DOCKER_REPO:$TAG" .
    docker push "$DOCKER_ACCOUNT/$DOCKER_REPO:$TAG"
    sed -e "s/VERSION/$TAG/" /home/centos/deployment.yml >/tmp/deployment.yml
    kubectl apply -f /tmp/deployment.yml
    kubectl get pods -o wide
    

BONUS: Encrypting whole files using GPG

GPG can also be used for encryption and decryption of whole files, such as an executable (.exe) file for transmission over email, etc (not related to Git).

There are several ways to verify both the integrity of a file during transmission (as hashing can do) but also provide a way for users to trace authorship.

The steps below describes work with a detached signature where a signature is created in a separate file. We can then provide both the package and the signature file from a trusted source. The user can then verify the package against it. This is like with a hash, but instead of a cleartext signature, the signature is in a “.sig” file which has been encrypted using a private key known only to the file’s owner.

BLOG: Users may want this level of verification for security reasons. Especially if the package handles sensitive information.

  1. Navigate to the folder where the file to be encrypted is located. For example:

    cd ~/.aws
  2. Get the signature, such as “62C414BA89BFBE52”.

    gpg --list-secret-keys --keyid-format LONG
  3. Copy the signing key marked “[ultimate]” and not “[revoked]”, such as “62C414BA89BFBE52” in this sample response:

    sec   rsa2048/62C414BA89BFBE52 2020-03-01 [SC] [expires: 2022-03-01]
       0BB29E3C5216420CC50ACF8D62C414BA89BFBE52
    uid                 [ultimate] John Doe <john_doe+github@gmail.com>
    
  4. Plug in your Yubikey if the command response above has a line like this:

        Card serial no. = 0006 16252890
  5. Construct a variable by typing definitions of values to be used in commands:

    SIGNING="62C414BA89BFBE52"
    ENCRYPTED_FILE="credentials.gpg"
    SOURCE_FILE="credentials"

    PROTIP: Defining variables allows copy and paste of the complex command below, easier than constructing it piecemeal. This also eliminates typos when the same values are specified in several commands.

  6. Construct a command to create a signed file by triple-clicking this command to copy to Clipboard the command to encrypt file “credentials” and output file “credentials.gpg”:

    gpg --detach-sign --sign-with "$SIGNING" -o "${ENCRYPTED_FILE}"  "${SOURCE_FILE}"
    

    --detach-sign requests a detached signature to be generated.

    --sign-with precedes the GPG key id to be used to perform signing.

    -o specifies the output file. Traditionally we use either a .sig or a .gpg extension.

  7. If you configured a Yubikey, a pop-up is presented:

    git-signing-insert-card-1076x320

    Insert your Yubikey and enter its PIN code.

  8. Verify that files were generated:

    ls -al "$ENCRYPTED_FILE"
    

Standard signing

Standard signing and clear signing both create ciphertext from the cleartext input file:

  • Standard signing is used with encryption.
  • Clear signing wraps the input with a plaintext signature.

  1. To sign a plaintext file with your secret key:

    gpg -s textfile
  2. To encrypt a plain text file with the user_id of the recipient’s public key:

    gpg -e -r recipient_userid textfile
  3. To sign a plaintext file with your secret key and have the output readable to people without running GPG first:

    gpg --clearsign textfile
  4. To sign a plaintext file with your secret key, and then encrypt it with the recipient’s public key:

    gpg -se -r recipient_userid
  5. To decrypt a ciphertext file to a clear text outputfile, also checking the signature integrity of a signed file:

    gpg -o outputfile ciphertextfile

Getting Facebook to encrypt notification emails

In 2015, Facebook introduced an option to it to encrypt notification emails – account recovery emails, in particular. It’s done by you (the user) adding your OpenPGP public key to your Facebook profile.

  1. Generate your public and private keys.
  2. Copy and paste the text block of your PGP public key, starting with: —–BEGIN PGP PUBLIC KEY BLOCK—– and including —–END PGP PUBLIC KEY BLOCK—– at the end. (On a Mac, I exported my public key as a plain-text ASC file from the GPG Keychain application that I was then able to open in TextEdit to copy the text block mentioned above.)

  3. In Facebook, login and navigate to your About page, “Contact and Basic Info” section:

    https://www.facebook.com/me/about?section=contact-info

  4. Click “Add a public key”.
  5. Paste.
  6. Check box “Use this public key to encrypt notification emails that Facebook sends you”.
  7. Click “Save Changes”.
  8. In your email program, decrypt the email from Facebook and click the link.


Resources

This article was the result of consulting several sources of information:

As with all things Git, the canonical documentation is at git-scm. Regarding Git signing: https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work

https://help.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key

https://help.github.com/en/enterprise/2.17/user/github/authenticating-to-github/signing-commits

Explanation of gpg program parameters are at: https://www.gnupg.org/documentation/manuals/gnupg/GPG-Input-and-Output.html

Protect Your Git Repositories From Commit Forgery Using Signing

https://confluence.atlassian.com/bitbucketserver/using-gpg-keys-913477014.html

VIDEO: [Git/GitHub] Signing your commits in GitHub – Getting the verified badge on your commits by Raveesh Agarwal

https://stackoverflow.com/questions/39494631/gpg-failed-to-sign-the-data-fatal-failed-to-write-commit-object-git-2-10-0

https://juliansimioni.com/blog/troubleshooting-gpg-git-commit-signing quotes https://wiki.gentoo.org/wiki/GnuPG#Changing_pinentry_for_SSH_logins

https://ice-blog.readthedocs.io/en/latest/tutorial/encrypt/gpg

https://jigarius.com/blog/signing-git-commits

https://gist.github.com/troyfontaine/18c9146295168ee9ca2b30c00bd1b41e

VIDEO: [Git/GitHub] Signing your commits in GitHub – Getting the verified badge on your commits</a>

A Git Horror Story: repository integrity with signed commits

https://www.thegeekyway.com/hands-on-guide-on-gpg-keys/ by GeekyShacklebolt

http://varrette.gforge.uni.lu/blog/2017/03/14/tutorial-gpg-gnu-privacy-guard/

More on DevOps

This is one of a series on DevOps:

  1. DevOps_2.0
  2. ci-cd (Continuous Integration and Continuous Delivery)
  3. User Stories for DevOps
  4. Enterprise Software)

  5. Git and GitHub vs File Archival
  6. Git Commands and Statuses
  7. Git Commit, Tag, Push
  8. Git Utilities
  9. Data Security GitHub
  10. GitHub API
  11. TFS vs. GitHub

  12. Choices for DevOps Technologies
  13. Pulumi Infrastructure as Code (IaC)
  14. Java DevOps Workflow
  15. Okta for SSO & MFA

  16. AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
  17. AWS server deployment options
  18. AWS Load Balancers

  19. Cloud services comparisons (across vendors)
  20. Cloud regions (across vendors)
  21. AWS Virtual Private Cloud

  22. Azure Cloud Onramp (Subscriptions, Portal GUI, CLI)
  23. Azure Certifications
  24. Azure Cloud

  25. Azure Cloud Powershell
  26. Bash Windows using Microsoft’s WSL (Windows Subsystem for Linux)
  27. Azure KSQL (Kusto Query Language) for Azure Monitor, etc.

  28. Azure Networking
  29. Azure Storage
  30. Azure Compute
  31. Azure Monitoring

  32. Digital Ocean
  33. Cloud Foundry

  34. Packer automation to build Vagrant images
  35. Terraform multi-cloud provisioning automation
  36. Hashicorp Vault and Consul to generate and hold secrets

  37. Powershell Ecosystem
  38. Powershell on MacOS
  39. Powershell Desired System Configuration

  40. Jenkins Server Setup
  41. Jenkins Plug-ins
  42. Jenkins Freestyle jobs
  43. Jenkins2 Pipeline jobs using Groovy code in Jenkinsfile

  44. Docker (Glossary, Ecosystem, Certification)
  45. Make Makefile for Docker
  46. Docker Setup and run Bash shell script
  47. Bash coding
  48. Docker Setup
  49. Dockerize apps
  50. Docker Registry

  51. Maven on MacOSX

  52. Ansible

  53. MySQL Setup

  54. SonarQube & SonarSource static code scan

  55. API Management Microsoft
  56. API Management Amazon

  57. Scenarios for load
  58. Chaos Engineering

More on Security

This is one of a series on Security in DevSecOps:

  1. Git Signing
  2. Hashicorp Vault

  3. WebGoat known insecure PHP app and vulnerability scanners
  4. Test for OWASP using ZAP on the Broken Web App

  5. Encrypt all the things

  6. AWS Security (certification exam)
  7. AWS IAM (Identity and Access Management)

  8. Cyber Security
  9. Security certifications