Jib: how to use amazon-ecr-credential-helper without installing it?
Asked Answered
D

2

7

When using jib-gradle-plugin to build and push to AWS ECR, it requires me to install aws ecr credential helper otherwise the build complains "The system does not have docker-credential-ecr-login CLI".

I am wondering if there is a way to push to AWS ECR without installing the credential helper, or if it is possible to bundle a portable version of the credential helper in the repo?

The issues with installing the helper are:

  1. it requires the helper to be installed on every machine where the project needs to be built, hence making the build flow not as automated as I would like
  2. To install the aws ecr credential helper, it requires Docker to be installed. This feels a bit ironic because a large part of the point of Jib is that no Docker is needed on the host where the build happens, hence the build can be self-contained and portable.

I know this is not a Jib issue but I am just hoping whoever using Jib might have run into similar challenges and therefore can offer some insights of how to work around it.

Detonator answered 26/9, 2020 at 6:59 Comment(0)
C
8

In the end, authenticating with a registry all boils down to providing a simple username/password string pair to Jib. Once Jib retrieves the pair, Jib just passes the username and password string literals to a server as-is without any processing at all. (BTW, this mechanism isn't specific to Jib; every Docker registry works this way.) It is that simple: a username and password pair is all that matters.

Using a Docker credential helper is no different than providing this string pair through a CLI. Any credential helper will output a username and a password with the "get" command. For example with Google Container Registry,

$ docker-credential-gcr get <<<gcr.io
{"ServerURL":"","Username":"... this is the username ...","Secret":"... this is the password ..."}

So, theoretically you can write a dumb script or binary that always outputs some username/password, name the file docker-credential-my-dumb-script, and configure jib.{from|to}.credHelper='my-dumb-script'. I wouldn't do it though; this is just to highlight that registry auth is only a matter of providing a username and password pair to Jib.

However, note that many credential helpers dynamically generate short-lived credentials that expire soon, which are much more secure than using static and permanent credentials. This is one of the reasons we generally recommend using a credential helper whenever possible. It could also be that some cloud registries accept only these short-lived credentials generated by their credential helpers.

Another example is docker login. For example, successfully logging in with docker login chanseoktest.azurecr.io -u my-username -p my-password simply results in recording my-username and my-password in ~/.docker/config.json:

    "auths": {
        "chanseoktest.azurecr.io": {
            # <username>:<password> in PLAIN string in base64 encoded form
            "auth": "bXktdXNlcm5hbWU6bXktcGFzc3dvcmQ="
        },

(If you do base64-decode on bXktdXNlcm5hbWU6bXktcGFzc3dvcmQ=, it results in my-username:my-password in plain string.) This means that, if you can make docker pull/push work on some system, Jib will also work (as Jib looks into ~/.docker/config.json). Therefore, another way to provide credentials to Jib would be to create a working ~/.docker/config.json on the system (or you could copy it from another system where you successfully ran docker login). This approach, I wouldn't do either unless this can be done securely.

For yet another example, instead of the dumb credential helper or ~/.docker/config indirection, you can also directly pass your credentials to Jib via jib.{from|to}.auth.{username|password} (which can also be set through the corresponding system properties with, e.g., -Djib.from.auth.username=...). We don't recommend this either as long as you can use a credential helper. Be aware that if you pass credentials on the command-line, other users on the same system can see the command (including the credentials), not to mention that commands can be logged or stored in a shell history. In certain environments, this command-line risk may be mitigated if you store these credentials in some environment variables and you modify your build.gradle or pom.xml to read jib.{from|to}.auth.{username|password} from the environment variables.

For the complete list of ways you can provide a username/password pair, you can consult the official FAQ.

Also do note that what you believe a correct username and password pair may not be the one that your registry actually accepts. For example, this AWS ECR user mistakenly assumed that they could use an "AWS ECR key user" (whatever it is) as a username, whereas in reality, docker-credential-ecr-login returned AWS as a username. (Not that you always have to use AWS as a username; ECR may (or may not) have multiple forms of acceptable credentials.)

Lastly, I would confirm with the AWS ECR community or the community of the platform where you're using Jib to figure out which credential form would be best to use as a username and password pair to "login to Docker" if you cannot use a credential helper. For example, for GitHub Actions, previously I successfully used aws-actions/amazon-ecr-login.

Cantaloupe answered 28/9, 2020 at 15:55 Comment(2)
"which are much more secure than using static and permanent credentials" -> Really? why as I am still using permanent credentials to fetch the temporary token? and I still have to put the permanent credentials in CI to fetch the token every time. I have been curious about this for a while and how it is more secure.Fireguard
@DeanHiller 1. some attacks (e.g., breachattack.com) are targeting in transit secrets even if those are encrypted (not all encrypted comms guaranty perfect forward secrecy). Making the secrets change periodically, combined with other measures (e.g., rate limiting) can help reducing such risks, while different measures are needed to protect the secrets at rest. 2. Using short lived tokens with refresh mechanism allows better auditing capabilities (who used this old access key?!) and fine grained control for revoking specific keys in case those are compromised. IANAL (nor CISO)...Now
R
1

You don't need docker to be installed to have the amazon-ecr-credential-helper working with Jib. Jib will just automatically pick the credentials and use them to push the image without docker.

You just need to use setCredHelper("ecr-login") in the jib plugin config like:

Ranaerancagua answered 29/8, 2023 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.