Browse Source

Spec: Pegleg encryption and decryption

This patchset rounds out the encryption-related design changes
for Pegleg, on top of the existing secret generation material.
It also incorporates some late-add feedback from the previous
patchset.

Change-Id: Ifff04551d24d29e41d71812526bd04c9512b4fbd
Story: 2003708
Task: 26535
Matt McEuen 7 months ago
parent
commit
f17d817ae0
1 changed files with 76 additions and 19 deletions
  1. 76
    19
      specs/approved/pegleg-secrets.rst

+ 76
- 19
specs/approved/pegleg-secrets.rst View File

@@ -43,9 +43,8 @@ The following Airship components will be impacted by this solution:
43 43
 
44 44
 #. Pegleg: enhanced to generate, rotate, encrypt, and decrypt secrets.
45 45
 #. Promenade: PKICatalog will move to Pegleg.
46
-#. Treasuremap: site manifests augmented to support the updated Secrets schema.
47
-#. Airship-in-a-Bottle: site manifests augmented to support the updated
48
-   Secrets schema.
46
+#. Treasuremap: update site manifests to use new Catalogs.
47
+#. Airship-in-a-Bottle: update site manifests to use new Catalogs.
49 48
 
50 49
 Proposed change
51 50
 ===============
@@ -79,7 +78,7 @@ example::
79 78
       abstract: false
80 79
       # Pegleg will initially support generation at site level only
81 80
       layer: site
82
-    storagePolicy: encrypted
81
+    storagePolicy: cleartext
83 82
   data:
84 83
     generated:
85 84
       at: <timestamp>
@@ -89,6 +88,7 @@ example::
89 88
         reference: <git ref-head or similar>
90 89
         path: <PKICatalog/PassphraseCatalog details>
91 90
     managedDocument:
91
+      schema: <as appropriate for wrapped document>
92 92
       metadata:
93 93
         storagePolicy: encrypted
94 94
         schema: <as appropriate for wrapped document>
@@ -109,12 +109,13 @@ example::
109 109
     layeringDefinition:
110 110
       abstract: false
111 111
       layer: matching-wrapped-doc
112
-    storagePolicy: encrypted
112
+    storagePolicy: cleartext
113 113
   data:
114 114
     encrypted:
115 115
       at: <timestamp>
116 116
       by: <author>
117 117
     managedDocument:
118
+      schema: <as appropriate for wrapped document>
118 119
       metadata:
119 120
         storagePolicy: encrypted
120 121
         schema: <as appropriate for wrapped document>
@@ -126,7 +127,7 @@ A PeglegManagedDocument that is both generated via a Catalog, and encrypted
126 127
 (as specified by the catalog) will contain both ``generated`` and
127 128
 ``encrypted`` stanzas.
128 129
 
129
-Note that this ``encrypted`` has a different purpose than the Deckhand
130
+Note that this ``encrypted`` key has a different purpose than the Deckhand
130 131
 ``storagePolicy: encrypted`` metadata, which indicates an *intent* for Deckhand
131 132
 to store a document encrypted at rest in the cluster.  The two can be used
132 133
 together to ensure security, however:  if a document is marked as
@@ -134,6 +135,11 @@ together to ensure security, however:  if a document is marked as
134 135
 persisted (e.g. to a Git repository) if it is in fact encrypted within
135 136
 a PeglegManagedDocument.
136 137
 
138
+Note also that the Deckhand ``storagePolicy`` of the PeglegManagedDocument
139
+itself is always ``cleartext``, since its data stanza is not encrypted -- it
140
+only wraps a document that *is* ``storagePolicy: encrypted``.
141
+This should be implemented as a Pegleg lint rule.
142
+
137 143
 Document Generation
138 144
 -------------------
139 145
 
@@ -204,7 +210,10 @@ The nonobvious bits of the document described above are:
204 210
   replace dashes in the ``document_name`` with underscores.
205 211
 * ``length`` is optional, and denotes the length in characters of the
206 212
   generated cleartext passphrase data.  If absent, ``length`` defaults
