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

doc: explain --credential_helper #485

Merged
merged 2 commits into from
Feb 2, 2024
Merged
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
3 changes: 3 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ build --incompatible_strict_action_env
build --nolegacy_external_runfiles
test --test_env=DOCKER_HOST

# TODO(2.0): enable once we drop support for Bazel 5.
# 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
# This needs to be last statement in this
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
35 changes: 35 additions & 0 deletions docs/pull.md

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

1 change: 0 additions & 1 deletion e2e/wasm/.bazelrc

This file was deleted.

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

# Requirements
# - curl
# - jq
thesayyn marked this conversation as resolved.
Show resolved Hide resolved
# - awk
#
# ./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

# This will write the response to stdout in a format that Bazels credential helper protocol understands.
# Since this is called by Bazel, users won't bee seeing output of this.
curl -fsSL https://$host/token | jq '{headers:{"Authorization": [("Bearer " + .token)]}}'
thesayyn marked this conversation as resolved.
Show resolved Hide resolved
log "Auth: Complete"

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

# Pull an image from public ECR.
# When --credential_helper is provided, see .bazelrc at workspace root, it will take precende over
# auth from oci_pull. However, pulling from public ECR works out of the box so this will never fail
# unless oci_pull's authentication mechanism breaks and --credential_helper is absent.
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 Expand Up @@ -156,7 +170,10 @@ def fetch_images():
# tag = "7.16.2",
image = "docker.elastic.co/kibana/kibana",
digest = "sha256:9a83bce5d337e7e19d789ee7f952d36d0d514c80987c3d76d90fd1afd2411a9a",
platforms = ["linux/amd64"],
platforms = [
"linux/amd64",
"linux/arm64"
],
)

_DEB_TO_LAYER = """\
Expand Down
35 changes: 35 additions & 0 deletions oci/pull.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,41 @@ 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
printed to `stdout` by the external program.

For more information about the credential helpers checkout the [documentation](https://github.com/bazelbuild/proposals/blob/main/designs/2022-06-07-bazel-credential-helpers.md).

See the [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
Loading