Add IAM Role support for S3 authentication on AWS servers
I'm deploying Mattermost on AWS using IAM Roles to provide temporary credentials to the instances. I was hoping it would work out of the box and, when it didn't, I created a script to retrieve the temporary credentials periodically and update the Mattermost config.json with the credentials so it can store files in S3. However, the config only supports AccessKeyId and SecretAccessKey. The temporary credentials require the inclusion of a Session Token as well.
I see two possible solutions to this:
The simple solution would be to add an optional AmazonS3SessionToken configuration option in the FileSettings and update the authentication to provide this value if it exists.
The better solution, in my mind, would be to have Mattermost natively support credential lookup for AWS instance roles, managing the token expiration and auth configuration internally so temporary credentials are not exposed in the System Console or config.json file. Not sure if goamz supports this natively or if it would be a solution like providing the role name in config.json and having Mattermost retrieve the credentials.
Mattermost v4.9 and later now supports AWS Identity and Access Management (IAM) roles for Amazon S3 file storage.
Thanks everyone for voting this feature!
-
Steven Aerts commented
I took a look the source code and I think this trivial to fix/implement.
As it is not clear for me how exactly to submit a pull request, I dump it here.
Let me know if you prefer to have it in another way:
diff --git a/api/file.go b/api/file.go
index 1136662..9b24638 100644
--- a/api/file.go
+++ b/api/file.go
@@ -539,9 +539,10 @@ func generatePublicLinkHash(filename, salt string) string {
func WriteFile(f []byte, path string) *model.AppError {
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
- var auth aws.Auth
- auth.AccessKey = utils.Cfg.FileSettings.AmazonS3AccessKeyId
- auth.SecretKey = utils.Cfg.FileSettings.AmazonS3SecretAccessKey
+ auth, err := aws.getAuth(utils.Cfg.FileSettings.AmazonS3AccessKeyId, utils.Cfg.FileSettings.AmazonS3SecretAccessKey)
+ if err != nil {
+ return err
+ }
s := s3.New(auth, awsRegion())
bucket := s.Bucket(utils.Cfg.FileSettings.AmazonS3Bucket) -
Gordon Shankman commented
Originally posted as a GitHub issue: https://github.com/mattermost/platform/issues/1797