207
-  to ``24``.
213
+  to ``24``.  Note that with this length and the selected character set there
214
+  will be less than 8x10^48 probability of getting a new passphrase that is
215
+  identical to the previous passphrase.  This is sufficiently random to
216
+  ensure no duplication of rotated passphrases in practice.
208 217
 * ``description`` is optional.
209 218
 
210 219
 The ``encrypted`` key will be added to the PKICatalog schema, and adds the same
@@ -220,16 +229,27 @@ Committing and pushing the changes will be left to the
220 229
 operator or to script-based automation.
221 230
 
222 231
 For the CLI commands below which encrypt or decrypt secrets, an environment
223
-variable (e.g. ``$PEGLEG_KEY`` will be use to capture the key/passphrase to use.
224
-``pegleg site secrets rotate`` will use a second variable
225
-(e.g. ``$PEGLEG_PREVIOUS_KEY``) to hold the key/passphrase being rotated
226
-out.
232
+variable (e.g. ``PEGLEG_PASSPHRASE`` will be use to capture the master
233
+passphrase to use.  ``pegleg site secrets rotate`` will use a second variable
234
+(e.g. ``PEGLEG_PREVIOUS_PASSPHRASE``) to hold the key/passphrase being rotated
235
+out.  The contents of these keys/passphrases are not generated by Pegleg,
236
+but are created externally and set by a deployment engineer or tooling.
237
+A configurable minimum length (default 24) for master passphrases will
238
+be checked by all CLI commands which use the passphrase.  All other criteria
239
+around passphrase strength are assumed to be enforced elsewhere, as it is an
240
+external secret that is consumed/used by Pegleg.
227 241
 
228 242
 ``pegleg site secrets generate passphrases``:  Generate passphrases according to
229 243
 all PassphraseCatalog documents in the site.
230 244
 Note that regenerating passphrases can be accomplished
231 245
 simply by re-running ``pegleg site secrets generate passphrases``.
232 246
 
247
+``pegleg generate passphrase``:  A standalone version of passphrase generation.
248
+This generates a single passphrase based on the default length, character set,
249
+and implementation described above, and outputs it to the console.  The
250
+PassphraseCatalog is not involved in this operation.  This command is suitable
251
+for generation of a highly-secure Pegleg master passphrase.
252
+
233 253
 ``pegleg site secrets generate pki``:  Generate certificates and keys according
234 254
 to all PKICatalog documents in the site.
235 255
 Note that regenerating certificates can be accomplished
@@ -258,22 +278,28 @@ original document YAML to standard output.  This is intended to be used when
258 278
 an authorized deployment engineer needs to determine a particular cleartext
259 279
 secret for a specific operational purpose.
260 280
 
261
-``pegleg site secrets rotate``:  This action re-encrypts encrypted secrets
262
-with a new key/passphrase, and it takes the previously-used key and a new
263
-key as input.  It accomplishes its task via two activities:
281
+``pegleg site secrets rotate passphrases``:  This action re-encrypts
282
+encrypted passphrases with a new key/passphrase, and it takes the
283
+previously-used key and a new key as input.  It accomplishes its task via
284
+two activities:
264 285
 
265
-* For encrypted secrets that were imported from outside of Pegleg
286
+* For encrypted passphrases that were imported from outside of Pegleg
266 287
   (i.e. PeglegManagedDocuments which lack the ``generated`` stanza),
267 288
   decrypt them with the old key (in-memory), re-encrypt them with
268 289
   the new key, and output the results.
269
-* Perform a fresh ``pegleg site secrets generate`` process using the new key.
270
-  This will replace all ``generated`` secrets with new secret values
290
+* Perform a fresh ``pegleg site secrets generate passphrases`` process
291
+  using the new key.
292
+  This will replace all ``generated`` passphrases  with new secret values
271 293
   for added security.  There is an assumption here that the only actors
272 294
   that need to know generated secrets are the services within the
273 295
   Airship-managed cluster, not external services or deployment engineers,
274 296
   except perhaps for point-in-time troubleshooting or operational
275 297
   exercises.
276 298
 
299
+Similar functionality for rotating certificates (which is expected to have
300
+a different cadence than passphrase rotation, typically) will be
301
+added in the future.
302
+
277 303
 Driving deployment of a site directly via Pegleg is follow-on functionality
278 304
 which will
279 305
 collect site documents, use them to create the ``genesis.sh`` script, and then
@@ -289,7 +315,7 @@ PeglegManagedDocuments will be written (encrypted) to disk.
289 315
 To enable special case full site secret decryption, a ``--force-decrypt`` flag
290 316
 will be added to ``pegleg collect`` to do this under controlled circumstances,
291 317
 and to help bridge the gap with existing CICD pipelines until Pegleg-driven
292
-site deployment is in place.  It will leverage the ``$PEGLEG_KEY``
318
+site deployment is in place.  It will leverage the ``PEGLEG_PASSPHRASE``
293 319
 variable described above.
294 320
 
295 321
 Secret Generation
@@ -309,7 +335,33 @@ Python string.ascii_letters, string.digits, and string.punctuation.
309 335
 Secret Encryption
310 336
 -----------------
311 337
 
312
-Details around encryption will be defined in a follow-on patch set to this spec.
338
+The Python ``cryptography`` library has been chosen to implement the
339
+encryption and decryption of secrets within Pegleg.  ``cryptography``
340
+aims to be the standard cryptographic approach for Python, and takes
341
+pains to make it difficult to do encryption poorly (via its ``recipes``
342
+layer), while still allowing access to the algorithmic details when
343
+truly needed (via its ``hazmat`` layer).  ``cryptography`` is actively
344
+maintained and is the target encryption library for OpenStack as well.
345
+
346
+The ``cryptography.fernet`` module will be used for symmetric encryption.
347
+It uses AES with a 128-bit key for encryption, and HMAC using SHA256
348
+for encryption.
349
+
350
+Fernet requires as input a URL-safe, base64-encoded 32-byte encryption key,
351
+which will be derived from the master passphrase passed into Pegleg via
352
+``PEGLEG_PASSPHRASE`` as described above.
353
+The example for password-based encryption from the `Fernet documentation`_
354
+should be followed as a guide. The ``salt`` to be used in key derivation
355
+will be configurable, and will be set to a fixed value within a built
356
+Pegleg container via an environment variable passed into the Pegleg
357
+Dockerfile.  This will allow the salt to be different on an
358
+operator-by-operator basis.
359
+
360
+The ``cryptography.exceptions.InvalidSignature`` exception is thrown by
361
+``cryptography`` when an attempt is made to decrypt a message with a key that
362
+is different than the one used to encrypt a message, i.e., when the user has
363
+supplied an incorrect phassphrase.  It should be handled gracefully by Pegleg,
364
+resulting in an informative message back to the user.
313 365
 
314 366
 Security impact
315 367
 ===============
@@ -346,6 +398,10 @@ the point-in-time encryption status.  ``storagePolicy`` is still valuable
346 398
 in this context to make sure everything that *should* be encrypted *is*,
347 399
 prior to performing actions with it (e.g. Git commits).
348 400
 
401
+The ``PyCrypto`` library is a popular solution for encryption in Python;
402
+however, it is no longer actively maintained.  Following the lead of OpenStack
403
+and others, we opted instead for the ``cryptography`` library.
404
+
349 405
 This proposed implementation writes the output of generation/encryption events
350 406
 back to the same source files from which the original data came.  This is a
351 407
 destructive operation; however, it wasn't evident that it is problematic in
@@ -370,3 +426,4 @@ References
370 426
 
371 427
 .. _Storyboard Story: https://storyboard.openstack.org/#!/story/2003708
372 428
 .. _Git branch and revision support: https://review.openstack.org/#/c/577886/
429
+.. _Fernet documentation: https://cryptography.io/en/latest/fernet/

Loading…
Cancel
Save