-
Notifications
You must be signed in to change notification settings - Fork 0
/
web_ident.clj
72 lines (68 loc) · 3.43 KB
/
web_ident.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
(ns aerogrant.web-ident
(:require [clojure.java.io :as io]
[cognitect.aws.client.api :as aws]
[cognitect.aws.client.shared :as shared]
[cognitect.aws.credentials :as credentials]
[cognitect.aws.util :as util])
(:import (java.io File)))
(def ^:private sts-client
"An AWS STS client using static, empty credentials."
(aws/client {:api :sts
:credentials-provider (credentials/basic-credentials-provider
{:access-key-id ""
:secret-access-key ""})}))
(defn- assume-role-with-web-identity
"Call AssumeRoleWithWebIdentity on the STS service with `role-arn`,
`session-name`, and `token`, returning the `:Credentials` map if it exists,
otherwise `nil`. Passing `nil` for `session-name` will cause a session name to
be automatically generated."
[role-arn session-name token]
(let [session-name (or session-name
(str "cognitect-aws-api-" (System/currentTimeMillis)))]
(-> (aws/invoke sts-client {:op :AssumeRoleWithWebIdentity
:request {:RoleArn role-arn
:RoleSessionName session-name
:WebIdentityToken token}})
:Credentials)))
(defn web-identity-credentials-provider
"Obtains temporary credentials from STS using the AssumeRoleWithWebIdentity
API call.
The role to assume is expected to be in the environment variable AWS_ROLE_ARN,
and the file containing the web identity token to exchange for the temporary
credentials is expected to be named by the AWS_WEB_IDENTITY_TOKEN_FILE
environment variable. Will optionally use AWS_ROLE_SESSION_NAME from the
environment to name the session, or else a session name will be automatically
generated."
([]
(web-identity-credentials-provider
(util/getenv "AWS_ROLE_ARN")
(util/getenv "AWS_ROLE_SESSION_NAME")
(io/file (util/getenv "AWS_WEB_IDENTITY_TOKEN_FILE"))))
([role-arn session-name ^File token]
(credentials/cached-credentials-with-auto-refresh
(reify credentials/CredentialsProvider
(fetch [_]
(when (and role-arn token (.isFile token) (.canRead token))
(when-let [creds (assume-role-with-web-identity role-arn
session-name
(slurp token))]
(credentials/valid-credentials
{:aws/access-key-id (:AccessKeyId creds)
:aws/secret-access-key (:SecretAccessKey creds)
:aws/session-token (:SessionToken creds)
::credentials/ttl (credentials/calculate-ttl creds)}
"web identity"))))))))
(defn default-credentials-provider
"Like [[credentials/default-credentials-provider]], but with the addition of
[[web-identity-credentials-provider]] in the same position as in the AWS SDK
for Java's default credential provider chain."
([]
(default-credentials-provider (shared/http-client)))
([http-client]
(credentials/chain-credentials-provider
[(credentials/environment-credentials-provider)
(credentials/system-property-credentials-provider)
(web-identity-credentials-provider)
(credentials/profile-credentials-provider)
(credentials/container-credentials-provider http-client)
(credentials/instance-profile-credentials-provider http-client)])))