A Trusted Git

Development

Work-flow

Overview

  • Basic Understanding and Value
    • Client
    • Project Manager
    • Developers
  • (Drupal) Configuration Management
  • (GPG) GNU Privacy Guard
  • Git
  • GitHub/Lab

Opinionated

  • Burtronix' Current Way
  • Yours Will Differ

Understanding & Value

  • Configuration Management
      with Drupal
  • Version Control
      with Git
  • Trusted Contribution Chain
      with GPG
  • Collaboration
      with GitHub/Lab

Client / Project Owner

  • Configuration Management with Drupal
    • Fast staging
  • Version Control with Git
    • Reliable
    • History
    • Low/no vendor lock-in
  • Trusted Contribution Chain with GPG
    • Trusted contribution chain
  • Collaboration with GitHub/Lab
    • Visibility and Overview

Understanding & Value

Developer

  • (Drupal) Configuration Management
  • (GPG) GNU Privacy Guard
  • Git
  • GitHub/Lab

(Drupal)
Configuration Management

  • Features
    • Origin
    • Configuration vs Content
    • The Rub
    • Collection for CM vs Features
  • Drupal 8

Developer

GPG

  • PGP, GPG, GNU
  • Not Privacy of Identity but:
    • Trusted Identity
    • Trusted Communication
  • Keys and Sub-Keys
    • Old View
    • Certificates
    • Authentication
    • Encryption
    • Signing

GPG

  • Trusted Identity
    • Web of Trust
      • Teams (of developers)
      • Others (Signing Parties)
      • Levels of Trust
    • Biglumber and keybase.io
  • Modern, Stable and Classic
  • Configure Well
  • Keep Offline, Apart and Secure
    • Master Signing Key
    • Revocation Certificate

Configuration 1/4

GPG

#------------------------------------------------------------------------------#
# Default Key                                                                  #
#------------------------------------------------------------------------------#

# The default key to sign with.
#
# If this option is not used, the default key is the first key found in the
# secret keyring.

default-key E615 5DBC DBDE C60F 7B48  A894 A830 D565 2D87 ED9A

Configuration 2/4

GPG

#------------------------------------------------------------------------------#
# Keyserver                                                                    #
#------------------------------------------------------------------------------#

keyserver hkps://hkps.pool.sks-keyservers.net

keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/sks-keyservers.netCA.pem

keyserver-options no-honor-keyserver-url
keyserver-options include-revoked

keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050
keyserver-options no-try-dns-srv

Configuration 3/4

GPG

#------------------------------------------------------------------------------#
# Algorithm and Ciphers                                                        #
#------------------------------------------------------------------------------#

personal-cipher-preferences AES256
personal-digest-preferences SHA512
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

Configuration 4/4

GPG

#------------------------------------------------------------------------------#
# Behaviour                                                                    #
#------------------------------------------------------------------------------#

no-emit-version
no-comments
no-greeting
keyid-format 0xlong
with-fingerprint

list-options show-uid-validity
verify-options show-uid-validity

use-agent

Usage: Encrypt

GPG

$ echo 'Hey Guys, the password: '$(pwgen -s 20 1) > content.txt

$ gpg -r daniel -r greg --armor --encrypt content.txt

$ cat content.txt.asc
-----BEGIN PGP MESSAGE-----

hQIMAzhUD5gJJ4taARAAiU1NtItiqCcda387YWlKDwWNrO6my5lBzSB6zBCPW3zr
8zUcU7zGOYzIhFPvMnyhcXHRvGZkKFqW9YPPwbtxziVO3AL8L81lbkhEK0qeA3jb
nSJjtvcDtAC/0MUmPf64S79+XapUJdiIkTB1cQKziA2gbom3+uwBsWxyuWqg2Zdd
...
M6fek/+Ykmga0v/RVomMFk/CRADICpcHV4M+uZ67ltWTVw8u6jxeFa7dGLl6b9J1
AW7vbNiXeLn9/Hpm99NrsJ1I9dvoX7yOfg4skAMP2Rm/eoR+X0CP+L+sTz1j18kx
Ph6n2G4ukdUeDHrwWLoaXGe+LcjfDr2lvZHtYp6nkhDCjYhvHPzY7c8N/bQlDpRG
lYj9cnGwm2d2Godcytn4AIdyBICW
=L2Uw
-----END PGP MESSAGE-----
$ gpg -d content.txt.asc

