opensecret 0.0.9925 → 0.0.9949

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +656 -40
  3. data/lib/configs/README.md +58 -0
  4. data/lib/extension/file.rb +67 -0
  5. data/lib/extension/string.rb +10 -0
  6. data/lib/factbase/facts.opensecret.io.ini +1 -0
  7. data/lib/interprete.rb +334 -61
  8. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  9. data/lib/keytools/kdf.api.rb +9 -15
  10. data/lib/keytools/kdf.bcrypt.rb +69 -19
  11. data/lib/keytools/kdf.pbkdf2.rb +112 -23
  12. data/lib/keytools/key.api.rb +146 -36
  13. data/lib/keytools/key.db.rb +94 -29
  14. data/lib/keytools/key.id.rb +1 -1
  15. data/lib/keytools/key.ident.rb +243 -0
  16. data/lib/keytools/key.local.rb +62 -68
  17. data/lib/keytools/key.pass.rb +2 -2
  18. data/lib/keytools/key.rb +2 -28
  19. data/lib/modules/{cryptology.md → README.md} +0 -0
  20. data/lib/session/fact.finder.rb +65 -428
  21. data/lib/session/time.stamp.rb +1 -28
  22. data/lib/usecase/cmd.rb +127 -54
  23. data/lib/usecase/config/README.md +57 -0
  24. data/lib/usecase/docker/README.md +146 -0
  25. data/lib/usecase/docker/docker.rb +49 -0
  26. data/lib/usecase/edit/README.md +43 -0
  27. data/lib/usecase/edit/delete.rb +46 -0
  28. data/lib/usecase/export.rb +40 -0
  29. data/lib/usecase/files/README.md +37 -0
  30. data/lib/usecase/files/eject.rb +56 -0
  31. data/lib/usecase/files/file_me.rb +78 -0
  32. data/lib/usecase/files/read.rb +169 -0
  33. data/lib/usecase/files/write.rb +89 -0
  34. data/lib/usecase/goto.rb +57 -0
  35. data/lib/usecase/id.rb +1 -1
  36. data/lib/usecase/import.rb +13 -30
  37. data/lib/usecase/init.rb +2 -17
  38. data/lib/usecase/jenkins/README.md +146 -0
  39. data/lib/usecase/jenkins/crazy_ruby_post_attempt.OLD +234 -0
  40. data/lib/usecase/jenkins/jenkins.rb +208 -0
  41. data/lib/usecase/login.rb +6 -5
  42. data/lib/usecase/logout.rb +1 -3
  43. data/lib/usecase/open.rb +11 -66
  44. data/lib/usecase/print.rb +40 -0
  45. data/lib/usecase/put.rb +34 -156
  46. data/lib/usecase/set.rb +2 -4
  47. data/lib/usecase/show.rb +138 -0
  48. data/lib/usecase/terraform/README.md +91 -0
  49. data/lib/usecase/terraform/terraform.rb +121 -0
  50. data/lib/usecase/token.rb +4 -80
  51. data/lib/usecase/update/README.md +55 -0
  52. data/lib/usecase/update/rename.rb +180 -0
  53. data/lib/usecase/use.rb +1 -3
  54. data/lib/usecase/verse.rb +20 -0
  55. data/lib/usecase/view.rb +71 -0
  56. data/lib/usecase/vpn/README.md +150 -0
  57. data/lib/usecase/vpn/vpn.ini +31 -0
  58. data/lib/usecase/vpn/vpn.rb +54 -0
  59. data/lib/version.rb +1 -1
  60. data/opensecret.gemspec +3 -4
  61. metadata +34 -35
  62. data/.travis.yml +0 -5
  63. data/CODE_OF_CONDUCT.md +0 -74
  64. data/LICENSE.txt +0 -21
  65. data/bin/ops +0 -20
  66. data/lib/keytools/binary.map.rb +0 -294
  67. data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +0 -179
  68. data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +0 -190
  69. data/lib/keytools/doc.star.schema.strategy.txt +0 -77
  70. data/lib/keytools/doc.using.pbkdf2.kdf.ruby +0 -95
  71. data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +0 -266
  72. data/lib/keytools/key.mach.rb +0 -248
  73. data/lib/keytools/keydebug.txt +0 -295
  74. data/lib/modules/cryptology/open.bcrypt.rb +0 -170
  75. data/lib/usecase/read.rb +0 -89
  76. data/lib/usecase/safe.rb +0 -92
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>read use case</b> pulls a file in from either an accessible filesystem
6
+ # or from a remote http, https, git, S3, GoogleDrive and/or ssh source.
7
+ #
8
+ # This use case expects a @file_url parameter. The actions it takes are to
9
+ #
10
+ # - register @in.url to mirror @file_url
11
+ # - register @out.url to mirror @file_url
12
+ # - check the location of @file_url
13
+ # - if no file exists it humbly finishes up
14
+ #
15
+ # If a file does exist at the @in.url this use case
16
+ #
17
+ # - handles HOME directory enabling portability
18
+ # - creates an encryption key and random iv
19
+ # - creates a file (name) id
20
+ # - stores the file byte and human readable size
21
+ # - stores the extension if it has one
22
+ # - stores the last created date
23
+ # - stores the last modified date
24
+ # - stores the (now) in date
25
+ #
26
+ # Once done it displays <b><em>key facts about the file</em></b>.
27
+ class Read < UseCase
28
+
29
+ # -- ---------------------- --#
30
+ # -- ---------------------- --#
31
+ # -- [SAFE] Name Changes --#
32
+ # -- ---------------------- --#
33
+ # -- Change env.path ~> open.chapter
34
+ # -- Change key.path ~> open.verse
35
+ # -- Change envelope@xxxx ~> chapter@xxxx
36
+ # --
37
+ # -- Change filenames to ~~~~~> book.db.breadcrumbs
38
+ # -- Change filenames to ~~~~~> chapter.cipher.file
39
+ # -- Change filenames to ~~~~~> safe.db.abc123xyzpq
40
+ # -- ---------------------- --#
41
+ # -- {
42
+ # -- "db.create.date": "Sat Aug 11 11:20:16 2018 ( 18223.1120.07.511467675 )",
43
+ # -- "db.domain.name": "ab.com",
44
+ # -- "db.domain.id": "uhow-ku9l",
45
+ # -- "env.path": "aa",
46
+ # -- "key.path": "aa",
47
+ # -- "envelope@aa": {
48
+ # -- "content.xid": "3uzk12dxity",
49
+ # -- "content.iv": "XTVe%qIGKVvWw@EKcgSa153nfVPaMVJH",
50
+ # -- "content.key": "1u3b2o6KLiAUmt11yYEDThJw1E5Mh4%1iHYOpJQjWiYLthUGgl8IZ5szus8Fz2Jt"
51
+ # -- }
52
+ # -- }
53
+ # -- ---------------------- --#
54
+ # -- ---------------------- --#
55
+
56
+ attr_writer :file_url
57
+
58
+ # The <b>read use case</b> pulls a file in from either an accessible filesystem
59
+ # or from a remote http, https, git, S3, GoogleDrive and/or ssh source.
60
+ def execute
61
+
62
+ return unless ops_key_exists?
63
+ master_db = OpenKey::KeyApi.read_master_db()
64
+ return if unopened_envelope?( master_db )
65
+
66
+ # -- Get the open chapter identifier (id).
67
+ # -- Decide whether chapter already exists.
68
+ # -- Then get (or instantiate) the chapter's hash data structure
69
+ # --
70
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
71
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
72
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) ) if chapter_exists
73
+ chapter_data = OpenKey::KeyDb.new() unless chapter_exists
74
+
75
+ content_hdr = create_header()
76
+
77
+ # -- If no content envelope exists we need to place
78
+ # -- an empty one inside the appdb content database.
79
+ # --
80
+ master_db[ chapter_id ] = {} unless chapter_exists
81
+
82
+ # -- We populate (PUT) file instance attributes into
83
+ # -- the mini-dictionary at the [VERSE] location.
84
+ # --
85
+ verse_id = master_db[ KEY_PATH ]
86
+ file_absolute_path = ::File.absolute_path( @file_url )
87
+ chapter_data.create_entry( verse_id, "@in.url", file_absolute_path )
88
+ chapter_data.create_entry( verse_id, "@out.url", file_absolute_path )
89
+
90
+ # -- Lock No.1
91
+ # --
92
+ # -- Lock the file content and leave the 3 breadcrumbs
93
+ # -- (content id, content iv and content key) inside
94
+ # -- the file attributes mini dictionary to facilitate
95
+ # -- decrypting and writing out the file again.
96
+ # --
97
+ OpenKey::KeyApi.content_lock( chapter_data[ verse_id ], ::File.read( @file_url ), content_hdr )
98
+
99
+ # -- Lock No.2
100
+ # --
101
+ # -- Lock the chapter's data which includes the new or
102
+ # -- updated mini-dictionary that holds the breadcrumbs
103
+ # -- (content id, content iv and content key) that will
104
+ # -- be used to decrypt and write out the file content.
105
+ # --
106
+ # -- Leave another set of breadcrumbs inside the master
107
+ # -- database (content id, content iv and content key)
108
+ # -- to facilitate decrypting the chapter's data.
109
+ # --
110
+ OpenKey::KeyApi.content_lock( master_db[ chapter_id ], chapter_data.to_json, content_hdr )
111
+
112
+ # -- Lock No.3
113
+ # --
114
+ # -- Re-lock the master database including the breadcrumbs
115
+ # -- (content id, content iv and content key) that will
116
+ # -- (in the future) decrypt this chapter's data.
117
+ # --
118
+ OpenKey::KeyApi.write_master_db( content_hdr, master_db )
119
+
120
+
121
+ # -- Communicate that the indicated file has just been
122
+ # -- successfully ingested into the safe.
123
+ # --
124
+ print_file_success master_db[ ENV_PATH ], verse_id, file_absolute_path
125
+
126
+ end
127
+
128
+
129
+ private
130
+
131
+
132
+ def print_file_success chapter_id, verse_id, file_url
133
+
134
+ puts ""
135
+ puts "|-"
136
+ puts "|- Chapter ~> #{chapter_id}"
137
+ puts "|- + Verse ~> #{verse_id}"
138
+ puts "|-"
139
+ puts "|- In File ~> #{file_url}"
140
+ puts "|-"
141
+ puts "|- File cocooned inside your safe."
142
+ puts "|-"
143
+ puts "|-Command Options"
144
+ puts "|-"
145
+ puts "|- #{COMMANDMENT} put out.dir ~/this/folder"
146
+ puts "|- #{COMMANDMENT} put out.name new-filename.txt"
147
+ puts "|- #{COMMANDMENT} write"
148
+ puts "|-"
149
+ puts ""
150
+
151
+ end
152
+
153
+
154
+ # Perform pre-conditional validations in preparation to executing the main flow
155
+ # of events for this use case. This method may throw the below exceptions.
156
+ #
157
+ # @raise [SafeDirNotConfigured] if the safe's url has not been configured
158
+ # @raise [EmailAddrNotConfigured] if the email address has not been configured
159
+ # @raise [StoreUrlNotConfigured] if the crypt store url is not configured
160
+ def pre_validation
161
+
162
+
163
+ end
164
+
165
+
166
+ end
167
+
168
+
169
+ end
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # The <b>write use case</b> writes (or overwrites) a file at the
6
+ # out url destination.
7
+ class Write < UseCase
8
+
9
+ attr_writer :file_url
10
+
11
+ # The <b>read use case</b> pulls a file in from either an accessible filesystem
12
+ # or from a remote http, https, git, S3, GoogleDrive and/or ssh source.
13
+ def execute
14
+
15
+ return unless ops_key_exists?
16
+ master_db = get_master_database()
17
+ return if unopened_envelope?( master_db )
18
+
19
+ # Get the open chapter identifier (id).
20
+ # Decide whether chapter already exists.
21
+ # Then get (or instantiate) the chapter's hash data structure
22
+ chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
23
+ verse_id = master_db[ KEY_PATH ]
24
+ chapter_exists = OpenKey::KeyApi.db_envelope_exists?( master_db[ chapter_id ] )
25
+
26
+
27
+ # @todo begin
28
+ # Throw an exception (error) if the chapter
29
+ # either exists and is empty or does not exist.
30
+ # @todo end
31
+
32
+
33
+ # Unlock the chapter data structure by supplying
34
+ # key/value mini-dictionary breadcrumbs sitting
35
+ # within the master database at the section labelled
36
+ # envelope@<<actual_chapter_id>>.
37
+ chapter_data = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ chapter_id ] ) )
38
+
39
+
40
+ # Unlock the file content by supplying the
41
+ # key/value mini-dictionary breadcrumbs sitting
42
+ # within the chapter's data structure in the
43
+ # section labelled <<verse_id>>.
44
+ file_content = OpenKey::KeyApi.content_unlock( chapter_data[ verse_id ] )
45
+
46
+
47
+ # We read the location url we plan to eject the
48
+ # file out into.
49
+ file_path = @file_url ? @file_url : chapter_data[ verse_id ][ "@out.url" ]
50
+ file_name = ::File.basename( file_path)
51
+
52
+ # If the directory the file will be exported to does
53
+ # not exist we promptly create it.
54
+ FileUtils.mkdir_p( File.dirname( file_path ) )
55
+
56
+ # Create a backup file if we can detect that a
57
+ # file occupies the eject (write) filepath.
58
+ backup_file_path = ::File.join( ::File.dirname( file_path ), OpenKey::KeyNow.yyjjj_hhmm_sst() + "-" + file_name )
59
+ ::File.write( backup_file_path, ::File.read( file_path ) ) if ::File.file?( file_path )
60
+
61
+
62
+ # Now write (and if necessary overwrite) the eject
63
+ # file url path with the previously ingested content.
64
+ ::File.write( file_path, file_content )
65
+
66
+
67
+ # Communicate that the indicated file has just been
68
+ # successfully written out from the safe.
69
+ print_file_success( master_db[ ENV_PATH ], verse_id, file_path )
70
+
71
+ end
72
+
73
+
74
+ private
75
+
76
+
77
+ # Document a successful write of a file cocooned in the safe.
78
+ # @param chapter_id the chapter of the file written out
79
+ # @param verse_id the verse of the file written out
80
+ # @param file_url the filepath the file was written to
81
+ def print_file_success chapter_id, verse_id, file_url
82
+ puts "File [#{file_url}] written out of safe at chapter [#{chapter_id}] and verse [#{verse_id}]."
83
+ end
84
+
85
+
86
+ end
87
+
88
+
89
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ # Goto is a shortcut (or alias even) for the open command that takes an integer
6
+ # index that effectively specifies which <envelope> and <key> to open.
7
+ #
8
+ # Use <b>view</b> to list the valid integer indices for each envelope and key
9
+ # combination.
10
+ #
11
+ # View maps out and numbers each envelope/key combination.
12
+ # Goto with the number effectively shortcuts the open pin pointer command.
13
+ # Show prints the dictionary at the opened path masking any secrets.
14
+ #
15
+ # Once goto is enacted all path CRUD commands come into play as if you had
16
+ # opened the path. These include put, copy, paste, show, tell and delete.
17
+ class Goto < UseCase
18
+
19
+ # The index (number) starting with 1 of the envelope and key-path
20
+ # combination that should be opened.
21
+ attr_writer :index
22
+
23
+ def execute
24
+
25
+ return unless ops_key_exists?
26
+ master_db = OpenKey::KeyApi.read_master_db()
27
+
28
+ goto_location = 0
29
+ envelope_dictionaries = OpenKey::KeyApi.to_matching_dictionary( master_db, ENVELOPE_KEY_PREFIX )
30
+ envelope_dictionaries.each_pair do | envelope_name, crumb_dictionary |
31
+
32
+ envelope_content = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( crumb_dictionary ) )
33
+ envelope_content.each_key do | envelope_key |
34
+
35
+ goto_location += 1
36
+ next unless @index.to_i == goto_location
37
+
38
+ open_uc = Open.new
39
+ open_uc.env_path = envelope_name
40
+ open_uc.key_path = envelope_key
41
+ open_uc.flow_of_events
42
+
43
+ return
44
+
45
+ end
46
+
47
+
48
+ end
49
+
50
+
51
+ end
52
+
53
+
54
+ end
55
+
56
+
57
+ end
@@ -3,7 +3,7 @@
3
3
  module OpenSecret
