Skip to content

Commit

Permalink
Support aws IAM authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
alexparlett committed Mar 19, 2021
1 parent eb9508d commit 38e0d93
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -7,3 +7,5 @@ pom.xml.asc
*.class
/.lein-*
/.nrepl-port
.idea/
*.iml
32 changes: 32 additions & 0 deletions src/vault/authenticate.clj
Expand Up @@ -132,3 +132,35 @@
:content-type :json
:accept :json
:as :json})))))


(defmethod authenticate* :aws
[client _ credentials]
(let [{:keys [api-path iam-http-request-method iam-request-url iam-request-body
iam-request-headers role]} credentials
api-path (or api-path (str "/v1/auth/aws/" (:auth-mount-point client) "login"))]
(when-not iam-http-request-method
(throw (IllegalArgumentException. "AWS auth credentials must include :iam-http-request-method")))
(when-not iam-request-url
(throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-url")))
(when-not iam-request-body
(throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-body")))
(when-not iam-request-headers
(throw (IllegalArgumentException. "AWS auth credentials must include :iam-request-headers")))
(when-not role
(throw (IllegalArgumentException. "AWS auth credentials must include :role")))
(api-auth!
(str "AWS auth role=" role)
(:auth client)
(api-util/do-api-request
:post (str (:api-url client) api-path)
(merge
(:http-opts client)
{:form-params {:iam_http_request_method iam-http-request-method
:iam_request_url iam-request-url
:iam_request_body iam-request-body
:iam_request_headers iam-request-headers
:role role}
:content-type :json
:accept :json
:as :json})))))
108 changes: 108 additions & 0 deletions test/vault/client/http_test.clj
Expand Up @@ -90,3 +90,111 @@
(vault/authenticate! client :k8s {:jwt "fake-jwt-goes-here"})))
(is (empty? @api-requests))
(is (empty? @api-auths))))))


(deftest authenticate-via-aws
(testing "When all parameters are specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args)
:do-api-request-response)
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args)
:api-auth!-response)]
(vault/authenticate! client :aws {:role "my-role"
:iam-http-request-method "POST"
:iam-request-url "fake.sts.com"
:iam-request-body "FakeAction&Version=1"
:iam-request-headers "{'foo':'bar'}"})
(is (= [[:post
(str example-url "/v1/auth/aws/login")
{:form-params {:iam_http_request_method "POST"
:iam_request_url "fake.sts.com"
:iam_request_body "FakeAction&Version=1"
:iam_request_headers "{'foo':'bar'}"
:role "my-role"}
:content-type :json
:accept :json
:as :json}]]
@api-requests))
(is (= [[(str "AWS auth role=my-role")
(:auth client)
:do-api-request-response]]
@api-auths)))))
(testing "When no iam-http-request-method is specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args))
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args))]
(is (thrown? IllegalArgumentException
(vault/authenticate! client :aws {:role "my-role"
:iam-request-url "fake.sts.com"
:iam-request-body "FakeAction&Version=1"
:iam-request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no iam-request-url is specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args))
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args))]
(is (thrown? IllegalArgumentException
(vault/authenticate! client :aws {:role "my-role"
:iam-http-request-method "POST"
:iam-request-body "FakeAction&Version=1"
:iam-request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no iam-request-body is specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args))
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args))]
(is (thrown? IllegalArgumentException
(vault/authenticate! client :aws {:role "my-role"
:iam-http-request-method "POST"
:iam-request-url "fake.sts.com"
:iam-request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no iam-request-headers is specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args))
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args))]
(is (thrown? IllegalArgumentException
(vault/authenticate! client :aws {:role "my-role"
:iam-http-request-method "POST"
:iam-request-url "fake.sts.com"
:iam-request-body "FakeAction&Version=1"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no role is specified"
(let [client (http-client example-url)
api-requests (atom [])
api-auths (atom [])]
(with-redefs [api-util/do-api-request (fn [& args]
(swap! api-requests conj args))
authenticate/api-auth! (fn [& args]
(swap! api-auths conj args))]
(is (thrown? IllegalArgumentException
(vault/authenticate! client :aws {:iam-http-request-method "POST"
:iam-request-url "fake.sts.com"
:iam-request-body "FakeAction&Version=1"
:iam-request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths))))))

0 comments on commit 38e0d93

Please sign in to comment.