1GIT-REMOTE-GCRYPT(1) GIT-REMOTE-GCRYPT(1)
2
3
4
6 git-remote-gcrypt - GNU Privacy Guard-encrypted git remote
7
9 git-remote-gcrypt is a git remote helper to push and pull from reposi‐
10 tories encrypted with GnuPG, using a custom format. This remote helper
11 handles URIs prefixed with gcrypt::.
12
13 Supported backends are local, rsync:// and sftp://, where the reposi‐
14 tory is stored as a set of files, or instead any <giturl> where gcrypt
15 will store the same representation in a git repository, bridged over
16 arbitrary git transport. See "Performance" below for backends compari‐
17 son.
18
19 There is also an experimental rclone:// backend for early adoptors only
20 (you have been warned).
21
22 The aim is to provide confidential, authenticated git storage and col‐
23 laboration using typical untrusted file hosts or services.
24
25 Installation
26 • use your GNU/Linux distribution's package manager -- Debian, Ubuntu,
27 Fedora, Arch and some smaller distros are known to have packages
28
29 • run the supplied install.sh script on other systems
30
31 Quickstart
32 Create an encrypted remote by pushing to it:
33
34 git remote add cryptremote gcrypt::rsync://example.com/repo
35 git push cryptremote master
36 > gcrypt: Setting up new repository
37 > gcrypt: Remote ID is :id:7VigUnLVYVtZx8oir34R
38 > [ more lines .. ]
39 > To gcrypt::[...]
40 > * [new branch] master -> master
41
43 The following git-config(1) variables are supported:
44
45 remote.<name>.gcrypt-participants
46
47 gcrypt.participants
48 Space-separated list of GPG key identifiers. The remote is en‐
49 crypted to these participants and only signatures from these are
50 accepted. gpg -k lists all public keys you know.
51
52 If this option is not set, we encrypt to your default key and
53 accept any valid signature. This behavior can also be requested
54 explicitly by setting participants to simple.
55
56 The gcrypt-participants setting on the remote takes precedence
57 over the repository variable gcrypt.participants.
58
59 remote.<name>.gcrypt-publish-participants
60
61 gcrypt.publish-participants
62 By default, the gpg key ids of the participants are obscured by
63 encrypting using gpg -R. Setting this option to true disables
64 that security measure.
65
66 The problem with using gpg -R is that to decrypt, gpg tries each
67 available secret key in turn until it finds a usable key. This
68 can result in unnecessary passphrase prompts.
69
70 gcrypt.gpg-args
71 The contents of this setting are passed as arguments to gpg.
72 E.g. --use-agent.
73
74 remote.<name>.gcrypt-signingkey
75
76 user.signingkey
77 (The latter from regular git configuration) The key to use for
78 signing. You should set user.signingkey if your default signing
79 key is not part of the participant list. You may use the per-re‐
80 mote version to sign different remotes using different keys.
81
82 remote.<name>.gcrypt-rsync-put-flags
83
84 gcrypt.rsync-put-flags
85 Flags to be passed to rsync when uploading to a remote using the
86 rsync:// backend. If the flags are set to a specific remote, the
87 global flags, if also set, will not be applied for that remote.
88
89 remote.<name>.gcrypt-require-explicit-force-push
90
91 gcrypt.require-explicit-force-push
92 A longstanding bug is that every git push effectively has a
93 --force.
94
95 If this flag is set to true, git-remote-gcrypt will refuse to
96 push, unless --force is passed, or refspecs are prefixed with +.
97
99 GCRYPT_FULL_REPACK
100 When set (to anything), this environment variable forces a full
101 repack when pushing.
102
104 How to set up a remote for two participants:
105
106 git remote add cryptremote gcrypt::rsync://example.com/repo
107 git config remote.cryptremote.gcrypt-participants "KEY1 KEY2"
108 git push cryptremote master
109
110 How to use a git backend:
111
112 # notice that the target git repo must already exist and its
113 # `next` branch will be overwritten!
114 git remote add gitcrypt gcrypt::git@example.com:repo#next
115 git push gitcrypt master
116
117 The URL fragment (#next here) indicates which backend branch is used.
118
120 Collaboration
121 The encryption of the manifest is updated for each push to match
122 the participant configuration. Each pushing user must have the
123 public keys of all collaborators and correct participant config.
124
125 Dependencies
126 rsync, curl and rclone for remotes rsync:, sftp: and rclone: re‐
127 spectively. The main executable requires a POSIX-compliant shell
128 that supports local.
129
130 GNU Privacy Guard
131 Both GPG 1.4 and 2 are supported. You need a personal GPG key.
132 GPG configuration applies to algorithm choices for public-key
133 encryption, symmetric encryption, and signing. See man gpg for
134 more information.
135
136 Remote ID
137 The Remote ID is not secret; it only ensures that two reposito‐
138 ries signed by the same user can be distinguished. You will see
139 a warning if the Remote ID changes, which should only happen if
140 the remote was re-created.
141
142 Performance
143 Using an arbitrary <giturl> or an sftp:// URI requires uploading
144 the entire repository history with each push. If your reposi‐
145 tory history is large or you are pushing over a slow link, con‐
146 sider using the rsync:// transport, which performs incremental
147 pushes. Note that the latter won't work with a repository host‐
148 ing service like Gitolite, GitHub or GitLab.
149
150 rsync URIs
151 The URI format for the rsync backend is rsync://user@host/path,
152 which translates to the rsync location user@host:/path, accessed
153 over ssh. Note that the path is absolute, not relative to the
154 home directory. An earlier non-standard URI format is also sup‐
155 ported: rsync://user@host:path, which translates to the rsync
156 location user@host:path
157
158 rclone backend
159 In addition to adding the rclone backend as a remote with URI
160 like gcrypt::rclone://remote:subdir, you must add the remote to
161 the rclone configuration too. This is typically done by execut‐
162 ing rclone config. See rclone(1).
163
164 The rclone backend is considered experimental and is for early
165 adoptors only. You have been warned.
166
167 Repository format
168 EncSign(X): Sign and Encrypt to GPG key holder
169 Encrypt(K,X): Encrypt using symmetric-key algorithm
170 Hash(X): SHA-2/256
171
172 B: branch list
173 L: list of the hash (Hi) and key (Ki) for each packfile
174 R: Remote ID
175
176 To write the repository:
177
178 Store each packfile P as Encrypt(Ki, P) → P' in filename Hi
179 where Ki is a new random string and Hash(P') → Hi
180 Store EncSign(B || L || R) in the manifest
181
182 To read the repository:
183
184 Get manifest, decrypt and verify using GPG keyring → (B, L, R)
185 Warn if R does not match previously seen Remote ID
186 for each Hi, Ki in L:
187 Get file Hi from the server → P'
188 Verify Hash(P') matches Hi
189 Decrypt P' using Ki → P then open P with git
190
191
192 Manifest file
193 Example manifest file (with ellipsis for brevity):
194
195 $ gpg -d 91bd0c092128cf2e60e1a608c31e92caf1f9c1595f83f2890ef17c0e4881aa0a
196 542051c7cd152644e4995bda63cc3ddffd635958 refs/heads/next
197 3c9e76484c7596eff70b21cbe58408b2774bedad refs/heads/master
198 pack :SHA256:f2ad50316...cd4ba67092dc4 z8YoAnFpMlW...3PkI2mND49P1qm
199 pack :SHA256:a6e17bb4c...426492f379584 82+k2cbiUn7...dgXfyX6wXGpvVa
200 keep :SHA256:f2ad50316...cd4ba67092dc4 1
201 repo :id:OYiSleGirtLubEVqJpFF
202
203 Each item extends until newline, and matches one of the following:
204
205 <sha-1> <gitref>
206 Git object id and its ref
207
208 pack :<hashtype>:<hash> <key>
209 Packfile hash (Hi) and corresponding symmetric key (Ki).
210
211 keep :<hashtype>:<hash> <generation>
212 Packfile hash and its repack generation
213
214 repo <id>
215 The remote id
216
217 extn <name> ...
218 Extension field, preserved but unused.
219
221 To detect if a git url is a gcrypt repo, use: git-remote-gcrypt --check
222 url Exit status is 0 if the repo exists and can be decrypted, 1 if the
223 repo uses gcrypt but could not be decrypted, and 100 if the repo is not
224 encrypted with gcrypt (or could not be accessed).
225
226 Note that this has to fetch the repo contents into the local git repos‐
227 itory, the same as is done when using a gcrypt repo.
228
230 Every git push effectively has --force. Be sure to pull before push‐
231 ing.
232
233 git-remote-gcrypt can decide to repack the remote without warning,
234 which means that your push can suddenly take significantly longer than
235 you were expecting, as your whole history has to be reuploaded. This
236 push might fail over a poor link.
237
238 git-remote-gcrypt might report a repository as "not found" when the
239 repository does in fact exist, but git-remote-gcrypt is having authen‐
240 tication, port, or network connectivity issues.
241
243 git-remote-helpers(1), gpg(1)
244
246 The original author of git-remote-gcrypt was GitHub user bluss.
247
248 The de facto maintainer in 2013 and 2014 was Joey Hess.
249
250 The current maintainer, since 2016, is Sean Whitton <‐
251 spwhitton@spwhitton.name>.
252
254 This document and git-remote-gcrypt are licensed under identical terms,
255 GPL-3 (or 2+); see the git-remote-gcrypt file.
256
257
258
259
260 GIT-REMOTE-GCRYPT(1)