Covers JWT authentication, subject mapping/transforms, OCSP support, Windows Service integration, per-subsystem logging, per-client trace, per-account stats, and TLS cert expiry in /varz.
7.1 KiB
Remaining Lower-Priority Gaps — Design Document
Goal: Resolve all remaining lower-priority gaps from differences.md with full Go parity, bringing the .NET NATS server to feature completeness for single-server (non-clustered) deployments.
Approach: Full Go parity — implement all listed gaps including JWT authentication, subject mapping, OCSP, and quick wins.
1. JWT Authentication
The largest component. NATS uses standard JWT encoding (base64url header.payload.signature) with Ed25519 signing via the nats-io/jwt/v2 Go library.
New Files
Auth/Jwt/NatsJwt.cs— JWT decode/encode utilities. Base64url parsing, header extraction, Ed25519 signature verification via NATS.NKeys. Detects JWT by"eyJ"prefix.Auth/Jwt/UserClaims.cs— User claim record:Subject(nkey),Issuer(account nkey),IssuerAccount(scoped signer),Name,Tags,BearerToken,Permissions(pub/sub allow/deny),ResponsePermission,Src(allowed CIDRs),Times(time-based access),AllowedConnectionTypes,IssuedAt,Expires.Auth/Jwt/AccountClaims.cs— Account claim record:Subject,Issuer(operator nkey),SigningKeys,Limits,Exports,Imports.Auth/Jwt/PermissionTemplates.cs— Template expansion for all 6 mustache-style templates:{{name()}}→ user's Name{{subject()}}→ user's Subject (nkey){{tag(name)}}→ user tags matchingname:prefix{{account-name()}}→ account display name{{account-subject()}}→ account nkey{{account-tag(name)}}→ account tags matching prefix- Cartesian product applied for multi-value tags.
Auth/Jwt/AccountResolver.cs—IAccountResolverinterface (FetchAsync,StoreAsync,IsReadOnly) +MemAccountResolverin-memory implementation.Auth/JwtAuthenticator.cs— ImplementsIAuthenticator. Flow: decode user JWT → resolve account → verify Ed25519 signature against nonce → expand permission templates → buildNkeyUser→ validate source IP + time restrictions → check user revocation.
Modified Files
Auth/Account.cs— AddNkey,Issuer,SigningKeys(Dictionary),RevokedUsers(ConcurrentDictionary<string, long>).NatsOptions.cs— AddTrustedKeys(string[]),AccountResolver(IAccountResolver).NatsClient.cs— Pass JWT + signature from CONNECT opts to authenticator.
Design Decisions
- No external JWT NuGet — NATS JWTs are simple enough to parse inline (base64url + System.Text.Json + Ed25519 via NATS.NKeys).
MemAccountResolveronly — URL/directory resolvers are deployment infrastructure.- User revocation:
ConcurrentDictionary<string, long>on Account (nkey → issuedAt; JWTs issued before revocation time are rejected). - Source IP validation via
System.Net.IPNetwork.Contains()(.NET 8+).
2. Subject Mapping / Transforms
Port Go's subject_transform.go. Configurable source pattern → destination template with function tokens.
New File
Subscriptions/SubjectTransform.cs— A transform has a source pattern (with wildcards) and a destination template with function tokens. On match, captured wildcard values are substituted into the destination.
Transform Functions
| Function | Description |
|---|---|
{{wildcard(n)}} / $n |
Replace with nth captured wildcard token (1-based) |
{{partition(num,tokens...)}} |
FNV-1a hash of captured tokens mod num |
{{split(token,delim)}} |
Split captured token by delimiter into subject tokens |
{{splitFromLeft(token,pos)}} |
Split token into two at position from left |
{{splitFromRight(token,pos)}} |
Split token into two at position from right |
{{sliceFromLeft(token,size)}} |
Slice token into fixed-size chunks from left |
{{sliceFromRight(token,size)}} |
Slice token into fixed-size chunks from right |
{{left(token,len)}} |
Take first len chars |
{{right(token,len)}} |
Take last len chars |
Integration
NatsOptions.SubjectMappings—Dictionary<string, string>of source→destination rules.- Transforms compiled at config time into token operation lists (no runtime regex).
- Applied in
NatsServer.DeliverMessagebefore subject matching. - Account-level mappings for import/export rewriting.
3. OCSP Support
Two dimensions: peer verification (client cert revocation checking) and stapling (server cert status).
New File
Tls/OcspConfig.cs—OcspModeenum (Auto,Always,Must,Never) +OcspConfigrecord withModeandOverrideUrls.
Peer Verification
- Modify
TlsConnectionWrapperto setX509RevocationMode.OnlinewhenOcspPeerVerifyis true. - Checks CRL/OCSP during TLS handshake for client certificates.
OCSP Stapling
- Build
SslStreamCertificateContext.Create(cert, chain, offline: false)at startup — .NET fetches OCSP response automatically. - Pass to
SslServerAuthenticationOptions.ServerCertificateContext. Mustmode: verify OCSP response obtained; fail startup if not.
Modified Files
NatsOptions.cs—OcspConfigandOcspPeerVerifyproperties.TlsConnectionWrapper.cs— Peer verification in cert validation callback.NatsServer.cs—SslStreamCertificateContextwith OCSP at startup.VarzHandler.cs— PopulateTlsOcspPeerVerifyfield.
4. Quick Wins
A. Windows Service Integration
- Add
Microsoft.Extensions.Hosting.WindowsServicesNuGet. - Detect
--serviceflag inProgram.cs, callUseWindowsService(). - .NET generic host handles service lifecycle automatically.
B. Per-Subsystem Log Control
NatsOptions.LogOverrides—Dictionary<string, string>mapping namespace→level.- CLI:
--log_level_override "NATS.Server.Protocol=Trace"(repeatable). - Serilog:
MinimumLevel.Override(namespace, level)per entry.
C. Per-Client Trace Mode
TraceModeflag inClientFlagHolder.- When set, parser receives logger regardless of global
options.Trace. - Connz response includes
traceboolean per connection.
D. Per-Account Stats
long _inMsgs, _outMsgs, _inBytes, _outBytesonAccountwithInterlocked.IncrementInbound(long bytes)/IncrementOutbound(long bytes).- Called from
DeliverMessage(outbound) and message processing (inbound). /accountzendpoint returns per-account stats.
E. TLS Certificate Expiry in /varz
- In
VarzHandler, read server TLS certNotAfter. - Populate existing
TlsCertNotAfterfield.
F. differences.md Update
- Mark all resolved features as Y with notes.
- Update summary section.
- Correct any stale entries.
Task Dependencies
Independent (parallelizable):
- JWT Authentication (#23)
- Subject Mapping (#24)
- OCSP Support (#25)
- Windows Service (#26)
- Per-Subsystem Logging (#27)
- Per-Client Trace (#28)
- Per-Account Stats (#29)
- TLS Cert Expiry (#30)
Dependent:
- Update differences.md (#31) — blocked by all above
Most tasks can run in parallel since they touch different files. JWT and Subject Mapping are the two largest. The quick wins (26-30) are all independent of each other and of the larger tasks.