Skip to content
bitzorcas
中EN

Guide

Private NuGet Feed Setup and Operations

Configure a feed, initialize Consumers, distribute short-lived credentials, publish candidates, verify GA, rotate access, and handle incidents.

Last updated

The private feed controls who may download which BitzOrcas.* packages and versions. It does not replace Runtime Licensing, and one customer’s download credential must never be reused for another.

Separate the four identities

IdentityPermissionCredential location
Feed administratorSource, immutability, backup, and audit policyFeed management plane
Publish workflowWrite candidate packages onlyGitHub commercial-release environment
GA workflowRead-only restore from the formal feedGitHub commercial-release environment
Customer/developerRead selected product, channel, and package prefixesCredential Provider or personal secret store

The publish API key and Consumer token are distinct credentials. A browser, Consumer repository, template, or NuGet.Config must never receive publish access.

1. Create the feed

The feed product is replaceable, but it must provide:

  • an HTTPS endpoint without userinfo, query, or fragment;
  • immutable published PackageId + Version identities;
  • preferably staging/promote, otherwise a recovery protocol that resumes an existing identity only when bytes match exactly;
  • least-privilege tokens scoped by customer, product, BitzOrcas.* prefix, and version channel;
  • separate, revocable, auditable read and write credentials;
  • backup and restore exercises for packages, metadata, and policy.

2. Configure the release repository

Configure these GitHub Repository/Environment values:

TypeNamePurpose
VariableBITZORCAS_COMMERCIAL_FEED_URLCredential-free HTTPS feed URL
SecretBITZORCAS_COMMERCIAL_PUSH_API_KEYWrite credential used only by publishing
SecretBITZORCAS_COMMERCIAL_FEED_CREDENTIALSNuGet-standard read credential used by GA
SecretBITZORCAS_NUGET_SIGNING_CERTIFICATE_BASE64Base64 PFX used only by the signing environment
SecretBITZORCAS_NUGET_SIGNING_CERTIFICATE_PASSWORDSeparate password for that PFX
VariableBITZORCAS_NUGET_TIMESTAMP_URLTrusted RFC 3161 timestamp URL (HTTP or HTTPS)
VariableBITZORCAS_TRUSTED_SIGNER_FINGERPRINTSApproved package-signing certificates
VariableBITZORCAS_TRUSTED_RELEASE_WORKFLOWTrusted candidate workflow
VariableBITZORCAS_TRUSTED_ATTESTATION_WORKFLOWTrusted attestation workflow
VariableBITZORCAS_TRUSTED_ATTESTATION_WORKFLOW_DIGESTPinned workflow commit
VariableBITZORCAS_VULNERABILITY_THRESHOLDVulnerability gate
VariableBITZORCAS_THIRD_PARTY_LICENSE_POLICYThird-party license policy
VariableBITZORCAS_APPROVED_LICENSE_EXPRESSIONSExplicitly approved license expressions

BITZORCAS_COMMERCIAL_FEED_CREDENTIALS must have this shape:

Username=<read-only-account>;Password=<short-lived-token>;ValidAuthenticationTypes=Basic

Keep the two certificate secrets only in the protected commercial-release-builder environment. Keep feed write and GA read credentials in commercial-release. Never put these values in workflow YAML; protect both environments with approval, a small administrator set, and secret-access auditing.

3. Initialize a Consumer

From the product repository root:

Terminal window
export BITZORCAS_COMMERCIAL_FEED_URL="https://packages.example.com/nuget/v3/index.json"
scripts/feed/init-consumer.sh /absolute/path/to/ConsumerSolution

The script creates a credential-free NuGet.Config only when none exists. Existing files are validated and never overwritten. The result contains:

  • <clear /> to remove inherited machine sources;
  • BitzOrcasCommercial, resolved from %BITZORCAS_COMMERCIAL_FEED_URL%;
  • a mapping that sends only BitzOrcas.* to the commercial feed;
  • a public-package mapping to nuget.org;
  • no packageSourceCredentials.

Validate structure first:

Terminal window
scripts/feed/doctor.sh config /absolute/path/to/ConsumerSolution/NuGet.Config

