-
Notifications
You must be signed in to change notification settings - Fork 0
/
aws_ssm_ps.clj
116 lines (104 loc) · 3.95 KB
/
aws_ssm_ps.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/
(ns dev.gethop.secrets-storage.aws-ssm-ps
(:require [amazonica.aws.simplesystemsmanagement :as ssm]
[amazonica.core :refer [ex->map]]
[clojure.spec.alpha :as s]
[dev.gethop.secrets-storage.core :as core]
[integrant.core :as ig]))
(s/def ::aws-kms-key string?)
(s/def ::user-keys-path string?)
(s/def ::AWSConfig (s/keys :req-un [::aws-kms-key ::user-keys-path]))
(defn- get-user-key-path
"Build the path in Parameter Store for `user-id` user key"
[config user-id]
{:pre [(and (s/valid? ::AWSConfig config)
(s/valid? ::core/user-id user-id))]}
(format (:user-keys-path config) user-id))
(s/def ::get-user-key-path-args (s/cat :config ::AWSConfig :user-id ::core/user-id))
(s/def ::get-user-key-path-ret string?)
(s/fdef get-user-key-path
:args ::get-user-key-path-args
:ret ::get-user-key-path-ret)
(defn- get-crypt-key
"Get encryption key for user `user-id` from Parameter Store."
[{:keys [config]} user-id]
{:pre [(and (s/valid? ::AWSConfig config)
(s/valid? ::core/user-id user-id))]}
(try
(let [crypt-key (->
(ssm/get-parameter
{:name (get-user-key-path config user-id)
:with-decryption true})
(get-in [:parameter :value]))]
(if crypt-key
{:success? true
:key (core/deserialize crypt-key)}
{:success? false
:error-details {:error-code "CryptKeyNotFound"}}))
(catch com.amazonaws.AmazonServiceException e
{:success? false
:error-details (ex->map e)})
(catch Exception e
{:success? false
:error-details (.getMessage e)})))
(s/fdef get-crypt-key
:args ::core/get-key-args
:ret ::core/get-key-ret)
(defn- put-crypt-key
"Put encryption key `crypt-key` for user `user-id` in Parameter Store."
[{:keys [config]} user-id crypt-key]
{:pre [(and (s/valid? ::AWSConfig config)
(s/valid? ::core/user-id user-id)
(s/valid? ::core/crypt-key crypt-key))]}
(try
(let [result (ssm/put-parameter
{:name (get-user-key-path config user-id)
:type "SecureString"
:overwrite true
:key-id (:aws-kms-key config)
:value (core/serialize crypt-key)})]
(if result
{:success? true}
{:success? false
:error-details {:error-code "UnknownError"}}))
(catch com.amazonaws.AmazonServiceException e
{:success? false
:error-details (ex->map e)})
(catch Exception e
{:success? false
:error-details (.getMessage e)})))
(s/fdef put-crypt-key
:args ::core/put-key-args
:ret ::core/put-key-ret)
(defn- delete-crypt-key
"Delete encryption key for user `user-id` from Parameter Store."
[{:keys [config]} user-id]
{:pre [(and (s/valid? ::AWSConfig config)
(s/valid? ::core/user-id user-id))]}
(try
(let [result (ssm/delete-parameter {:name (get-user-key-path config user-id)})]
(if result
{:success? true}
{:success? false
:error-details {:error-code "UnknownError"}}))
(catch com.amazonaws.AmazonServiceException e
{:success? false
:error-details (ex->map e)})
(catch Exception e
{:success? false
:error-details (.getMessage e)})))
(s/fdef delete-crypt-key
:args ::core/delete-key-args
:ret ::core/delete-key-ret)
(defrecord AWSParameterStore [config]
core/UserEncryptionKeyStore
(get-key [this user-id]
(get-crypt-key this user-id))
(put-key [this user-id encryption-key]
(put-crypt-key this user-id encryption-key))
(delete-key [this user-id]
(delete-crypt-key this user-id)))
(defmethod ig/init-key :dev.gethop.secrets-storage/aws-ssm-ps [_ config]
(->AWSParameterStore config))