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