Skip to content

Commit

Permalink
Added support for MFA (#4)
Browse files Browse the repository at this point in the history
* added option to ask for mfa token

* moved ask for mfa to func

* empty line

* fixing travis..

* fixed travis

* updated docs
  • Loading branch information
jkrajniak authored and mescam committed Oct 10, 2019
1 parent 718bc25 commit d05f1d4
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 105 deletions.
17 changes: 9 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
language: go
go:
- 1.x
- 1.11.x
- master
env:
- GO111MODULE=on
git:
depth: 1
before_install:
- curl -L -s https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64
-o $GOPATH/bin/dep
- chmod +x $GOPATH/bin/dep
install:
- dep ensure --vendor-only
notifications:
email: false
install: true
before_script:
- go mod verify
script:
- go test -v ./...
- mkdir bin
Expand All @@ -26,4 +26,5 @@ deploy:
- bin/assume-role-arn-osx
on:
repo: nordcloud/assume-role-arn
tags: true
tags: true

56 changes: 0 additions & 56 deletions Gopkg.lock

This file was deleted.

30 changes: 0 additions & 30 deletions Gopkg.toml

This file was deleted.

2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build:
GOOS=linux go build -o bin/assume-role-arn-linux cmd/assume-role-arn/main.go
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Available flags:
* `-r role_arn` - required, role ARN
* `-e external_id` - optional, if you need to specify external id
* `-n role_session_name` - probably you don't need this
* `-m mfa_serial` - optional, the ARN of MFA virtual device
* `-mfatoken token` - optional, the MFA token
* `-h` - help

## CI/CD pipeline example
Expand All @@ -51,5 +53,13 @@ eval $(assume-role-arn -r arn:aws:iam::ACCOUNT_NUMBER_STG:role/Deployment)

Now you should be able to execute AWS-related commands with your assumed role.

## MFA

If your account is secured with MFA (multi-factor authentication) then you have to provide the ARN of MFA device
and the token:
```
eval $(assume-role-arn -r arn:aws:iam:ACCOUNT_NUMBER_STG:role/Role -m arn:aws:iam::ACCOUNT:mfa/MFA_ID -mfatoken MFATOKEN)
```

## Authors
* Jakub Woźniak, Nordcloud 🇵🇱
46 changes: 35 additions & 11 deletions cmd/assume-role-arn/main.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package main

import (
"bufio"
"flag"
"fmt"
"os"
"os/exec"
"strings"
"syscall"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
)

var roleARN string
var roleName string
var externalID string
var roleARN, roleName, externalID, mfa, mfaToken string

func init() {
flag.StringVar(&roleARN, "role", "", "role arn")
Expand All @@ -26,6 +26,11 @@ func init() {
flag.StringVar(&externalID, "extid", "", "external id")
flag.StringVar(&externalID, "e", "", "external id (shorthand)")

flag.StringVar(&mfa, "mfaserial", "", "mfa serial")
flag.StringVar(&mfa, "m", "", "mfa serial (shorthand)")

flag.StringVar(&mfaToken, "mfatoken", "", "mfa token")

flag.Parse()

if roleARN == "" {
Expand All @@ -43,9 +48,28 @@ func prepareAssumeInput() *sts.AssumeRoleInput {
input.ExternalId = aws.String(externalID)
}

if mfa != "" {
input.SerialNumber = aws.String(mfa)
input.TokenCode = aws.String(mfaToken)
if mfaToken == "" {
input.TokenCode = aws.String(askForMFAToken(roleARN))
}
}

return input
}

func askForMFAToken(roleARN string) string {
// ask for mfa token
reader := bufio.NewReader(os.Stdin)
fmt.Printf("Enter MFA for %s: ", roleARN)
mfaToken, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
return strings.TrimRight(mfaToken, "\n")
}

func getSession() *session.Session {
region := "us-east-1"
sess, err := session.NewSessionWithOptions(session.Options{
Expand All @@ -62,13 +86,9 @@ func getSession() *session.Session {
return sess
}

func assumeRole(sess *session.Session, input *sts.AssumeRoleInput) *sts.AssumeRoleOutput {
func assumeRole(sess *session.Session, input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
svc := sts.New(sess)
out, err := svc.AssumeRole(input)
if err != nil {
panic(err)
}
return out
return svc.AssumeRole(input)
}

func printExport(val *sts.AssumeRoleOutput) {
Expand All @@ -95,9 +115,13 @@ func runCommand(args []string) error {
}

func main() {
toAssume := prepareAssumeInput()
sess := getSession()
role := assumeRole(sess, toAssume)
toAssume := prepareAssumeInput()

role, err := assumeRole(sess, toAssume)
if err != nil {
panic(err)
}

if len(flag.Args()) > 0 {
setEnv(role)
Expand Down
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module github.com/nordcloud/assume-role-arn

go 1.12

require (
github.com/aws/aws-sdk-go v1.15.82
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8
github.com/sirupsen/logrus v1.4.2 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/aws/aws-sdk-go v1.15.82 h1:tvOP/hcmpiUqtqJnU/IwJkqTEfnbsgja0xbPjvZuzbI=
github.com/aws/aws-sdk-go v1.15.82/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

0 comments on commit d05f1d4

Please sign in to comment.