The diagnostic prints status only, never URL, account, or token values.

4. Inject read-only credentials and restore

Prefer the organization’s NuGet Credential Provider. Without one, the wrapper can read a short-lived token securely from the terminal:

Terminal window
# The wrapper exposes the short-lived credential only to this restore process.
export BITZORCAS_COMMERCIAL_FEED_URL="https://packages.example.com/nuget/v3/index.json"
scripts/feed/with-credentials.sh -- \
dotnet restore /absolute/path/to/ConsumerSolution/Consumer.slnx \
--configfile /absolute/path/to/ConsumerSolution/NuGet.Config

CI injects this standard variable from its secret store into the individual restore/install process:

NuGetPackageSourceCredentials_BitzOrcasCommercial

Do not use dotnet nuget add source --store-password-in-clear-text. Never put a token in command arguments, shell profiles, image layers, or logs.

5. Run an online clean-cache probe

Structure validation does not prove authentication, entitlement, or package signatures. Select one exact package and version the identity may download:

Terminal window
# Use an exact entitled package version to verify auth, scope, and signatures.
scripts/feed/doctor.sh consumer \
/absolute/path/to/ConsumerSolution/NuGet.Config \
--online BitzOrcas.Profile.MiniApi 1.2.3

The probe isolates NUGET_PACKAGES, HTTP cache, plugin cache, and DOTNET_CLI_HOME, restores from an empty cache, then runs:

Terminal window
dotnet nuget verify <package> --all

Both restore and full signature verification must pass. A hit from an old developer cache is not evidence.

6. Publish a version

Use this fixed sequence:

  1. Dispatch Build Commercial Release Candidate on protected main with one exact release_train.
  2. Record its successful run id, artifact name, and full 40-character commit.
  3. Dispatch Publish Commercial Candidate with those exact three values.
  4. Dispatch Commercial GA with the same values.
  5. Add the version to customer channels and upgrade notes only after GA passes.

Never repack in the publish job or alter an artifact before upload. Changed bytes require a new version and a new candidate chain.

7. Distribute customer access

Issue a separate, read-only, short-lived, revocable identity for each customer or automation principal. Record:

  • customer, product, and owner;
  • package prefixes and version channels;
  • issue, expiry, and last-use time;
  • delivery channel and secret-store location;
  • rotation owner and revocation ticket.

Distribute through an enterprise secret manager, Credential Provider, or one-time secure channel. Do not send tokens in email, chat, Wiki, or ticket bodies. Customer repositories retain only credential-free NuGet.Config.

8. Rotate and revoke

Normal rotation:

  1. Issue a new read token.
  2. Pass the online probe from an empty cache.
  3. Update CI/developer secret stores.
  4. Observe that the old token is no longer used.
  5. Revoke it and retain evidence.

For leakage:

  1. Revoke the token immediately.
  2. Audit downloads, source IPs, package ids, and versions.
  3. Check whether the secret was reused by publishing or another customer.
  4. Issue a narrower replacement.
  5. Freeze the channel and invoke the malicious-package procedure if integrity is uncertain.

A feed outage does not invalidate already deployed Runtime Licenses. Existing deployments continue under their signed local license and offline lease; new restores, upgrades, and environments are affected.

Diagnostic table

SymptomCheck first
NU1101Source Mapping, entitlement, and exact version publication
401/403Expiry, read scope, and source name BitzOrcasCommercial
Local succeeds, CI failsFour isolated caches and the standard credential variable
NU300xSignature, certificate chain, timestamp, and trusted fingerprint
Same version, different hashStop consumption; investigate overwrite and partial-publish recovery
Slow restoreFeed network, Credential Provider, first empty cache, dependency count

Acceptance checklist

  • Consumer configuration is credential-free with exact Source Mapping;
  • write and read credentials are physically separated;
  • a real customer identity passes clean-cache restore and dotnet nuget verify --all;
  • published versions are immutable;
  • candidate, publish, and GA bind the same artifact identity and commit;
  • tokens have owners, expiry, rotation, and revocation records;
  • backup, restore, and partial-publication procedures exist.

See also

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%