diff --git a/.github/workflows/util-probe-npm-oidc-exchange.yml b/.github/workflows/util-probe-npm-oidc-exchange.yml new file mode 100644 index 00000000000..bcbef299f05 --- /dev/null +++ b/.github/workflows/util-probe-npm-oidc-exchange.yml @@ -0,0 +1,61 @@ +name: 'Utility: Probe npm OIDC Exchange' + +on: + workflow_dispatch: + inputs: + package-name: + description: 'Published npm package to test' + required: true + default: '@n8n/typeorm' + type: string + +permissions: {} + +jobs: + probe: + name: Probe npm OIDC exchange + runs-on: ubuntu-latest + environment: npm + permissions: + id-token: write + env: + PACKAGE_NAME: ${{ inputs.package-name }} + steps: + - name: Exchange GitHub OIDC token with npm + shell: bash + run: | + set -euo pipefail + ID_TOKEN_RESPONSE="$RUNNER_TEMP/npm-oidc-id-token.json" + EXCHANGE_RESPONSE="$RUNNER_TEMP/npm-oidc-exchange.json" + trap 'rm -f "$ID_TOKEN_RESPONSE" "$EXCHANGE_RESPONSE"' EXIT + + id_token_status="$(curl --silent --show-error --output "$ID_TOKEN_RESPONSE" --write-out '%{http_code}' --get \ + --header "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + --header 'Accept: application/json' \ + --data-urlencode 'audience=npm:registry.npmjs.org' \ + "$ACTIONS_ID_TOKEN_REQUEST_URL")" + if [ "$id_token_status" != '200' ]; then + echo "::error::GitHub did not issue an OIDC token (HTTP $id_token_status)." + exit 1 + fi + + id_token="$(node --input-type=module -e ' + import { readFileSync } from "node:fs"; + const response = JSON.parse(readFileSync(process.argv[1], "utf8")); + if (typeof response.value !== "string") process.exit(1); + process.stdout.write(response.value); + ' "$ID_TOKEN_RESPONSE")" + package_name="$(node --input-type=module -e 'process.stdout.write(encodeURIComponent(process.env.PACKAGE_NAME))')" + exchange_status="$(curl --silent --show-error --output "$EXCHANGE_RESPONSE" --write-out '%{http_code}' \ + --request POST \ + --header "Authorization: Bearer $id_token" \ + --header 'Accept: application/json' \ + --header 'Content-Length: 0' \ + "https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/$package_name")" + + if [ "$exchange_status" != '201' ]; then + echo "::error::npm OIDC token exchange failed (HTTP $exchange_status)." + exit 1 + fi + + echo 'npm OIDC token exchange succeeded.'