Cocoar.Json.Zero 0.1.0-alpha.5

This is a prerelease version of Cocoar.Json.Zero.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package Cocoar.Json.Zero --version 0.1.0-alpha.5
                    
NuGet\Install-Package Cocoar.Json.Zero -Version 0.1.0-alpha.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cocoar.Json.Zero" Version="0.1.0-alpha.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cocoar.Json.Zero" Version="0.1.0-alpha.5" />
                    
Directory.Packages.props
<PackageReference Include="Cocoar.Json.Zero" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cocoar.Json.Zero --version 0.1.0-alpha.5
                    
#r "nuget: Cocoar.Json.Zero, 0.1.0-alpha.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cocoar.Json.Zero@0.1.0-alpha.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cocoar.Json.Zero&version=0.1.0-alpha.5&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Cocoar.Json.Zero&version=0.1.0-alpha.5&prerelease
                    
Install as a Cake Tool

Cocoar.Json.Zero

Zero Strings. Zero Leaks. Zero Leftovers.

A mutable JSON document object model (DOM) that stores all content as UTF-8 byte arrays, enabling deterministic memory cleanup for sensitive data handling.

Why Use This?

Problem: Regular JSON libraries (including System.Text.Json) store data as managed string objects. You can't control when strings are garbage collected or zeroed from memory. For sensitive data (API keys, passwords, PII), this means secrets may linger in RAM for unpredictable periods.

Solution: Cocoar.Json.Zero stores all JSON content as byte[] arrays that you can deterministically zero via Dispose(). When you're done with sensitive data, call Dispose() and it's immediately zeroed from memory—no waiting for the garbage collector.

For complete security details, see Security Implementation.

Key Features

Zero-string JSON handling - All content stored as byte[] instead of managed strings
Deterministic cleanup - Dispose() immediately zeros all byte arrays
UTF-8 native - Works directly with UTF-8 bytes using ReadOnlySpan<byte>
Mutable in-memory structure - Parse, modify, merge, transform, serialize back
Built on System.Text.Json - Uses battle-tested Utf8JsonReader and Utf8JsonWriter
Path navigation - Colon-separated paths ("Root:Level1:Property")
Security hardened - Randomized hashing, buffer zeroing, path limits

Quick Start

using Cocoar.Json.Zero;
using System.Security.Cryptography;

// Parse from file (automatically zeros input buffer)
using var doc = JsonZeroIO.ParseFromFileAndZero("config.json");
var root = (JsonZeroObject)doc;

// Navigate using paths (UTF-8, no string allocations)
var value = root.GetByPathUtf8("Database:ConnectionString"u8);

// Transform sensitive values (original is auto-zeroed)
root.Transform("Database:Password"u8, _ => "REDACTED"u8.ToArray());

// Update values
byte[] newData = GetFromVault(); // byte[] from external source
root.SetByPathUtf8("ApiKey"u8, JsonZeroString.FromOwned(newData));

// Serialize to stream (preferred - automatic buffer zeroing)
using var fs = File.Create("output.json");
await JsonZeroDocument.WriteToAsync(root, fs);

// Dispose zeros all internal byte arrays immediately
// (happens automatically at end of 'using' block)

Use Cases

Perfect for:

  • Configuration management with secrets (passwords, API keys, tokens)
  • PCI-DSS, HIPAA, GDPR, SOC2 compliance scenarios requiring deterministic cleanup
  • Long-running services where GC timing is unpredictable
  • Data transformation pipelines with controlled cleanup
  • Preventing secrets in memory dumps or page files

Not suitable for:

  • General-purpose JSON (use System.Text.Json instead)
  • High-frequency, low-latency APIs (use specialized parsers)
  • Read-only JSON processing (use Utf8JsonReader directly)
  • Scenarios where you need POCO mapping (use JsonSerializer)

Core Operations

Parsing

// Parse and zero input (small-medium files)
using var doc = JsonZeroIO.ParseFromFileAndZero("config.json");

// Parse from stream (async + zeroing)
await using var stream = File.OpenRead("config.json");
using var doc = await JsonZeroIO.ParseFromStreamAndZeroAsync(stream);

// Parse large files in chunks (>100MB)
using var stream2 = File.OpenRead("large.json");
using var doc2 = JsonZeroIO.ParseFromStreamChunked(stream2);