Usage: Sign (Trust)

GPG

$ echo 'Hey Guys, Do not Launch the Space Ship without Me!' > order.txt

$ gpg --clearsign order.txt

$ cat order.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Hey Guys, Do not Launch the Space Ship without Me!
-----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJY/KJ2AAoJEPKv9lRJpdu44zEQAJOeYoGCxSc9jT7r/fKO49Ua
4z76xBwUTOnr3gcY5M3qijUiBUom2tR5fg1bqHfPdw5dUG4QjtZIHY6zs8Xo7baq
oI27ztHVj9FMQAqWgxrGaVru+n2aHY8BR5AvRqUWVYie0DmlnYbrFWEX0WReDAKX
...
Vw5kPjLepBU0Pwff563fsXk+nR+s7xUM9wmmyd5AJE+h/UICPhShe18QEEd4wM0s
Hxz3uQ7XNhdOBoRvoaQjbSBAQcSPSK+FR8uH2mEGoJoC12O8nH+Sqy7G8EKIo0jN
j+idbNm1r5HTW6/PlAU+
=7RvD
-----END PGP SIGNATURE-----

Init

$ touch {a,b,c}-file.txt
$ ls -1A
a-file.txt
b-file.txt
c-file.txt
$ git init
Initialized empty Git repository in /home/riaan/talk/.git/
$ ls -1A
a-file.txt
b-file.txt
c-file.txt
.git

Some basic files to work with:

Start using git:

Git Basics (Quick)

Staging & Commit

$ gs
# On branch: master  |  [*] => $e*
#
➤ Untracked files
#
#      untracked: [1] a-file.txt 
#      untracked: [2] b-file.txt 
#      untracked: [3] c-file.txt

Git Status

Git Basics (Quick)

$ ga *
# Added 'a-file.txt'
# Added 'b-file.txt'
# Added 'c-file.txt'
#
# On branch: master  |  [*] => $e*
#
➤ Changes to be committed
#
#       new file: [1] a-file.txt 
#       new file: [2] b-file.txt 
#       new file: [3] c-file.txt

Add to Stage

$ git commit -S -m 'Initial commit.'

You need a passphrase to unlock the secret key for
user: "Andries Petrus Burger <riaan.burger@burtronix.com>"
4096-bit RSA key, ID 0xF2AFF65449A5DBB8, created 2015-11-01
         (subkey on main key ID 0xA830D5652D87ED9A)

[master (root-commit) 995e108] Initial commit.
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a-file.txt
 create mode 100644 b-file.txt
 create mode 100644 c-file.txt

Commit

  • scm_breeze
  • scmpuff
  • Aliases
    • Ctrl-x Space
  • -S

Inside ./.git

$ ls -1A ./.git/
branches
config
description
HEAD
hooks
info
objects
refs
$ cat ./.git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true

./.git/config (more later)

Git Basics (Quick)

  • Hashed-based store of all previously committed files
  • Not diffs
  • Config and Metadata

~/.gitconfig

$ grep . ~/.gitconfig
[user]
  name        = Riaan Burger
  email       = riaan.burger@burtronix.com
  signingkey  = E615 5DBC DBDE C60F 7B48  A894 A830 D565 2D87 ED9A
[push]
  default     = simple
[core]
  editor      = vim
[merge]
  ff          = false
  tool        = meld
[diff]
  tool        = meld
  guitool     = meld
[difftool]
  prompt      = false
