Skip to content

Commit

Permalink
credential-helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed May 29, 2024
1 parent d787152 commit d7d1112
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 11 deletions.
7 changes: 5 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ test --test_env=DOCKER_HOST
# Disable bzlmod lockfile
common --lockfile_mode=off

# TODO(2.0): enable once we drop support for Bazel 5.
# common --credential_helper=public.ecr.aws=%workspace%/examples/credential_helper/auth.sh
# On bazel 6.4.0 these are needed to successfully fetch images.
common:needs_credential_helpers --credential_helper=public.ecr.aws=%workspace%/examples/credential_helper/auth.sh
common:needs_credential_helpers --credential_helper=index.docker.io=%workspace%/examples/credential_helper/auth.sh
common:needs_credential_helpers --credential_helper=docker.elastic.co=%workspace%/examples/credential_helper/auth.sh
common:needs_credential_helpers --credential_helper_cache_duration=0

# 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
21 changes: 20 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ jobs:
if: matrix.bzlmodEnabled
run: echo "bzlmod_flag=--enable_bzlmod" >> $GITHUB_OUTPUT

- name: Set credential helpers flag
# Add --config needs_credential_helpers to add additional credential helpers
# to fetch from registries with HTTP headers set by credential helpers.
id: set_credential_helper_flag
if: matrix.bazelversion == '6.4.0' && matrix.folder == '.'
run: echo "credential_helper_flag=--config=needs_credential_helpers" >> $GITHUB_OUTPUT

- name: Setup credential helpers
uses: imjasonh/setup-crane@v0.3
if: matrix.bazelversion == '6.4.0' && matrix.folder == '.'
with:
version: "v0.19.1"

- name: Configure Bazel version
working-directory: ${{ matrix.folder }}
run: echo "${{ matrix.bazelversion }}" > .bazelversion
Expand Down Expand Up @@ -146,4 +159,10 @@ jobs:
env:
# Bazelisk will download bazel to here, ensure it is cached between runs.
XDG_CACHE_HOME: ~/.cache/bazel-repo
run: bazel --bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc --bazelrc=.bazelrc test ${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} //...
run: |
bazel \
--bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc \
--bazelrc=.bazelrc \
test //... \
${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} \
${{ steps.set_credential_helper_flag.outputs.credential_helper_flag }}
34 changes: 28 additions & 6 deletions examples/credential_helper/auth.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#!/usr/bin/env bash

# Requirements
# - curl
# - crane
# - jq
# - 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
echo $@ >> "/tmp/oci_auth.log"
}

log ""
Expand All @@ -20,18 +21,39 @@ log "Payload: $input"
uri=$(jq -r ".uri" <<< $input)
log "URI: $uri"

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


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

repository=$(awk -F'^https?://|v2/|/manifests|/blobs' '{print $2 $3}' <<< "$uri")
log "Repository: $repository"


ACCEPTED_MEDIA_TYPES='[
"application/vnd.docker.distribution.manifest.v2+json",
"application/vnd.docker.distribution.manifest.list.v2+json",
"application/vnd.oci.image.manifest.v1+json",
"application/vnd.oci.image.index.v1+json"
]'


# 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)]}}'
crane auth token "$repository" |
jq --argjson accept "$ACCEPTED_MEDIA_TYPES" \
'{headers: {Authorization: [("Bearer " + .token)], Accept: [($accept | join(", "))], "Docker-Distribution-API-Version": ["registry/2.0"] }}'

if [[ $? != 0 ]]; then
log "Auth: Failed"
exit 1
fi
log "Auth: Complete"

# Alternatively you can call an external program such as `docker-credential-ecr-login` to perform the token exchange.

# Alternatively you can call an external program such as `docker-credential-ecr-login` to perform the token exchange.
12 changes: 10 additions & 2 deletions oci/private/pull.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@ _IMAGE_REFERENCE_ATTRS = {
SCHEMA1_ERROR = """\
The registry sent a manifest with schemaVersion=1.
This commonly occurs when fetching from a registry that needs the Docker-Distribution-API-Version header to be set.
See: https://github.com/bazel-contrib/rules_oci/blob/main/docs/pull.md#authentication-using-credential-helpers
"""

OCI_MEDIA_TYPE_OR_AUTHN_ERROR = """\
Unable to retrieve the manifest. This could be due to authentication problems or an attempt to fetch an image with OCI image media types.
Unable to retrieve the image manifest. This could be due to authentication problems or an attempt to fetch an image with OCI image media types.
See: https://github.com/bazel-contrib/rules_oci/blob/main/docs/pull.md#authentication-using-credential-helpers
"""

OCI_MEDIA_TYPE_OR_AUTHN_ERROR_BAZEL7 = """\
Unable to retrieve the image manifest. This could be due to authentication problems.
"""

# Supported media types
Expand Down Expand Up @@ -142,7 +148,9 @@ def _download_manifest(rctx, authn, identifier, output):
explanation = authn.explain()
if explanation:
util.warning(rctx, explanation)
fail(OCI_MEDIA_TYPE_OR_AUTHN_ERROR)
fail(
OCI_MEDIA_TYPE_OR_AUTHN_ERROR_BAZEL7 if versions.is_at_least("7.1.0", versions.get()) else OCI_MEDIA_TYPE_OR_AUTHN_ERROR,
)

return manifest, len(bytes), digest

Expand Down

0 comments on commit d7d1112

Please sign in to comment.