// Parse from bytes (caller owns buffer)
using var doc3 = JsonZeroDocument.Parse(utf8Bytes);
// Get value at path
var value = root.GetByPathUtf8("Parent:Child:Property"u8);

// Set value (creates intermediate objects if needed)
root.SetByPathUtf8("Config:Host"u8, new JsonZeroString("localhost"u8.ToArray()));

// Remove property
bool removed = root.RemoveByPathUtf8("Secrets:OldKey"u8);

// Clone subtree (returns deep clone, safe for concurrent use)
var subtree = root.SelectByPathUtf8("Config:Database"u8);

Transform

Transform values with automatic zeroing of original bytes. For detailed patterns (redaction, masking, tokenization, encryption), see Usage Guide.

Merge & Serialize

// Merge two configs
JsonZeroMerge.Merge(target, source);

// Serialize to stream (automatic zeroing)
await JsonZeroDocument.WriteToAsync(root, stream);

// Serialize to bytes (caller must zero)
byte[] json = JsonZeroDocument.ToUtf8Bytes(root);
try {
    File.WriteAllBytes("out.json", json);
} finally {
    CryptographicOperations.ZeroMemory(json);
}

Integration with System.Text.Json

Use Json.Zero for manipulation, then deserialize to POCOs with System.Text.Json:

// 1. Load and transform with Json.Zero
using var config = JsonZeroIO.ParseFromFileAndZero("config.json");
var obj = (JsonZeroObject)config;
obj.Transform("Database:Password"u8, _ => "REDACTED"u8.ToArray());

// 2. Serialize to UTF-8
byte[] json = JsonZeroDocument.ToUtf8Bytes(obj);

// 3. Deserialize to POCO (strings allocated here, but originals are zeroed)
var appConfig = JsonSerializer.Deserialize<AppConfig>(json);

// 4. Zero intermediate buffer
CryptographicOperations.ZeroMemory(json);

// 5. Use type-safe config
Console.WriteLine($"Host: {appConfig.Database.Host}");
Console.WriteLine($"Password: {appConfig.Database.Password}"); // Shows "REDACTED"

Memory Safety

What This Library Guarantees

✅ All JSON content stored as byte[] (never string)
Dispose() immediately zeros all byte arrays via CryptographicOperations.ZeroMemory()
✅ Disposal cascades - parent disposal zeroes all children recursively
✅ Pooled buffers zeroed before return to ArrayPool
✅ Property removal zeros property name bytes
✅ Transform operations zero original values (even if transform throws)

What You Must Do

Never use UTF-8 literals for sensitive data - literals are embedded in assembly and can't be zeroed
Always dispose - use using blocks or explicit Dispose() calls
Zero output buffers - if using ToUtf8Bytes(), you must zero the returned array
Use UTF-8 APIs - prefer GetByPathUtf8 over GetByPath to avoid string allocations

Limitations

  • Data is zeroed after disposal, not during active processing
  • Brief processing window (milliseconds) where data exists in memory
  • OS-level risks (page file, hibernation) if system events occur during processing
  • See docs/security-implementation.md for complete threat model

Documentation

  • Usage Guide - Detailed examples, patterns, stream parsing, transforms, POCO integration
  • API Reference - Complete API documentation with all methods and properties
  • Advanced Topics - Memory management deep dive, concurrency, performance tuning, architecture
  • Performance Benchmarks - Json.Zero vs System.Text.Json comparison, trade-offs, real-world scenarios
  • Security Implementation - Security guarantees, resource limits, threat model, best practices

Installation

dotnet add package Cocoar.Json.Zero

Requirements

  • .NET 8.0 or later
  • System.Text.Json (built-in)

Building & Testing

# Build
dotnet build src/Cocoar.Json.Zero.slnx

# Run tests (84 tests including security regression tests)
dotnet test src/tests/Cocoar.Json.Zero.Tests/

# Run benchmarks
dotnet run -c Release --project src/Benchmarks/Cocoar.Json.Zero.Benchmarks/

License

Apache License 2.0 - see LICENSE

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Security

Acknowledgments

Built on top of the excellent System.Text.Json library from the .NET team.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated