Added AWS Credentials Support for Scanning Private Registry (ECR) - #1103
Added AWS Credentials Support for Scanning Private Registry (ECR)#1103VF-mbrauer wants to merge 7 commits into
Conversation
19e1523 to
265aac9
Compare
265aac9 to
1411d12
Compare
|
@VF-mbrauer there's an issue with your |
|
@pschulten, great catch. If have removed the 2 Redundant parentheses as they are not needed. And for the brackets, I fixed that in I have corrected that already and committed d361d7f |
| } else { | ||
| errormsg = err.Error() | ||
| } | ||
| return nil, errors.New((errormsg)) |
There was a problem hiding this comment.
| return nil, errors.New((errormsg)) | |
| return nil, errors.New(errormsg) |
There was a problem hiding this comment.
Done and pushed.
| } | ||
| } | ||
|
|
||
| var creds (ecr_credentials) = ecr_credentials{aws_creds[0][1], aws_creds[0][2]} |
There was a problem hiding this comment.
| var creds (ecr_credentials) = ecr_credentials{aws_creds[0][1], aws_creds[0][2]} | |
| var creds = ecr_credentials{aws_creds[0][1], aws_creds[0][2]} |
There was a problem hiding this comment.
Done and pushed.
|
|
||
| if config.UseECRCredentials() && CheckAwsEcrPrivateRegistry(container.Image) != "" { | ||
|
|
||
| if utils.TokenTTLValidation(EcrTokenGen, TTLResult) { |
There was a problem hiding this comment.
I think its better not to have EcrTokenGen and aws_creds as global variables, I would, I would create ECRRegistry struct as a property of plugin which will encapsulate both properties (EcrTokenGen and aws_creds)
There was a problem hiding this comment.
Agreed and fixed.
| if config.UseECRCredentials() && CheckAwsEcrPrivateRegistry(container.Image) != "" { | ||
|
|
||
| if utils.TokenTTLValidation(EcrTokenGen, TTLResult) { | ||
| EcrTokenGen = time.Now() |
There was a problem hiding this comment.
| EcrTokenGen = time.Now() | |
| EcrTokenGen = p.clock.Now() |
There was a problem hiding this comment.
Agreed and fixed.
| # AWS authorization token is valid for 12 hours by default | ||
| # Unit is hours(h) | ||
| # | ||
| # ecrTokenRefreshTTL = 11h |
There was a problem hiding this comment.
ecrTokenRefreshTTL has to be shorter then 12h? as Trivy might want to authenticate with an expired credential
There was a problem hiding this comment.
Also, maybe a retry logic should be placed for GetAuthorizationToken in case tokens are expired unless we force refresh before 12h
There was a problem hiding this comment.
No, Trivy will never use an expired token as in the original part I pushed, the Token creation was part of "each" individual request Trivy did per repository. The only reason we have this timer now in place is to reduce the number of requests (Throttling) against the ECR-API.
So, if you want to detect an expired token and you want to make it part of a retry to refresh the token now you need to get the first trivy job triggered which tries to get the image and will run into the error.
In this case, a Token Refresh needs to be triggered. But this is a completely new scenario, which needs to be plugged into the trivy process in combination with the PlugIn routines.
Also, a drawback and a negative aspect are here is, that each request needs to be sent towards API to check if still valid or not. But this will be contradicting the Throttling which I wanted to solve.
As of now, I see no point in that we need that. The Throttling does its job, and it is up to the implementer to configure the TTLs on their own. In my view, this is the best approach.
| EcrTokenGen = time.Now() | ||
| aws_creds, err = GetAuthorizationToken(CheckAwsEcrPrivateRegistry(container.Image)) | ||
| if err != nil { | ||
| return corev1.PodSpec{}, nil, err |
There was a problem hiding this comment.
EcrTokenGen should be set to p.clock.Now() only if the GetAuthorizationToken returns no error. to avoid index out of range error in the next authorization cycle as aws_creds will be nil (GetAuthorizationToken will not be called again until TTL expire)
suggestions:
aws_creds, err = GetAuthorizationToken(CheckAwsEcrPrivateRegistry(container.Image))
if err != nil {
return corev1.PodSpec{}, nil, err
}
EcrTokenGen = p.clock.Now()
There was a problem hiding this comment.
Agreed and fixed.
…al Variables and put it into struct. Changed Session NEW deprecation.
| # follow Semantic Versioning. They should reflect the version the application is using. | ||
| appVersion: 0.15.0 | ||
| appVersion: 0.15.1 | ||
|
|
There was a problem hiding this comment.
this file should be restored as it was , we only change versions when we release
There was a problem hiding this comment.
Changed back to normal.
Back to normal before the change as this is part of the release process which will change this values.
There was a problem hiding this comment.
I had a closer look at this PR from the integration stand point and it feels to me overly complex and not easy to maintain. Especially that it requires kiam, which is not actively maintained anymore, and even kiam maintainers suggested switching over to IAM roles for service accounts some time ago.
Besides, my concern is that we cannot provide a real support in case of problems with such implementation, because proposed solution requires configuring Starboard in many places: Trivy plugin config, custom annotation added to each scan job, annotation added the starboard-operator namespace, and IAM Roles.
I missed high level explanation how this solution works, but after spending some time reverse engineering the source code I realized it does the following:
- Retrieve an ECR authorization token based on AWS environment variables that kiam injects by looking at the custom
iam.amazonaws.com/roleannotation added to each scan job. - Pass the authorization token to Trivy with
TRIVY_USERNAME=AWSandTRIVY_PASSWROD=<token>environment variables:TRIVY_USERNAME="AWS" \ TRIVY_PASSWORD="<token>" \ trivy image <image ref>
However, we can accomplish the same by passing AWS environment variables directly to Trivy, which will exchange them for authorization token to pull down an image before scan:
AWS_ACCESS_KEY_ID=*** \
AWS_SECRET_ACCESS_KEY=*** \
AWS_DEFAULT_REGION=eu-central-1 \
trivy image <image ref>
This would not require kiam or any solution like that. The same capability is actually used when you deploy Starboard in EKS as explained on
https://aquasecurity.github.io/starboard/v0.15.4/vulnerability-scanning/managed-registries/#amazon-elastic-container-registry-ecr
Having said that, I would think of a solution that does not require installing and documenting any additional software that's not actively maintained. Ideally Starboard should be self-contained and self-sufficient to perform scans without overly complex configuration.
Notice also, that we've been experimenting with Trivy filesystem scanner to avoid cloud privider-specifi code in Starboard and scan without exchanging credentials. Check our design docs in this repo for more details.
|
@danielpacak I very much share your reluctance to introduce complexity, but using the normal aws sdk credential auth flow for ECR pulls would be very helpful for people running non-EKS cluster (like us 😊) This branch works great for us using our standard node role via the instance profile flow. Ideally we would like to run in |
|
@chen-keinan I guess we can close? Do we? |
Added support for scanning the private registry of AWS-ECR.
Feature still in Beta-mode but usable when prerequisites are met.
Prerequisite:
K8S-Kiam or any other method IRSA (Future) to be used to allow Assuming Instance Roles.
Configurations:
Annotate the Starboard Namespace to be allowed to use KIAM:
Annotations: iam.amazonaws.com/permitted: .*Add the Role you want to Assume which has the proper right to create ECR-Credentials
Configuration in HELM value file to enable the feature
trivy.useEcrRoleCreds: false