4
4
 
5
5
 
6
- class Id < Command
6
+ class Id < UseCase
7
7
 
8
8
 
9
9
  def execute
@@ -2,8 +2,6 @@
2
2
 
3
3
  module OpenSecret
4
4
 
5
- require 'openssl'
6
-
7
5
  # The <b>import use case</b> follows <b>open</b> and it pulls a file into an
8
6
  # <em>(encrypted at rest)</em> <b>envelope</b> while writing metadata about
9
7
  # the file into the opened tree dictionary position.
@@ -27,7 +25,7 @@ module OpenSecret
27
25
  # remove immediately - remove on next login - remove after a time period
28
26
  # or to never remove (manual garbage collection).
29
27
  #
30
- class Import < Command
28
+ class Import < UseCase
31
29
 
32
30
  attr_writer :secret_id, :secret_value
33
31
 
@@ -56,34 +54,19 @@ module OpenSecret
56
54
  # - a new session id and encryption key is generated and used to re-encrypt
57
55
  def execute
58
56
 
59
- ## @todo - rename appdb_content as master_db
60
- ## @todo - rename appdb_content as master_db
61
- ## @todo - rename appdb_content as master_db
62
- ## @todo - rename appdb_content as master_db
63
- ## @todo - rename appdb_content as master_db
64
- ## @todo - rename appdb_content as master_db
65
- ## @todo - rename appdb_content as master_db
66
- ## @todo - rename appdb_content as master_db
67
- ## @todo - rename appdb_content as master_db
68
- ## @todo - rename appdb_content as master_db
69
- ## @todo - rename appdb_content as master_db
70
- ## @todo - rename appdb_content as master_db
71
- ## @todo - rename appdb_content as master_db
72
- ## @todo - rename appdb_content as master_db
73
-
74
57
  return unless ops_key_exists?
