Skip to main content
Root Library Catalog supports NuGet packages for .NET projects. Patched packages are published under the RootIO. prefix at pkg.root.io/nuget/ and can be consumed via the Root Patcher CLI or by adding Root as a NuGet package source.

Prerequisites

Install the Root Patcher CLI (rootio_patcher):
# macOS (Apple Silicon)
curl -sL https://github.com/rootio-avr/rootio_patcher/releases/latest/download/rootio_patcher_darwin_arm64.tar.gz | tar xz
chmod +x rootio_patcher && sudo mv rootio_patcher /usr/local/bin/

# Linux (x86_64)
curl -sL https://github.com/rootio-avr/rootio_patcher/releases/latest/download/rootio_patcher_linux_x86_64.tar.gz | tar xz
chmod +x rootio_patcher && sudo mv rootio_patcher /usr/local/bin/
For macOS Intel and Windows, see the full installation instructions. Then set your API key:
export ROOTIO_API_KEY="your-api-key-here"

How NuGet Patching Works

Root publishes patched NuGet packages in two forms:
Package formName patternVersion patternUse case
AliasedRootIO.{OriginalName}{version}.12007{build}Explicit opt-in via PackageReference
Original{OriginalName}{version}.12007{build}Transparent drop-in replacement
Both forms contain identical patched source. The aliased form lets you reference the patched package explicitly; the original form is a drop-in that requires no PackageReference changes.

Configure the Registry

Add Root as a package source in your NuGet.Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="root-io" value="https://pkg.root.io/nuget/v3/index.json" />
  </packageSources>
  <packageSourceCredentials>
    <root-io>
      <add key="Username" value="root" />
      <add key="ClearTextPassword" value="YOUR_ROOT_TOKEN" />
    </root-io>
  </packageSourceCredentials>
</configuration>
Keep your Root token out of source control. Use environment variable substitution or store credentials in a NuGet.Config outside your repository (e.g., ~/.nuget/NuGet/NuGet.Config).

Patch Dependencies

Use the Root Patcher CLI to identify vulnerable NuGet packages and apply Root-patched versions:
# Preview available patches
rootio_patcher nuget remediate

# Apply patches
rootio_patcher nuget remediate --dry-run=false

# Specify a .csproj or solution file
rootio_patcher nuget remediate --file=path/to/MyApp.csproj --dry-run=false
The patcher rewrites your PackageReference entries to use the aliased RootIO.* package name with the patched version:
<!-- Before -->
<PackageReference Include="OpenTelemetry.Api" Version="1.12.0" />

<!-- After (aliased form - RootIO.* name, patched version) -->
<PackageReference Include="RootIO.OpenTelemetry.Api" Version="1.12.0.120071" />
The aliased package is API-compatible with the original — no code changes are required beyond the PackageReference update. Then restore and build as usual:
dotnet restore
dotnet build

CI/CD Configuration

GitHub Actions

- name: Set up Root token
  run: |
    dotnet nuget add source https://pkg.root.io/nuget/v3/index.json \
      --name root-io \
      --username root \
      --password "$ROOT_TOKEN" \
      --store-password-in-clear-text
  env:
    ROOT_TOKEN: ${{ secrets.ROOT_TOKEN }}

- name: Restore and build
  run: |
    dotnet restore
    dotnet build --no-restore

GitLab CI

before_script:
  - dotnet nuget add source https://pkg.root.io/nuget/v3/index.json
      --name root-io
      --username root
      --password "$ROOT_TOKEN"
      --store-password-in-clear-text

build:
  script:
    - dotnet restore
    - dotnet build --no-restore

Troubleshooting

IssueSolution
401 UnauthorizedVerify your Root token and that credentials are configured for the root-io source
Package not foundConfirm nuget.org is still listed as a fallback source in NuGet.Config
Hash/checksum mismatchExpected - Root serves patched packages whose checksums differ from nuget.org originals
Multi-project solutionRun the patcher at the solution (.sln) level to update all projects at once
RootIO.* package not resolvingEnsure the root-io source is added and credentials are valid; aliased packages are only available on pkg.root.io