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 form | Name pattern | Version pattern | Use case |
|---|
| Aliased | RootIO.{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.
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
| Issue | Solution |
|---|
401 Unauthorized | Verify your Root token and that credentials are configured for the root-io source |
| Package not found | Confirm nuget.org is still listed as a fallback source in NuGet.Config |
| Hash/checksum mismatch | Expected - Root serves patched packages whose checksums differ from nuget.org originals |
| Multi-project solution | Run the patcher at the solution (.sln) level to update all projects at once |
RootIO.* package not resolving | Ensure the root-io source is added and credentials are valid; aliased packages are only available on pkg.root.io |