75
- appdb_content = OpenKey::KeyApi.read_app_content()
58
+ master_db = OpenKey::KeyApi.read_master_db()
76
59
 
77
60
  puts "---\n"
78
61
  puts "--- The Master Database (Before)\n"
79
62
  puts "---\n"
80
- puts JSON.pretty_generate( appdb_content )
63
+ puts JSON.pretty_generate( master_db )
81
64
  puts "---\n"
82
65
 
83
- return if unopened_envelope?( appdb_content )
66
+ return if unopened_envelope?( master_db )
84
67
 
85
- envelope_id = ENVELOPE_KEY_PREFIX + appdb_content[ ENV_PATH ]
86
- has_content = OpenKey::KeyApi.content_exists?( appdb_content[ envelope_id ] )
68
+ envelope_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
69
+ has_content = OpenKey::KeyApi.db_envelope_exists?( master_db[ envelope_id ] )
87
70
 
88
71
  # --
89
72
  # -- To get hold of the content we must either
@@ -91,7 +74,7 @@ module OpenSecret
91
74
  # -- a) unlock it using the breadcrumbs or
92
75
  # -- b) start afresh with a new content db
93
76
  # --
94
- content_box = OpenKey::KeyApi.content_unlock( appdb_content[ envelope_id ] ) if has_content
77
+ content_box = OpenKey::KeyDb.from_json( OpenKey::KeyApi.content_unlock( master_db[ envelope_id ] ) ) if has_content
95
78
  content_box = OpenKey::KeyDb.new() unless has_content
