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. Prefer local or rsync:// if you can use one
17 of those; see "Performance" below for discussion.
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. This means that
145 pushes of your repository become slower over time, as your git
146 history becomes longer, and it can easily get to the point that
147 continued usage of git-remote-gcrypt is impractical.
148
149 Thus, you should use these backends only when you know that your
150 repository will not ever grow very large, not just that it's not
151 large now. This means that these backends are inappropriate for
152 most repositories, and likely suitable only for unusual cases,
153 such as small credential stores. Even then, use rsync:// if you
154 can. Note, however, that rsync:// won't work with a repository
155 hosting service like Gitolite, GitHub or GitLab.
156
157 rsync URIs
158 The URI format for the rsync backend is rsync://user@host/path,
159 which translates to the rsync location user@host:/path, accessed
160 over ssh. Note that the path is absolute, not relative to the
161 home directory. An earlier non-standard URI format is also sup‐
162 ported: rsync://user@host:path, which translates to the rsync
163 location user@host:path
164
165 rclone backend
166 In addition to adding the rclone backend as a remote with URI
167 like gcrypt::rclone://remote:subdir, you must add the remote to
168 the rclone configuration too. This is typically done by execut‐
169 ing rclone config. See rclone(1).
170
171 The rclone backend is considered experimental and is for early
172 adoptors only. You have been warned.
173
174 Repository format
175 EncSign(X): Sign and Encrypt to GPG key holder
176 Encrypt(K,X): Encrypt using symmetric-key algorithm
177 Hash(X): SHA-2/256
178
179 B: branch list
180 L: list of the hash (Hi) and key (Ki) for each packfile
181 R: Remote ID
182
183 To write the repository:
184
185 Store each packfile P as Encrypt(Ki, P) → P' in filename Hi
186 where Ki is a new random string and Hash(P') → Hi
187 Store EncSign(B || L || R) in the manifest
188
189 To read the repository:
190
191 Get manifest, decrypt and verify using GPG keyring → (B, L, R)
192 Warn if R does not match previously seen Remote ID
193 for each Hi, Ki in L:
194 Get file Hi from the server → P'
195 Verify Hash(P') matches Hi
196 Decrypt P' using Ki → P then open P with git
197
198
199 Manifest file
200 Example manifest file (with ellipsis for brevity):
201
202 $ gpg -d 91bd0c092128cf2e60e1a608c31e92caf1f9c1595f83f2890ef17c0e4881aa0a
203 542051c7cd152644e4995bda63cc3ddffd635958 refs/heads/next
204 3c9e76484c7596eff70b21cbe58408b2774bedad refs/heads/master
205 pack :SHA256:f2ad50316...cd4ba67092dc4 z8YoAnFpMlW...3PkI2mND49P1qm
206 pack :SHA256:a6e17bb4c...426492f379584 82+k2cbiUn7...dgXfyX6wXGpvVa
207 keep :SHA256:f2ad50316...cd4ba67092dc4 1
208 repo :id:OYiSleGirtLubEVqJpFF
209
210 Each item extends until newline, and matches one of the following:
211
212 <sha-1> <gitref>
213 Git object id and its ref
214
215 pack :<hashtype>:<hash> <key>
216 Packfile hash (Hi) and corresponding symmetric key (Ki).
217
218 keep :<hashtype>:<hash> <generation>
219 Packfile hash and its repack generation
220
221 repo <id>
222 The remote id
223
224 extn <name> ...
225 Extension field, preserved but unused.
226
228 To detect if a git url is a gcrypt repo, use: git-remote-gcrypt --check
229 url Exit status is 0 if the repo exists and can be decrypted, 1 if the
230 repo uses gcrypt but could not be decrypted, and 100 if the repo is not
231 encrypted with gcrypt (or could not be accessed).
232
233 Note that this has to fetch the repo contents into the local git repos‐
234 itory, the same as is done when using a gcrypt repo.
235
237 Every git push effectively has --force. Be sure to pull before push‐
238 ing.
239
240 git-remote-gcrypt can decide to repack the remote without warning,
241 which means that your push can suddenly take significantly longer than
242 you were expecting, as your whole history has to be reuploaded. This
243 push might fail over a poor link.
244
245 git-remote-gcrypt might report a repository as "not found" when the
246 repository does in fact exist, but git-remote-gcrypt is having authen‐
247 tication, port, or network connectivity issues.
248
250 git-remote-helpers(1), gpg(1)
251
253 The original author of git-remote-gcrypt was GitHub user bluss.
254
255 The de facto maintainer in 2013 and 2014 was Joey Hess.
256
257 The current maintainer, since 2016, is Sean Whitton <‐
258 spwhitton@spwhitton.name>.
259
261 This document and git-remote-gcrypt are licensed under identical terms,
262 GPL-3 (or 2+); see the git-remote-gcrypt file.
263
264
265
266
267 GIT-REMOTE-GCRYPT(1)