Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions internal/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,22 @@ func readRoleFromAWS(role string, request *Request) (*iam.Role, error) {
return roleObject, nil
}

func assumeRoleFromAWS(arn string, request *Request) (*sts.AssumeRoleOutput, error) {
func constructAssumeRoleInput(arn string, externalId string) (*sts.AssumeRoleInput) {
if externalId == "" {
return &sts.AssumeRoleInput{
RoleArn: aws.String(arn),
RoleSessionName: aws.String("go-metadataproxy"),
}
}

return &sts.AssumeRoleInput{
ExternalId: aws.String(externalId),
RoleArn: aws.String(arn),
RoleSessionName: aws.String("go-metadataproxy"),
}
}

func assumeRoleFromAWS(arn string, externalId string, request *Request) (*sts.AssumeRoleOutput, error) {
request.log.Infof("Looking for STS Assume Role for %s", arn)

if assumedRole, ok := permissionCache.Get(arn); ok {
Expand All @@ -96,10 +111,7 @@ func assumeRoleFromAWS(arn string, request *Request) (*sts.AssumeRoleOutput, err

request.setLabel("assume_role_from_aws_cache", "miss")
request.log.Infof("Requesting STS Assume Role info for %s from AWS", arn)
req := stsService.AssumeRoleRequest(&sts.AssumeRoleInput{
RoleArn: aws.String(arn),
RoleSessionName: aws.String("go-metadataproxy"),
})
req := stsService.AssumeRoleRequest(constructAssumeRoleInput(arn, externalId))

assumedRole, err := req.Send()
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ func findDockerContainerIAMRole(container *docker.Container, request *Request) (
return "", fmt.Errorf("Could not find IAM_ROLE in the container ENV config")
}

func findDockerContainerExternalId(container *docker.Container, request *Request) string {
v, _ := findDockerContainerEnvValue(container, "IAM_EXTERNAL_ID")
return v
}

func findDockerContainerEnvValue(container *docker.Container, key string) (string, bool) {
for _, envPair := range container.Config.Env {
chunks := strings.SplitN(envPair, "=", 2)
Expand Down
10 changes: 5 additions & 5 deletions internal/http_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func iamInfoHandler(w http.ResponseWriter, r *http.Request) {
}

// read the role from AWS
roleInfo, err := findContainerRoleByAddress(r.RemoteAddr, request)
roleInfo, externalId, err := findContainerRoleByAddress(r.RemoteAddr, request)
if err != nil {
request.setLabels(map[string]string{
"response_code": "404",
Expand All @@ -121,7 +121,7 @@ func iamInfoHandler(w http.ResponseWriter, r *http.Request) {
request.setLabel("role_name", *roleInfo.RoleName)

// assume the role
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, request)
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, externalId, request)
if err != nil {
request.setLabels(map[string]string{
"response_code": "404",
Expand Down Expand Up @@ -173,7 +173,7 @@ func iamSecurityCredentialsName(w http.ResponseWriter, r *http.Request) {
}

// read the role from AWS
roleInfo, err := findContainerRoleByAddress(r.RemoteAddr, request)
roleInfo, _, err := findContainerRoleByAddress(r.RemoteAddr, request)
if err != nil {
request.setLabels(map[string]string{
"response_code": "404",
Expand Down Expand Up @@ -220,7 +220,7 @@ func iamSecurityCredentialsForRole(w http.ResponseWriter, r *http.Request) {
}

// read the role from AWS
roleInfo, err := findContainerRoleByAddress(r.RemoteAddr, request)
roleInfo, externalId, err := findContainerRoleByAddress(r.RemoteAddr, request)
if err != nil {
request.setLabels(map[string]string{
"response_code": "404",
Expand All @@ -245,7 +245,7 @@ func iamSecurityCredentialsForRole(w http.ResponseWriter, r *http.Request) {
}

// assume the container role
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, request)
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, externalId, request)
if err != nil {
request.setLabels(map[string]string{
"response_code": "404",
Expand Down
12 changes: 7 additions & 5 deletions internal/http_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func remoteIP(addr string) string {
return strings.Split(addr, ":")[0]
}

func findContainerRoleByAddress(addr string, request *Request) (*iam.Role, error) {
func findContainerRoleByAddress(addr string, request *Request) (*iam.Role, string, error) {
var container *docker.Container

// retry finding the Docker container since sometimes Docker doesn't actually list the container until its been
Expand All @@ -40,20 +40,22 @@ func findContainerRoleByAddress(addr string, request *Request) (*iam.Role, error

err := backoff.RetryNotify(retryable, b, notify)
if err != nil {
return nil, err
return nil, "", err
}

roleName, err := findDockerContainerIAMRole(container, request)
if err != nil {
return nil, err
return nil, "", err
}

role, err := readRoleFromAWS(roleName, request)
if err != nil {
return nil, err
return nil, "", err
}

return role, nil
externalId := findDockerContainerExternalId(container, request)

return role, externalId, nil
}

func isCompatibleAPIVersion(r *http.Request) bool {
Expand Down