96
79
  content_hdr = create_header()
97
80
 
@@ -99,7 +82,7 @@ module OpenSecret
99
82
  # -- If no content envelope exists we need to place
100
83
  # -- an empty one inside the appdb content database.
101
84
  # --
102
- appdb_content[ envelope_id ] = {} unless has_content
85
+ master_db[ envelope_id ] = {} unless has_content
103
86
 
104
87
  # --
105
88
  # -- This is the PUT use case so we append a
@@ -110,14 +93,14 @@ module OpenSecret
110
93
  # -- into the current content envelope and write
111
94
  # -- the envelope to the content filepath.
112
95
  # --
113
- crumbs_dict = appdb_content[ envelope_id ]
114
- content_box.create_entry( appdb_content[ KEY_PATH ], @secret_id, @secret_value )
96
+ crumbs_dict = master_db[ envelope_id ]
97
+ content_box.create_entry( master_db[ KEY_PATH ], @secret_id, @secret_value )
115
98
  OpenKey::KeyApi.content_lock( crumbs_dict, content_box.to_json, content_hdr )
116
99
 
117
100
  puts "---\n"
118
101
  puts "--- The Master Database (After)\n"
119
102
  puts "---\n"
120
- puts JSON.pretty_generate( appdb_content )
103
+ puts JSON.pretty_generate( master_db )
121
104
  puts "---\n"
122
105
 
123
106
  # --
@@ -125,7 +108,7 @@ module OpenSecret
125
108
  # -- random iv and the crypt key are written afreshinto
126
109
  # -- the master database.
127
110
  # --
128
- OpenKey::KeyApi.write_app_content( content_hdr, appdb_content )
111
+ OpenKey::KeyApi.write_master_db( content_hdr, master_db )
129
112
  print_put_success
130
113
 
131
114
  return
@@ -150,7 +133,7 @@ module OpenSecret
150
133
  puts "Success putting a key/value pair into the open envelope."
151
134
  puts "You can put more in and then close the envelope."
152
135
  puts ""
153
- puts " ops close"
136
+ puts " #{COMMANDMENT} close"
154
137
  puts ""
155
138
 
156
139
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  module OpenSecret
4
4
 
5
- require 'openssl'
6
-
7
5
  # The <b>init use case</b> initializes opensecret thus preparing it
8
6
  # for the ability to lock secrets, unlock them, transport their keys and
9
7
  # much more.
@@ -11,21 +9,11 @@ module OpenSecret
11
9
  # opensecret is a <b>(glorified) placeholder</b>. It takes things in now,
12
10
  # keeps them safe and gives them back later, in a <b>helpful manner</b>.
13
11
  #
14
- # ---
15
- #
16
- # ops init bob@gmail.com $HOME/bob.credentials
17
- #
18
- # or
19
- #
20
- # xport init bob@gmail.com $HOME/apollo.team.x
21
- #
22
- # ---
23
- #
24
12
  # == Alternat Error Flows
25
13
  #
26
14
  # An error will be thrown
27
15
  #
28
- # - if ops can't create or extend the base directory
16
+ # - if opensecret cannot create, extend, read or write the drive folder
29
17
  # - if the domain is already in the configuration file
30
18
  # - if domain has non alphanums, excl hyphens, underscores, @ symbols, periods
31
19
  # - if domain does not begin or end with alphanums.
@@ -34,7 +22,7 @@ module OpenSecret
34
22
  # - if the domain string's length is less than 5
35
23
  # - if "base.opensecret.io" appears twice (or more) in a directory tree
36
24
  #
37
- class Init < Command
25
+ class Init < UseCase
38
26
 
39
27
  attr_writer :master_p4ss, :domain_name, :base_path
40
28
 
@@ -42,9 +30,6 @@ module OpenSecret
42
30
  # The init use case prepares <b>opensecret</b> so that you can <b>open</b> an envelope,
43
31
  # <b>put</b> secrets into it and then <b>seal</b> (lock) it. Locking effectively writes
44
32
  # crypted blocks to both keystore and crypt store.
45
- #
46
- # ops init apollo@work $HOME/apollo.work.drive
47
- #
48
33
  def execute
49
34
 
50
35
  return unless ops_key_exists?