Skip to content

Commit f4499d0

Browse files
authored
Merge pull request #51 from byronwolfman/external-id
Add support for IAM external ID
2 parents 40dbdfc + daf85a3 commit f4499d0

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

internal/aws.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,22 @@ func readRoleFromAWS(role string, request *Request) (*iam.Role, error) {
8585
return roleObject, nil
8686
}
8787

88-
func assumeRoleFromAWS(arn string, request *Request) (*sts.AssumeRoleOutput, error) {
88+
func constructAssumeRoleInput(arn string, externalId string) (*sts.AssumeRoleInput) {
89+
if externalId == "" {
90+
return &sts.AssumeRoleInput{
91+
RoleArn: aws.String(arn),
92+
RoleSessionName: aws.String("go-metadataproxy"),
93+
}
94+
}
95+
96+
return &sts.AssumeRoleInput{
97+
ExternalId: aws.String(externalId),
98+
RoleArn: aws.String(arn),
99+
RoleSessionName: aws.String("go-metadataproxy"),
100+
}
101+
}
102+
103+
func assumeRoleFromAWS(arn string, externalId string, request *Request) (*sts.AssumeRoleOutput, error) {
89104
request.log.Infof("Looking for STS Assume Role for %s", arn)
90105

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

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

104116
assumedRole, err := req.Send()
105117
if err != nil {

internal/docker.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ func findDockerContainerIAMRole(container *docker.Container, request *Request) (
105105
return "", fmt.Errorf("Could not find IAM_ROLE in the container ENV config")
106106
}
107107

108+
func findDockerContainerExternalId(container *docker.Container, request *Request) string {
109+
v, _ := findDockerContainerEnvValue(container, "IAM_EXTERNAL_ID")
110+
return v
111+
}
112+
108113
func findDockerContainerEnvValue(container *docker.Container, key string) (string, bool) {
109114
for _, envPair := range container.Config.Env {
110115
chunks := strings.SplitN(envPair, "=", 2)

internal/http_handler.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func iamInfoHandler(w http.ResponseWriter, r *http.Request) {
105105
}
106106

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

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

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

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

247247
// assume the container role
248-
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, request)
248+
assumeRole, err := assumeRoleFromAWS(*roleInfo.Arn, externalId, request)
249249
if err != nil {
250250
request.setLabels(map[string]string{
251251
"response_code": "404",

internal/http_helper.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func remoteIP(addr string) string {
1717
return strings.Split(addr, ":")[0]
1818
}
1919

20-
func findContainerRoleByAddress(addr string, request *Request) (*iam.Role, error) {
20+
func findContainerRoleByAddress(addr string, request *Request) (*iam.Role, string, error) {
2121
var container *docker.Container
2222

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

4141
err := backoff.RetryNotify(retryable, b, notify)
4242
if err != nil {
43-
return nil, err
43+
return nil, "", err
4444
}
4545

4646
roleName, err := findDockerContainerIAMRole(container, request)
4747
if err != nil {
48-
return nil, err
48+
return nil, "", err
4949
}
5050

5151
role, err := readRoleFromAWS(roleName, request)
5252
if err != nil {
53-
return nil, err
53+
return nil, "", err
5454
}
5555

56-
return role, nil
56+
externalId := findDockerContainerExternalId(container, request)
57+
58+
return role, externalId, nil
5759
}
5860

5961
func isCompatibleAPIVersion(r *http.Request) bool {

0 commit comments

Comments
 (0)