Skip to content

CI/CD Pipelines

A build agent needs the same two things a workstation does: the proxy endpoint for its ecosystem, and an API key. What changes is where the key comes from and how hard you have to work to keep it out of the logs.

The rules that hold across every platform:

  • Store the key in the platform’s secret store, never in the repository or the image.
  • Mask it in logs, and inject it only into the steps that restore packages.
  • Never print an effective package-manager URL. In several ecosystems the credential lives inside the URL, so echoing it prints the key.
  • Prefer a key per pipeline. It makes revocation cheap and the audit trail meaningful.
- name: Setup NuGet
run: |
nuget sources add -name shieldedstack -source <proxy-url>/nuget/v3/index.json
nuget sources update -name shieldedstack -username _ -password ${{ secrets.SHIELDEDSTACK_API_KEY }}
before_script:
- npm config set //<proxy-host-and-port>/npm/:_authToken $SHIELDEDSTACK_API_KEY

Define SHIELDEDSTACK_API_KEY as a masked, protected CI/CD variable.

Store SHIELDEDSTACK_API_KEY in Azure Key Vault or as a pipeline secret, then reference it from the restore step. Secret variables are not passed to scripts automatically, so map it explicitly in the step’s env block.

Store the key in Jenkins Credentials and bind it for the duration of the step:

withCredentials([string(credentialsId: 'shieldedstack-api-key', variable: 'SHIELDEDSTACK_API_KEY')]) {
sh 'dotnet restore'
}

Some ecosystems keep per-machine state that a fresh runner does not have. Dart is the clearest case: the token registration lives on the machine, so it has to run in every job before packages are restored.

- name: Configure Dart package proxy
env:
SHIELDEDSTACK_API_KEY: ${{ secrets.SHIELDEDSTACK_API_KEY }}
PUB_HOSTED_URL: <proxy-url>/dart
run: |
dart pub token add "$PUB_HOSTED_URL" --env-var SHIELDEDSTACK_API_KEY
dart pub get

Go needs its GOPROXY constructed inside the job for the same reason, and Cargo wants CARGO_REGISTRIES_SHIELDEDSTACK_TOKEN in the environment rather than a credentials file. Each ecosystem page has the specifics under Committing the configuration.

After the first run, open Packages in the Control Plane and filter by the project name on the key. If the build succeeded but nothing new appears, the restore did not go through the proxy. Request Logs will show whether any request arrived at all.