Skip to content

Commit e62b977

Browse files
committed
credential-helpers
1 parent d787152 commit e62b977

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

.bazelrc

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ test --test_env=DOCKER_HOST
99
# Disable bzlmod lockfile
1010
common --lockfile_mode=off
1111

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

1518
# Load any settings specific to the current user.
1619
# .bazelrc.user should appear in .gitignore so that settings are not shared with team members

.github/workflows/ci.yaml

+19-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ jobs:
103103
if: matrix.bzlmodEnabled
104104
run: echo "bzlmod_flag=--enable_bzlmod" >> $GITHUB_OUTPUT
105105

106+
- name: Set credential helpers flag
107+
# Add --config needs_credential_helpers to add additional credential helpers
108+
# to fetch from registries with HTTP headers set by credential helpers.
109+
id: set_credential_helper_flag
110+
if: matrix.bazelversion == '6.4.0'
111+
run: echo "credential_helper_flag=--config=needs_credential_helpers" >> $GITHUB_OUTPUT
112+
113+
- name: Setup credential helpers
114+
uses: imjasonh/[email protected]
115+
with:
116+
version: "v0.19.1"
117+
106118
- name: Configure Bazel version
107119
working-directory: ${{ matrix.folder }}
108120
run: echo "${{ matrix.bazelversion }}" > .bazelversion
@@ -146,4 +158,10 @@ jobs:
146158
env:
147159
# Bazelisk will download bazel to here, ensure it is cached between runs.
148160
XDG_CACHE_HOME: ~/.cache/bazel-repo
149-
run: bazel --bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc --bazelrc=.bazelrc test ${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} //...
161+
run: |
162+
bazel \
163+
--bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc \
164+
--bazelrc=.bazelrc \
165+
test //... \
166+
${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} \
167+
${{ steps.set_credential_helper_flag.outputs.credential_helper_flag }}

examples/credential_helper/auth.sh

+28-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#!/usr/bin/env bash
22

33
# Requirements
4-
# - curl
4+
# - crane
55
# - jq
66
# - awk
77
#
88
# ./examples/credential_helper/auth.sh <<< '{"uri":"https://public.ecr.aws/token/?scope\u003drepository:lambda/python:pull\u0026service\u003dpublic.ecr.aws"}'
99
# ./examples/credential_helper/auth.sh <<< '{"uri":"https://public.ecr.aws/v2/lambda/python/manifests/3.11.2024.01.25.10"}'
10+
1011
function log () {
11-
echo "$1" >> /tmp/oci_auth.log
12+
echo $@ >> "/tmp/oci_auth.log"
1213
}
1314

1415
log ""
@@ -20,18 +21,39 @@ log "Payload: $input"
2021
uri=$(jq -r ".uri" <<< $input)
2122
log "URI: $uri"
2223

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

27+
2628
if [[ $input == *"/token"* ]]; then
2729
log "Auth: None"
2830
echo "{}"
29-
exit 0
31+
exit 1
3032
fi
3133

34+
repository=$(awk -F'^https?://|v2/|/manifests|/blobs' '{print $2 $3}' <<< "$uri")
35+
log "Repository: $repository"
36+
37+
38+
ACCEPTED_MEDIA_TYPES='[
39+
"application/vnd.docker.distribution.manifest.v2+json",
40+
"application/vnd.docker.distribution.manifest.list.v2+json",
41+
"application/vnd.oci.image.manifest.v1+json",
42+
"application/vnd.oci.image.index.v1+json"
43+
]'
44+
45+
3246
# This will write the response to stdout in a format that Bazels credential helper protocol understands.
3347
# Since this is called by Bazel, users won't bee seeing output of this.
34-
curl -fsSL https://$host/token | jq '{headers:{"Authorization": [("Bearer " + .token)]}}'
48+
crane auth token "$repository" |
49+
jq --argjson accept "$ACCEPTED_MEDIA_TYPES" \
50+
'{headers: {Authorization: [("Bearer " + .token)], Accept: [($accept | join(", "))], "Docker-Distribution-API-Version": ["registry/2.0"] }}'
51+
52+
if [[ $? != 0 ]]; then
53+
log "Auth: Failed"
54+
exit 1
55+
fi
3556
log "Auth: Complete"
3657

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

oci/private/pull.bzl

+10-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@ _IMAGE_REFERENCE_ATTRS = {
3838
SCHEMA1_ERROR = """\
3939
The registry sent a manifest with schemaVersion=1.
4040
This commonly occurs when fetching from a registry that needs the Docker-Distribution-API-Version header to be set.
41+
See: https://github.com/bazel-contrib/rules_oci/blob/main/docs/pull.md#authentication-using-credential-helpers
4142
"""
4243

4344
OCI_MEDIA_TYPE_OR_AUTHN_ERROR = """\
44-
Unable to retrieve the manifest. This could be due to authentication problems or an attempt to fetch an image with OCI image media types.
45+
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.
46+
See: https://github.com/bazel-contrib/rules_oci/blob/main/docs/pull.md#authentication-using-credential-helpers
47+
"""
48+
49+
OCI_MEDIA_TYPE_OR_AUTHN_ERROR_BAZEL7 = """\
50+
Unable to retrieve the image manifest. This could be due to authentication problems.
4551
"""
4652

4753
# Supported media types
@@ -142,7 +148,9 @@ def _download_manifest(rctx, authn, identifier, output):
142148
explanation = authn.explain()
143149
if explanation:
144150
util.warning(rctx, explanation)
145-
fail(OCI_MEDIA_TYPE_OR_AUTHN_ERROR)
151+
fail(
152+
OCI_MEDIA_TYPE_OR_AUTHN_ERROR_BAZEL7 if versions.is_at_least("7.1.0", versions.get()) else OCI_MEDIA_TYPE_OR_AUTHN_ERROR,
153+
)
146154

147155
return manifest, len(bytes), digest
148156

0 commit comments

Comments
 (0)