[commit]
  gpgsign     = true

Git Basics (Quick)

GitHub / GitLab

  • Shared Development (Teams)
  • Remote
    • Other People's Computers
    • Self Hosting
  • Project Management
  • Automation

(Quick)

Intermission

Branches

Git Basics (Quick)

± gb
* [1] master
± git checkout -b feature1
Switched to a new branch 'feature1'
± gb
* [1] feature1
  [2] master
± gco 2
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
± ga a-file.txt  && git commit -S -m 'Feaure change.'
...
1 file changed, 1 insertion(+)
± git merge -S feature1
Merge made by the 'recursive' strategy.
 a-file.txt | 1 +
 1 file changed, 1 insertion(+)
± gl
*   d9ce43f - (HEAD, master) Merge branch 'feature1' (12 seconds ago) <Riaan Burger>
|\  
| * 4f6ecb5 - (feature1) Feaure change. (6 minutes ago) <Riaan Burger>
|/  
* 995e108 - (origin/master) Initial commit. (22 hours ago) <Riaan Burger>
± git log --pretty="format:%ai %h %G? %aN  %s" -n10
2017-04-24 20:57:24 +0200 d9ce43f G Riaan Burger  Merge branch 'feature1'
2017-04-24 20:52:05 +0200 4f6ecb5 G Riaan Burger  Feaure change.
2017-04-23 23:10:42 +0200 995e108 G Riaan Burger  Initial commit.
± echo 'Feature change.' > a-file.txt

Remotes 1

Git Basics (Quick)

± git remote add origin git@github.com:Burtronix/talk.git
± git push -u origin master
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 866 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:Burtronix/talk.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
± gr
origin	git@github.com:Burtronix/talk.git (fetch)
origin	git@github.com:Burtronix/talk.git (push)

Pushed branch master to remote origin

Forks (GitHub & GitLab)

Git Basics (Quick)

Clone (fork)

Git Basics (Quick)

$ gcl git@github.com:RiaanBurger/talk.git && cd test
Cloning into 'talk'...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 7 (delta 1), reused 6 (delta 0), pack-reused 0
Receiving objects: 100% (7/7), done.
Resolving deltas: 100% (1/1), done.
Checking connectivity... done.
± gb
* [1] master
± gr
origin	git@github.com:RiaanBurger/talk.git (fetch)
origin	git@github.com:RiaanBurger/talk.git (push)

Remote (upstream fork)

Git Basics (Quick)

± git remote add upstream git@github.com:Burtronix/talk.git
± gr
origin	git@github.com:RiaanBurger/talk.git (fetch)
origin	git@github.com:RiaanBurger/talk.git (push)
upstream	git@github.com:Burtronix/talk.git (fetch)
upstream	git@github.com:Burtronix/talk.git (push)

./.git/config

Git Basics (Quick)

± cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = git@github.com:RiaanBurger/talk.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
[remote "upstream"]
	url = git@github.com:Burtronix/talk.git
	fetch = +refs/heads/*:refs/remotes/upstream/*

Push a Change

Git Basics (Quick)

± cat .git/config

Merge Request

Git Basics (Quick)

Done With Basics

;-)

!Pull

Git Merge and Trust

  • Don't pull (learn more first)
  • Pull is fetch and merge

Change & Push
(to Fork)

Git Merge and Trust

± ga b-file.txt  && git commit -S -m 'Change.'
...
1 file changed, 1 insertion(+)
± echo 'Change.' > b-file.txt
± gps
...
To git@github.com:RiaanBurger/talk.git
   d9ce43f..c307d0d  master -> master

Same as:

± git push origin master

Merge Request

Git Merge and Trust

  • Do not merge on GitHub
  • Remember, merge is a fetch and commit
  • GitHub cannot sign on your behalf

Merge 1/6

Git Merge and Trust

On merge review desktop,

temporary review branch:

± git checkout -b RiaanBurger-master-$(date +%F-%H-%M-%S) master
Switched to a new branch 'RiaanBurger-master-2017-04-24-23-39-17'

Fetch from developer's fork:

± git fetch git@github.com:RiaanBurger/talk.git
...
From github.com:RiaanBurger/talk
 * branch            HEAD       -> FETCH_HEAD

Merge 2/6

Git Merge and Trust

Log

± git log FETCH_HEAD --pretty="format:%ai %h %G? %aN  %s" 
2017-04-24 23:09:50 +0200 c307d0d G Riaan Burger  Change.
2017-04-24 20:57:24 +0200 d9ce43f G Riaan Burger  Merge branch 'feature1'
2017-04-24 20:52:05 +0200 4f6ecb5 G Riaan Burger  Feaure change.
2017-04-23 23:10:42 +0200 995e108 G Riaan Burger  Initial commit.

Merge to temporary branch:

± git merge --no-ff --verify-signatures -S FETCH_HEAD
Commit c307d0d has a good GPG signature by Andries Petrus Burger...
...
Merge made by the 'recursive' strategy.
 b-file.txt | 1 +
 1 file changed, 1 insertion(+)

G for GPG

Merge 3/6

Git Merge and Trust

Review the contribution in this state

± git diff master
diff --git a/b-file.txt b/b-file.txt
index e69de29..fec2997 100644
--- a/b-file.txt
+++ b/b-file.txt
@@ -0,0 +1 @@
+Change.

You can view differences with your master:

± git difftool master

GUI

Merge 4/6

Git Merge and Trust

Switch to master branch

Merge the temporary branch to master

± git checkout master

Delete the temporary branch

± git merge --no-ff --verify-signatures -S RiaanBurger-master-2017-04-24-23-39-17
± git branch -D RiaanBurger-master-2017-04-24-23-39-17

Push

± git push

Merge 5/6

Git Merge and Trust

Log retains all actions

± gl
*   baeffa4 - (HEAD, master) Merge branch 'RiaanBurger-master-2017-04-24-23-39-17' (6 minutes ago) <Riaan Burger>
|\  
| *   d93b720 - Merge github.com:RiaanBurger/talk into RiaanBurger-master-2017-04-24-23-39-17 (23 minutes ago) <Riaan Burger>
| |\  
|/ /  
| * c307d0d - Change. (59 minutes ago) <Riaan Burger>
|/  
*   d9ce43f - (origin/master) Merge branch 'feature1' (3 hours ago) <Riaan Burger>
|\  
| * 4f6ecb5 - (feature1) Feaure change. (3 hours ago) <Riaan Burger>
|/  
* 995e108 - Initial commit. (25 hours ago) <Riaan Burger>

Log with every commit signed (G):

± git log --pretty="format:%ai %h %G? %aN  %s"
2017-04-25 00:03:35 +0200 baeffa4 G Riaan Burger  Merge branch 'RiaanBurger-master-2017-04-24-23-39-17'
2017-04-24 23:46:21 +0200 d93b720 G Riaan Burger  Merge github.com:RiaanBurger/talk into RiaanBurger-master-...
2017-04-24 23:09:50 +0200 c307d0d G Riaan Burger  Change.
2017-04-24 20:57:24 +0200 d9ce43f G Riaan Burger  Merge branch 'feature1'
2017-04-24 20:52:05 +0200 4f6ecb5 G Riaan Burger  Feaure change.
2017-04-23 23:10:42 +0200 995e108 G Riaan Burger  Initial commit.

Merge 6/6

Git Merge and Trust

Log on GitHub (Verified)

GitHub / GitLab

Git Merge and Trust

  • Cannot be relied on for verification
  • Cannot and should not sign with trust
  • GitLab is still adding signature visuals
  • GitLab is superior in nearly very other way

Thank You

Slides

A Secure Git Development Work-flow

By Riaan Burger

A Secure Git Development Work-flow

  • 2,804