Skip to content

Commit

Permalink
doc: explain --credential_helper
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed Feb 1, 2024
1 parent 7fd5e63 commit 177cb5b
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 1 deletion.
1 change: 1 addition & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
build --incompatible_strict_action_env
build --nolegacy_external_runfiles
test --test_env=DOCKER_HOST
common --credential_helper=public.ecr.aws=%workspace%/examples/credential_helper/auth.sh

# Load any settings specific to the current user.
# .bazelrc.user should appear in .gitignore so that settings are not shared with team members
Expand Down
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
6.2.0
6.4.0

# The first line of this file is used by Bazelisk and Bazel to be sure
# the right version of Bazel is used to build and test this repo.
Expand Down
33 changes: 33 additions & 0 deletions docs/pull.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions examples/credential_helper/auth.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash

# Requirements
# - curl
# - jq
#
# ./examples/credential_helper/auth.sh <<< '{"uri":"https://public.ecr.aws/token/?scope\u003drepository:lambda/python:pull\u0026service\u003dpublic.ecr.aws"}'
# ./examples/credential_helper/auth.sh <<< '{"uri":"https://public.ecr.aws/v2/lambda/python/manifests/3.11.2024.01.25.10"}'
function log () {
echo "$1" >> /tmp/oci_auth.log
}

log ""
log "Authenticating"

input=$(cat)
log "Payload: $input"

uri=$(jq -r ".uri" <<< $input)
log "URI: $uri"

host="$(echo $uri | awk -F[/:] '{print $4}')"
log "Host: $host"

if [[ $input == *"/token"* ]]; then
log "Auth: None"
echo "{}"
exit 0
fi

curl -fsSL https://$host/token | jq '{headers:{"Authorization": [("Bearer " + .token)]}}'
log "Auth: Complete"

# Alternatively you can call an external program such as `docker-credential-ecr-login` to perform the token exchange.
11 changes: 11 additions & 0 deletions fetch.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ def fetch_images():
],
)

# ECR public registry
oci_pull(
name = "ecr_lambda_python",
image = "public.ecr.aws/lambda/python",
tag = "3.11.2024.01.25.10",
platforms = [
"linux/amd64",
"linux/arm64/v8"
]
)

# Show that the digest is optional.
# In this case, the dependency is "floating" and our build could break when a new
# image is pushed to gcr.io with the 'debug' tag, so we document this by setting
Expand Down
33 changes: 33 additions & 0 deletions oci/pull.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,39 @@ Set `--repo_env=DOCKER_CONFIG=/some/other/directory` to cause `oci_pull` to look
Finally, some less-common use cases are afforded with environment variables `XDG_RUNTIME_DIR` and `REGISTRY_AUTH_FILE`.
See the implementation of `_get_auth_file_path` in `/oci/private/auth_config_locator.bzl` for the complete reference.
# Authentication using credential helpers
By default oci_pull try to mimic `docker pull` authentication mechanism to allow users simply use `docker login` for authentication.
However, this doesn't always work due to some limitations of Bazel where response headers can't be read, which prevents us from
performing `WWW-Authenticate` challenges, as we don't know which endpoint to hit to complete the challenge. To workaround this
we keep a map of known registries that require us to perform www-auth challenge to acquire a temporary token for authentication.
Fortunately, Bazel supports running external programs to authenticate http requests using the `--credential_helper` command line flag.
When the credential helper flag passed, Bazel will call the external program before sending the request to allow additional headers to be set.
An example of this
.bazelrc
```
common --credential_helper=public.ecr.aws=%workspace%/tools/auth.sh
```
tools/auth.sh
```bash
input=$(cat)
uri=$(jq -r ".uri" <<< $input)
host="$(echo $uri | awk -F[/:] '{print $4}')"
curl -fsSL https://$host/token | jq '{headers:{"Authorization": [("Bearer " + .token)]}}'
```
This tells bazel to run `%workspace%/tools/auth.sh` for any request sent to `public.ecr.aws` and add additional headers that may have been
returned by the external program.
See [examples/credential_helper](/examples/credential_helper/auth.sh) directory for an example of how this work.
"""

load("//oci/private:pull.bzl", "oci_alias", _oci_pull = "oci_pull")
Expand Down
1 change: 1 addition & 0 deletions oci/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ build_test(
"@gitlab_assets_ce",
# TODO: https://github.com/bazel-contrib/rules_oci/issues/193
# "@apollo_router",
"@ecr_lambda_python",
"@from_rules_docker",
"@ubuntu",
"@es_kibana_image",
Expand Down

0 comments on commit 177cb5b

Please sign in to comment.