Skip to content

Harden CI: Artifactory OIDC via sdk-actions, NuGet lockfiles, scoped build - #146

Merged
MichaelGHSeg merged 8 commits into
mainfrom
ci/harden-build-publish
Sep 30, 2026
Merged

MichaelGHSeg merged 8 commits into
mainfrom
ci/harden-build-publish

Conversation

@MichaelGHSeg

@MichaelGHSeg MichaelGHSeg commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Routes CI dependency resolution through curated Artifactory using OIDC, with no stored credentials. CI is green.

Supply chain

  • Artifactory OIDC via the shared first-party twilio/sdk-actions/artifactory-oidc (ecosystem: dotnet), replacing a repo-local copy. Fixes land once across the SDKs rather than seven times.
  • NuGet lockfiles committed, restored with --locked-mode. They record package identity and hash only — no source URLs — so they resolve identically from Artifactory in CI and from nuget.org locally.
  • SHA-pinned actions and tightened workflow permissions; github.ref_name passed via env var rather than interpolated into a shell command.

Publishing

deploy.yml uses environment: deployment, which is where NUGET_API_KEY actually lives. It previously named nuget, an environment that does not exist — GitHub silently creates one on first reference with no protection rules, so the secret would have been unreachable and the job unreviewed.

Build correctness

Three problems that only became visible once the OIDC exchange started succeeding:

  • setup-dotnet pinned 8.0.x while Tests targets net10.0;net6.0. That only ever worked because the runner image happens to ship SDK 10. Both runtimes are now installed so both legs execute.
  • Tests/packages.lock.json knew only net6.0 and .NETFramework,v4.6 — which nothing targets — so --locked-mode refused with NU1004. Regenerated to match the project.
  • Restore, build and test are scoped via Analytics-CSharp.slnf to the library and its tests. The .sln also lists sample projects, several of them legacy msbuild Xamarin and Unity ones that dotnet cannot restore or build on a Linux runner at all.

Verified locally before pushing: locked-mode restore succeeds, build succeeds, 269 tests pass.

Not changed

The published package still targets netstandard1.3;netstandard2.0. Nothing here alters what consumers can install.

Worth flagging separately: Newtonsoft.Json 9.0.1 arrives transitively via the 2021-era test SDK and carries a high-severity advisory (GHSA-5crp-9r3c-p9vr). It passes curation today; bumping the test SDK would clear it.

- Add Artifactory OIDC composite action (configures NuGet to use virtual-nuget-thirdparty)
- Add ci.yml: fork-aware, dotnet build/test, --locked-mode, SHA-pinned actions
- Add deploy.yml: tag-triggered, environment: nuget gate, tightened permissions
- Add Directory.Build.props to enable NuGet lockfiles repo-wide
- Add packages.lock.json for Analytics-CSharp and Tests projects
- Update e2e-tests.yml: remove E2E_TESTS_TOKEN, fork-aware
Comment thread .github/workflows/deploy.yml
didiergarcia
didiergarcia previously approved these changes Jul 10, 2026
Rewrite composite action to use single-script pattern matching
analytics-python: audience=${ARTIFACTORY_URL}, provider_name=
github-actions-segmentio, and add JWT claim logging for debugging.
Replaces the repo-local copy with the shared first-party action, pinned. Each
SDK had its own drifting copy of the same exchange; the shared one covers every
ecosystem we use, so fixes land once instead of six times.
The job declared 'nuget', which does not exist. NUGET_API_KEY is an environment
secret on 'deployment', and environment secrets are only visible to jobs using
that exact environment — so secrets.NUGET_API_KEY resolved to empty and GitHub
silently created an unprotected 'nuget' environment on first run.

Pointing at 'deployment' rather than renaming keeps the existing secret in
place; its value cannot be read back to recreate it elsewhere.
… build

Tests target net10.0 and net6.0 while setup-dotnet pinned 8.0.x — net10.0 only
resolved because the runner image happens to ship SDK 10. Both runtimes are now
installed so both legs can execute.

Tests/packages.lock.json knew only net6.0 and .NETFramework 4.6, so
--locked-mode refused with NU1004. Regenerated; it now matches the project, and
the .NETFramework entry, which nothing targets, is gone.

Restore, build and test are scoped to a solution filter covering the library
and its tests. The .sln also lists sample projects, several of them legacy
msbuild Xamarin and Unity ones that dotnet cannot restore or build on Linux.
@MichaelGHSeg MichaelGHSeg changed the title Harden CI: Artifactory OIDC, NuGet lockfiles, tightened permissions Harden CI: Artifactory OIDC via sdk-actions, NuGet lockfiles, scoped build Sep 30, 2026
@MichaelGHSeg
MichaelGHSeg merged commit 193bcea into main Sep 30, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants