Skip to content

Commit a0a546c

Browse files
committed
[skip ci] Escalate role_arn with STS
1 parent d5e576c commit a0a546c

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

Rome.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ library
4141
, amazonka >= 1.6.1
4242
, amazonka-core >= 1.6.1
4343
, amazonka-s3 >= 1.6.1
44+
, amazonka-sts >= 1.6.1
4445
, exceptions >= 0.8
4546
, lens >= 4.13
4647
, parsec >= 3.1.10

src/Lib.hs

+38-11
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import qualified Network.AWS.Env as AWS (Env (..), retryConnectionF
4848
import qualified Network.AWS.Data as AWS (fromText)
4949
import qualified Network.AWS.Data.Sensitive as AWS (Sensitive (..))
5050
import qualified Network.AWS.S3 as S3
51+
import qualified Network.AWS.STS.AssumeRole as STS (assumeRole, arrsCredentials)
5152
import qualified Network.AWS.Utils as AWS
5253
import qualified Network.HTTP.Conduit as Conduit
5354

@@ -73,6 +74,18 @@ s3EndpointOverride (URL (Absolute h) _ _) =
7374
S3.s3
7475
s3EndpointOverride _ = S3.s3
7576

77+
-- | Tries to get authentication details and region to perform
78+
-- | requests to AWS.
79+
-- | The `AWS_PROFILE` is read from the environment
80+
-- | or falls back to `default`.
81+
-- | The `AWS_REGION` is first read from the environment, if not found
82+
-- | it is read from `~/.aws/config` based on the profile discovered in the previous step.
83+
-- | The `AWS_ACCESS_KEY_ID` & `AWS_SECRET_ACCESS_KEY` are first
84+
-- | read from the environment. If not found, then the `~/.aws/crendetilas`
85+
-- | file is read. If `source_profile` key is present the reading of the
86+
-- | authentication details happens from this profile rather then the `AWS_PROFILE`.
87+
-- | Finally, if `role_arn` is specified, the crendials gathered up to now are used
88+
-- | to obtain new credentials with STS esclated to `role_arn`.
7689
getAWSEnv :: (MonadIO m, MonadCatch m) => ExceptT String m AWS.Env
7790
getAWSEnv = do
7891
region <- discoverRegion
@@ -106,19 +119,33 @@ getAWSEnv = do
106119
manager <- liftIO (Conduit.newManager Conduit.tlsManagerSettings)
107120
ref <- liftIO (newIORef Nothing)
108121
let roleARN = eitherToMaybe $ AWS.roleARNOf profile =<< credentials
122+
let curerntEnv = AWS.Env region
123+
(\_ _ -> pure ())
124+
(AWS.retryConnectionFailure 3)
125+
mempty
126+
manager
127+
ref
128+
auth
109129
case roleARN of
110-
Just role -> do
111-
undefined -- Make request to STS
130+
Just role -> newEnvFromRole role curerntEnv
131+
Nothing -> return
132+
$ AWS.configure (maybe S3.s3 s3EndpointOverride endpointURL) curerntEnv
133+
134+
newEnvFromRole :: MonadIO m => T.Text -> AWS.Env -> ExceptT String m AWS.Env
135+
newEnvFromRole roleARN currentEnv = do
136+
assumeRoleResult <-
137+
liftIO
138+
$ AWS.runResourceT
139+
. AWS.runAWS currentEnv
140+
$ AWS.send
141+
$ STS.assumeRole roleARN "rome-cache-operation"
142+
let maybeAuth = AWS.Auth <$> assumeRoleResult ^. STS.arrsCredentials
143+
case maybeAuth of
112144
Nothing ->
113-
let env = AWS.Env region
114-
(\_ _ -> pure ())
115-
(AWS.retryConnectionFailure 3)
116-
mempty
117-
manager
118-
ref
119-
auth
120-
in return
121-
$ AWS.configure (maybe S3.s3 s3EndpointOverride endpointURL) env
145+
throwError
146+
$ "Could not create AWS Auth from STS response: "
147+
++ show assumeRoleResult
148+
Just newAuth -> return $ currentEnv & AWS.envAuth .~ newAuth
122149

123150
getAWSRegion :: (MonadIO m, MonadCatch m) => ExceptT String m AWS.Env
124151
getAWSRegion = do

0 commit comments

Comments
 (0)