Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added AWS Credentials Support for Scanning Private Registry #1062

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 1 addition & 1 deletion deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.9.1
version: 0.9.2

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
3 changes: 3 additions & 0 deletions deploy/helm/templates/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ data:
{{- if .ignoreUnfixed }}
trivy.ignoreUnfixed: {{ .ignoreUnfixed | quote }}
{{- end }}
{{- if .useEcrRoleCreds }}
trivy.useEcrRoleCreds: {{ .useEcrRoleCreds | quote }}
{{- end }}
{{- with .ignoreFile }}
trivy.ignoreFile: |
{{- . | trim | nindent 4 }}
Expand Down
11 changes: 11 additions & 0 deletions deploy/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ trivy:
#
# noProxy:

# Allows to fetch the ECR Login Token if the Service is running in AWS and the EC2-VM has an Instance-Role assigned.
# It also needs k8s KIAM (https://github.com/uswitch/kiam) to be in place which allowed Assuming Roles to specify
# dedicated permissions for the Finale Role which has the rights to get login credentials.
#
# useEcrRoleCreds: false

# Registries without SSL. There can be multiple registries with different keys.
nonSslRegistries: {}
# pocRegistry: poc.myregistry.harbor.com.pl
Expand Down Expand Up @@ -421,6 +427,11 @@ serviceAccount:
# podAnnotations annotations added to the operator's pod
podAnnotations: {}

# podAnnotations example for to get the ECR-Credentials fetch working via AWS-Roles
#
# podAnnotations:
# iam.amazonaws.com/role: <yourRolewithPermissions>

podSecurityContext: {}
# fsGroup: 2000

Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/aquasecurity/starboard
go 1.17

require (
github.com/aws/aws-sdk-go v1.15.11
github.com/caarlos0/env/v6 v6.9.1
github.com/davecgh/go-spew v1.1.1
github.com/go-logr/logr v1.2.0
Expand Down Expand Up @@ -44,6 +45,7 @@ require (
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-ini/ini v1.25.4 // indirect
github.com/go-logr/zapr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
Expand All @@ -60,6 +62,7 @@ require (
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.11 h1:m45+Ru/wA+73cOZXiEGLDH2d9uLN3iHqMc0/z4noDXE=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
Expand Down Expand Up @@ -361,6 +362,7 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
Expand Down Expand Up @@ -501,6 +503,7 @@ github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3i
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
Expand Down Expand Up @@ -573,6 +576,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 h1:SMvOWPJCES2GdFracYbBQh93GXac8fq7HeN6JnpduB8=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
Expand All @@ -588,6 +592,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
Expand Down Expand Up @@ -817,8 +822,10 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
Expand Down
155 changes: 117 additions & 38 deletions pkg/plugin/trivy/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package trivy

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"regexp"
"strings"

"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
Expand All @@ -13,6 +15,10 @@ import (
"github.com/aquasecurity/starboard/pkg/kube"
"github.com/aquasecurity/starboard/pkg/starboard"
"github.com/aquasecurity/starboard/pkg/vulnerabilityreport"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ecr"
"github.com/google/go-containerregistry/pkg/name"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand All @@ -26,6 +32,10 @@ const (
Plugin = "Trivy"
)

const (
AWSECR_Image_Regex = "^\\d+\\.dkr\\.ecr\\.(\\w+-\\w+-\\d+)\\.amazonaws\\.com\\/"
)

const (
keyTrivyImageRef = "trivy.imageRef"
keyTrivyMode = "trivy.mode"
Expand All @@ -42,6 +52,7 @@ const (
keyTrivyGitHubToken = "trivy.githubToken"
keyTrivySkipFiles = "trivy.skipFiles"
keyTrivySkipDirs = "trivy.skipDirs"
keyTrivyUseECRRoleCreds = "trivy.useEcrRoleCreds"

keyTrivyServerURL = "trivy.serverURL"
keyTrivyServerTokenHeader = "trivy.serverTokenHeader"
Expand All @@ -62,6 +73,11 @@ const (
ClientServer Mode = "ClientServer"
)

type ecr_credentials struct {
username string
password string
}

type Command string

const (
Expand Down Expand Up @@ -118,6 +134,11 @@ func (c Config) GetServerURL() (string, error) {
return c.GetRequiredData(keyTrivyServerURL)
}

func (c Config) UseECRCredentials() bool {
_, ok := c.Data[keyTrivyUseECRRoleCreds]
return ok
}

func (c Config) IgnoreFileExists() bool {
_, ok := c.Data[keyTrivyIgnoreFile]
return ok
Expand Down Expand Up @@ -547,31 +568,45 @@ func (p *plugin) getPodSpecForStandaloneMode(ctx starboard.PluginContext, config
})
}

if _, ok := credentials[c.Name]; ok && secret != nil {
registryUsernameKey := fmt.Sprintf("%s.username", c.Name)
registryPasswordKey := fmt.Sprintf("%s.password", c.Name)
if config.UseECRCredentials() {
var aws_creds = GetAuthorizationToken(c.Image)
var creds (ecr_credentials) = ecr_credentials{aws_creds[0][1], aws_creds[0][2]}
Copy link
Contributor

@chen-keinan chen-keinan Mar 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check matrix size both row and column to avoid index out of range


env = append(env, corev1.EnvVar{
Name: "TRIVY_USERNAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
Name: "TRIVY_USERNAME",
Value: creds.username,
})
env = append(env, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
Value: creds.password,
})
} else {
if _, ok := credentials[c.Name]; ok && secret != nil {
registryUsernameKey := fmt.Sprintf("%s.username", c.Name)
registryPasswordKey := fmt.Sprintf("%s.password", c.Name)

env = append(env, corev1.EnvVar{
Name: "TRIVY_USERNAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
},
Key: registryUsernameKey,
},
Key: registryUsernameKey,
},
},
}, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
}, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
},
Key: registryPasswordKey,
},
Key: registryPasswordKey,
},
},
})
})
}
}

