Skip to content

Commit 5a8c367

Browse files
committed
ci: add JFrog Artifactory proxy for npm registry access
Hardened runners block direct access to public registries. Configure JFrog Artifactory as an npm proxy using OIDC token exchange per the remote registry access guidance. Added to all jobs that run `npm ci`: lint, unit-test, e2e-test (main.yml) and build (release.yml). The coverage job and dco-check workflow do not access npm and are left unchanged. Adds `id-token: write` permission for the OIDC token exchange. Co-authored-by: Isaac
1 parent ad37a31 commit 5a8c367

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

.github/workflows/main.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010

1111
permissions:
1212
contents: read
13+
id-token: write
1314

1415
jobs:
1516
lint:
@@ -18,6 +19,33 @@ jobs:
1819
labels: linux-ubuntu-latest
1920
steps:
2021
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
22+
- name: Get JFrog OIDC token
23+
run: |
24+
set -euo pipefail
25+
ID_TOKEN=$(curl -sLS \
26+
-H "User-Agent: actions/oidc-client" \
27+
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
28+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"')
29+
echo "::add-mask::${ID_TOKEN}"
30+
ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \
31+
"https://databricks.jfrog.io/access/api/v1/oidc/token" \
32+
-d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"')
33+
echo "::add-mask::${ACCESS_TOKEN}"
34+
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
35+
echo "FAIL: Could not extract JFrog access token"
36+
exit 1
37+
fi
38+
echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV"
39+
echo "JFrog OIDC token obtained successfully"
40+
- name: Configure npm for JFrog
41+
run: |
42+
set -euo pipefail
43+
cat > ~/.npmrc << EOF
44+
registry=https://databricks.jfrog.io/artifactory/api/npm/db-npm/
45+
//databricks.jfrog.io/artifactory/api/npm/db-npm/:_authToken=${JFROG_ACCESS_TOKEN}
46+
always-auth=true
47+
EOF
48+
echo "npm configured to use JFrog registry"
2149
- name: Cache node modules
2250
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
2351
env:
@@ -57,6 +85,33 @@ jobs:
5785
uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4
5886
with:
5987
python-version: '3.10'
88+
- name: Get JFrog OIDC token
89+
run: |
90+
set -euo pipefail
91+
ID_TOKEN=$(curl -sLS \
92+
-H "User-Agent: actions/oidc-client" \
93+
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
94+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"')
95+
echo "::add-mask::${ID_TOKEN}"
96+
ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \
97+
"https://databricks.jfrog.io/access/api/v1/oidc/token" \
98+
-d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"')
99+
echo "::add-mask::${ACCESS_TOKEN}"
100+
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
101+
echo "FAIL: Could not extract JFrog access token"
102+
exit 1
103+
fi
104+
echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV"
105+
echo "JFrog OIDC token obtained successfully"
106+
- name: Configure npm for JFrog
107+
run: |
108+
set -euo pipefail
109+
cat > ~/.npmrc << EOF
110+
registry=https://databricks.jfrog.io/artifactory/api/npm/db-npm/
111+
//databricks.jfrog.io/artifactory/api/npm/db-npm/:_authToken=${JFROG_ACCESS_TOKEN}
112+
always-auth=true
113+
EOF
114+
echo "npm configured to use JFrog registry"
60115
- name: Cache node modules
61116
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
62117
with:
@@ -96,6 +151,33 @@ jobs:
96151

97152
steps:
98153
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
154+
- name: Get JFrog OIDC token
155+
run: |
156+
set -euo pipefail
157+
ID_TOKEN=$(curl -sLS \
158+
-H "User-Agent: actions/oidc-client" \
159+
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
160+
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"')
161+
echo "::add-mask::${ID_TOKEN}"
162+
ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \
163+
"https://databricks.jfrog.io/access/api/v1/oidc/token" \
164+
-d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"')
165+
echo "::add-mask::${ACCESS_TOKEN}"
166+
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
167+
echo "FAIL: Could not extract JFrog access token"
168+
exit 1
169+
fi
170+
echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV"
171+
echo "JFrog OIDC token obtained successfully"
172+
- name: Configure npm for JFrog
173+
run: |
174+
set -euo pipefail
175+
cat > ~/.npmrc << EOF
176+
registry=https://databricks.jfrog.io/artifactory/api/npm/db-npm/
177+
//databricks.jfrog.io/artifactory/api/npm/db-npm/:_authToken=${JFROG_ACCESS_TOKEN}
178+
always-auth=true
179+
EOF
180+
echo "npm configured to use JFrog registry"
99181
- name: Cache node modules
100182
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
101183
with:

0 commit comments

Comments
 (0)