Devolutions.Now.Policy.Model
2026.9.19
Prefix Reserved
See the version list below for details.
dotnet add package Devolutions.Now.Policy.Model --version 2026.9.19
NuGet\Install-Package Devolutions.Now.Policy.Model -Version 2026.9.19
<PackageReference Include="Devolutions.Now.Policy.Model" Version="2026.9.19" />
<PackageVersion Include="Devolutions.Now.Policy.Model" Version="2026.9.19" />
<PackageReference Include="Devolutions.Now.Policy.Model" />
paket add Devolutions.Now.Policy.Model --version 2026.9.19
#r "nuget: Devolutions.Now.Policy.Model, 2026.9.19"
#:package Devolutions.Now.Policy.Model@2026.9.19
#addin nuget:?package=Devolutions.Now.Policy.Model&version=2026.9.19
#tool nuget:?package=Devolutions.Now.Policy.Model&version=2026.9.19
Devolutions NOW policy model for .NET
Devolutions.Now.Policy.Model contains the .NET policy document model for Devolutions NOW package broker policies. It is the .NET counterpart to the Rust now-policy crate and represents the policy files used to decide whether package operations are allowed or denied.
Purpose
This package is focused on policy documents, not broker transport. It is used by .NET code that needs to create, parse, inspect, or serialize Devolutions NOW policy files.
The model is used to:
- represent package broker policy documents in C#;
- parse strict JSON policy documents;
- represent editable drafts separately from committed policy documents;
- serialize policy documents with the canonical JSON shape;
- share policy enums and document types with the package broker API compatibility layer.
Architecture
PolicyModels.csdefines committedPolicyDocument, editablePolicyDraftDocument, their metadata, explicit conversions, enforcement, rules, match criteria, constraints, and version range types.Enums.csdefines policy-level enums such as operation, manager, scope, architecture, elevation, and decision.PolicySerializer.csdefines the single source-generated policy JSON contract.PolicySerializer.Deserialize<T>,PolicySerializer.Options, and both documentParseJsonhelpers all reject unknown members, duplicate property names, and JSON null for non-nullable policy members or collection elements.- The duplicate check covers every nested object, decodes escaped names before comparing them, and uses ordinal, case-sensitive equality to match canonical property-name handling.
PolicyDocument.Create constructs a committed policy and PolicyDraftDocument.Create constructs an editable draft. PolicyDocument.ToDraft removes server-managed Revision and PublishedAt; PolicyDraftDocument.ToPolicyDocument requires those values when committing. ParseJson is the recommended strict policy parsing entry point.
PolicyFormatVersion is software-managed format compatibility metadata, not a publisher release version. New documents stamp 1.0.0; readers accept and preserve supported numeric versions in the 1.x line and reject malformed or unsupported-major values. Applications must not expose it as authored metadata. Policy documents contain no $schema member, and strict readers reject documents that contain one as unknown-field input.
Metadata.ValidFrom and Metadata.ValidUntil are optional operational UTC instants, not informational labels. Omitted or explicit null leaves that side unbounded, and canonical output omits an absent bound. When both are present, ValidFrom must be strictly earlier than ValidUntil; comparisons normalize offsets by instant. Brokers fail closed for every request: reject operations when the current instant is before ValidFrom or after ValidUntil, with no fallback policy.
PolicyMatch boolean request characteristics (Interactive, SkipHashCheck, PreRelease, HasCustomParameters, HasCustomInstallLocation, HasPrePostCommands, HasKillBeforeOperation, and HasUninstallPrevious) are optional scalar booleans. Omitted or explicit null means the characteristic does not affect whether the rule matches; false and true require that exact request characteristic. Canonical serialization omits absent values. Legacy boolean arrays are rejected. A rule's Match must still contain at least one effective non-null, nonempty criterion.
Collection-valued match filters accept omission or an explicit empty array as unrestricted input, but canonical serialization omits empty collections. The former PackageNames filter is rejected as unknown input. PackageIdentifiers has exactly one explicit mode: Exact contains validated stable identifiers and rejects wildcard characters, while Patterns contains deliberately broad wildcard patterns that may authorize multiple identifiers. Use UseExact or UsePatterns to switch a mutable PackageIdentifierCondition atomically. SourceNames contains exact configured package source names, not URLs or wildcard patterns. Source-name comparison follows the selected package manager's semantics, wildcard characters are literal, and nonempty SourceNames requires exactly one Managers value.
Version also has exactly one explicit mode: Exact contains one or more arbitrary package version strings, including non-SemVer versions, while Range contains the semantic-version range. Use UseExact or UseRange to switch a mutable VersionCondition atomically. Omitted or explicit null does not narrow matching. The former Versions and VersionRange match properties are rejected as unknown input.
ExecutionElevation matches the request's effective execution privilege, not only the client's requested elevation. Brokers must use Elevated when the package operation will run with administrator privileges—currently when Scope is Machine or Client.RequestedElevation is Elevated—and Standard otherwise. The former Elevation match property is rejected as unknown input.
Rule precedence is fixed by the policy format and is not represented by a JSON field: lower Priority values evaluate first, Deny wins equal-priority Allow/Deny ties, and remaining equal-priority ties retain document order. Constraints are additional safety limits for an Allow rule and are invalid on Deny rules. Editors may host incomplete blank rules transiently, but must not serialize or save a rule until Match contains an effective condition.
Breaking change
Policy documents are JSON-only. PolicyDocument.ParseYaml, which was public in Devolutions.Now.Policy.Model 2026.8.13, has been removed intentionally. Consumers must migrate stored policies to JSON before upgrading; OpenAPI YAML and unrelated YAML documents are unaffected. Boolean match arrays and the former PolicyType, RulePrecedence, and PackageNames members are also rejected rather than converted.
Consumer migration
- Gateway removes
PolicyType,RulePrecedence,PackageNames, and old match-field construction; keeps the fixed priority/deny-tie/document-order evaluator semantics; assumes Deny rules have no constraints; computesExecutionElevationasElevatedwhen scope isMachineor requested elevation isElevated, otherwiseStandard; implements the explicit package/version/source modes; retains per-request UTC validity enforcement; and adds exactValidFrom/ValidUntilboundary tests if missing. - UniGetUI removes editors/help for
PolicyType,RulePrecedence,PackageNames, and old match fields; shows constraints only for Allow rules; resolves friendly-name searches to stable identifiers; auto-generates unique priorities by visible order; uses date/time controls with inlineValidFrom < ValidUntilvalidation; and may host incomplete rules transiently but must not serialize or save them. - Stored documents replace boolean arrays with scalar booleans, rename
SourcestoSourceNamesandElevationtoExecutionElevation, wrap package identifiers inExactorPatterns, and replaceVersions/VersionRangewith oneVersionmode.
Validation
Run the Rust policy schema/tests as well when changing shared policy semantics.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Devolutions.Now.Policy.Model:
| Package | Downloads |
|---|---|
|
Devolutions.Now.Policy.Api
Request and response DTOs for the Devolutions NOW package broker API. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.10.16.1 | 134 | 10/16/2026 |
| 2026.10.16 | 119 | 10/16/2026 |
| 2026.9.19 | 19,387 | 9/19/2026 |
| 2026.9.17 | 155 | 9/17/2026 |
| 2026.9.15 | 141 | 9/15/2026 |
| 2026.9.3 | 166 | 9/3/2026 |
| 2026.8.13 | 1,805 | 8/13/2026 |
| 2026.8.5 | 282 | 8/5/2026 |
| 2026.7.28 | 1,018 | 7/28/2026 |
| 2026.7.13 | 550 | 7/13/2026 |
| 2026.6.23 | 148 | 6/23/2026 |