env, err = p.appendTrivyInsecureEnv(config, c.Image, env)
Expand Down Expand Up @@ -795,31 +830,45 @@ func (p *plugin) getPodSpecForClientServerMode(ctx starboard.PluginContext, conf
},
}

if _, ok := credentials[container.Name]; ok && secret != nil {
registryUsernameKey := fmt.Sprintf("%s.username", container.Name)
registryPasswordKey := fmt.Sprintf("%s.password", container.Name)
if config.UseECRCredentials() {
var aws_creds = GetAuthorizationToken(container.Image)
var creds (ecr_credentials) = ecr_credentials{aws_creds[0][1], aws_creds[0][2]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check matrix size both row and column to avoid index out of range


env = append(env, corev1.EnvVar{
Name: "TRIVY_USERNAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
Name: "TRIVY_USERNAME",
Value: creds.username,
})
env = append(env, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
Value: creds.password,
})
} else {
if _, ok := credentials[container.Name]; ok && secret != nil {
registryUsernameKey := fmt.Sprintf("%s.username", container.Name)
registryPasswordKey := fmt.Sprintf("%s.password", container.Name)

env = append(env, corev1.EnvVar{
Name: "TRIVY_USERNAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
},
Key: registryUsernameKey,
},
Key: registryUsernameKey,
},
},
}, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
}, corev1.EnvVar{
Name: "TRIVY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Name,
},
Key: registryPasswordKey,
},
Key: registryPasswordKey,
},
},
})
})
}
}

env, err = p.appendTrivyInsecureEnv(config, container.Image, env)
Expand Down Expand Up @@ -1301,3 +1350,33 @@ func constructEnvVarSourceFromConfigMap(envName, trivyConfigName, trivyConfikey
}
return
}

func GetAuthorizationToken(ImageUrl string) [][]string {
svc := ecr.New(session.New(aws.NewConfig().WithRegion(regexp.MustCompile(AWSECR_Image_Regex).FindAllStringSubmatch(ImageUrl, -1)[0][1])))
input := &ecr.GetAuthorizationTokenInput{}

result, err := svc.GetAuthorizationToken(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case ecr.ErrCodeServerException:
fmt.Println(ecr.ErrCodeServerException, aerr.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better pass logger and use it: log.V(1).Error(aerr,ecr.ErrCodeServerException,"error somthing")

case ecr.ErrCodeInvalidParameterException:
fmt.Println(ecr.ErrCodeInvalidParameterException, aerr.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here use logger

default:
fmt.Println(aerr.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here use logger

}
} else {
fmt.Println(err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

}
return nil
}

var credentials = *result.AuthorizationData[0].AuthorizationToken

sDec, _ := base64.StdEncoding.DecodeString(credentials)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error should not be ignored


pattern := regexp.MustCompile("^(AWS):(.+)$")
return pattern.FindAllStringSubmatch(string(sDec), -1)

}