Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support aws IAM authentication #50

Merged
merged 5 commits into from Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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-iam
[client _ credentials]
(let [{:keys [api-path http-request-method request-url request-body request-headers
role]} credentials
api-path (or api-path (str "/v1/auth/aws/" (:auth-mount-point client) "login"))]
(when-not http-request-method
(throw (IllegalArgumentException. "AWS auth credentials must include :http-request-method")))
(when-not request-url
(throw (IllegalArgumentException. "AWS auth credentials must include :request-url")))
(when-not request-body
(throw (IllegalArgumentException. "AWS auth credentials must include :request-body")))
(when-not request-headers
(throw (IllegalArgumentException. "AWS auth credentials must include :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 http-request-method
:iam_request_url request-url
:iam_request_body request-body
:iam_request_headers request-headers
:role role}
:content-type :json
:accept :json
:as :json})))))
4 changes: 2 additions & 2 deletions src/vault/client/http.clj
Expand Up @@ -144,8 +144,8 @@

(revoke-token!
[this]
(when-let [token (:client-token @auth)]
(.revoke-token! this token)))
(let [response (api-util/api-request this :post "auth/token/revoke-self" {})]
(= 204 (:status response))))
alexparlett marked this conversation as resolved.
Show resolved Hide resolved


(revoke-token!
Expand Down
3 changes: 2 additions & 1 deletion src/vault/core.clj
Expand Up @@ -20,7 +20,8 @@
- `:ldap {:username \"LDAP username\", :password \"hunter2\"}`
- `:k8s {:jwt \"...\", :role \"...\"}`
- `:app-id {:app \"foo-service-dev\", :user \"...\"}`
- `:app-role {:role-id \"...\", :secret-id \"...\"}")
- `:app-role {:role-id \"...\", :secret-id \"...\"}
- `:aws-iam {:http-request-method \"...\", :request-url \"...\", :request-body \"...\", :request-headers \"...\", :role \"...\"}`")

(status
[client]
Expand Down
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
alexparlett marked this conversation as resolved.
Show resolved Hide resolved
(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-iam {:role "my-role"
:http-request-method "POST"
:request-url "fake.sts.com"
:request-body "FakeAction&Version=1"
: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 (= [["AWS auth role=my-role"
(:auth client)
:do-api-request-response]]
@api-auths)))))
(testing "When no 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-iam {:role "my-role"
:request-url "fake.sts.com"
:request-body "FakeAction&Version=1"
:request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no 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-iam {:role "my-role"
:http-request-method "POST"
:request-body "FakeAction&Version=1"
:request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no 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-iam {:role "my-role"
:http-request-method "POST"
:request-url "fake.sts.com"
:request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths)))))
(testing "When no 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-iam {:role "my-role"
:http-request-method "POST"
:request-url "fake.sts.com"
: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"
:request-url "fake.sts.com"
:request-body "FakeAction&Version=1"
:request-headers "{'foo':'bar'}"})))
(is (empty? @api-requests))
(is (empty? @api-auths))))))