Skip to content

Component: Smrt.StorageGuard.ServiceHost

Canonical source: SmrtApps/src/Smrt.StorageGuard.ServiceHost/README.md (mirrored below)


Smrt.StorageGuard.ServiceHost

Overview and responsibilities

  • Windows service host that emits signed Storage Guard snapshots and retention evidence artifacts.
  • Hosts an HTTPS endpoint for trusted local consumers to fetch the latest snapshot/signature.

Public surface / entry points

  • Windows service process.
  • HTTPS endpoints (documented below).

Dependencies and integrations

  • Consumes Smrt.Retention for retention configuration and evidence contracts.
  • Consumed by SmrtHubSupervisor and Smrt.SupportBundle via signed snapshot client.

Configuration and operational data

  • Service configuration: appsettings.json and environment-specific appsettings.
  • Shared secret set: %ProgramData%/SmrtHub/Config/storage-guard/storage-guard-secret.json.
  • Evidence artifacts: %ProgramData%/SmrtHub/Logs/system-info/ (and system-info/retention/).

Observability and diagnostics

  • Uses SmrtHub.Logging with slugs storage-guard-service and retention-verifier.

Testing and validation

  • Not documented yet.

Support Bundle

  • Storage Guard and retention evidence artifacts should be collected via Support Bundle exports.
  • Retention Subsystem: README.Files/Subsystems/Retention/README.md
  • Retention Capability: README.Files/Capabilities/Retention/README.md
  • Retention Subsystem (contracts and invariants): README.Files/Subsystems/Retention/README.md
  • Retention Capability (end-to-end flow): README.Files/Capabilities/Retention/README.md
  • Retention & Legal Hold Plan (Phase 3): README.Files/System/Plans/SmrtHub-Retention-and-LegalHold.README.md

Purpose

  • Windows service responsible for continuously emitting system-info/storage-guard.json and its companion signature system-info/storage-guard.sig.
  • Runs the retention verification worker that writes system-info/retention/retention-verification.json + .sig and a rolling health summary.
  • Hosts an HTTPS endpoint that exposes the latest snapshot + signature to trusted SmrtHub components (Supervisor, Support Bundle, future diagnostics).
  • Enforces enterprise-grade security: Smrt.Logging, mutual TLS with an allow-listed client certificate set, and Smrt.Config-backed shared-secret authentication.

Key Responsibilities

  • Run Smrt.Infrastructure.StorageGuard.StorageGuardService on a fixed cadence (default 10 minutes) to capture encryption, free-space, and sync provider state.
  • Persist artifacts in %ProgramData%/SmrtHub/Logs/system-info/ (with automatic migration from legacy %LocalAppData%) so both LocalSystem services and userland tools share the same evidence.
  • Produce a SHA-512 hash + HMAC-SHA512 signature for every snapshot and store it in storage-guard.sig using the shared secret set (managed via StorageGuardSecretStore). The host always signs with the primary secret while keeping rollover keys available for verification.
  • Embed the current retention configuration (policies + legal holds from Smrt.Retention) into each signed snapshot so downstream tools can verify compliance without chasing separate files.
  • Run RetentionVerificationHostedService on a configurable cadence (default 6 hours) to hash policies/holds, emit stub provider results until adapters land, and sign retention-verification.json alongside retention-health.json.
  • Serve /healthz, /v1/storage-guard/snapshot, and /v1/storage-guard/signature over HTTPS with mutual TLS + shared-secret headers so consumers can fetch pre-signed evidence.

Configuration

  • appsettings.json (copied to output) defines StorageGuardService options:
  • Urls: HTTPS binding (default https://localhost:5065).
  • Certificates.Server: Store location/name + thumbprint for the server certificate used by Kestrel.
  • Certificates.AllowedClientThumbprints: List of thumbprints permitted to call the endpoints (Supervisor, SupportBundle harness, etc.).
  • Certificates.AllowDevelopmentServerCertificateFallback: When true (defaulted via appsettings.Development.json) the host attempts to reuse the ASP.NET Core HTTPS development certificate or auto-generates a self-signed server cert if the configured thumbprint is missing.
  • Certificates.AllowDevelopmentClientBypass: When true (dev only) the host temporarily disables mutual TLS enforcement and relies solely on the shared-secret header so developers can bootstrap without hand-issuing client certificates.
  • Auth.SharedSecretHeader: Header that must carry the shared secret (defaults to X-SmrtHub-StorageGuard-Secret).
  • Snapshot.IntervalSeconds: Cadence for refreshing snapshots/signatures (default 600 seconds).
  • RetentionVerification: Worker toggle and cadence (Enabled, IntervalSeconds), provenance stamping (EnvironmentName, BuildId), stub provider list (Providers), and signing toggle (SignEvidence). Defaults: enabled, 6 hours, signing on, provider list seeded with default.
  • The shared secret set lives under %ProgramData%/SmrtHub/Config/storage-guard/storage-guard-secret.json. The service auto-generates a 64-byte primary secret on first run and persists it alongside any trusted rollover keys so both LocalSystem services and user-scoped tooling can verify signatures during rotations.

Logging

  • Uses SmrtHub.Logging with component slugs storage-guard-service and retention-verifier. Logs land in %ProgramData%/SmrtHub/Logs/system-info/<slug>/ (falling back to %LocalAppData% only if ProgramData is unavailable) with the standard JSON+text dual sinks.
  • StorageGuardStatusCache tracks the last successful snapshot emission so /healthz can report healthy/degraded states.

Shared storage helpers

  • StorageGuardPaths resolves every snapshot/signature path and migrates legacy %LocalAppData% copies to %ProgramData%/SmrtHub/Logs/system-info/, keeping LocalSystem services and user-scoped tooling on the same evidence.
  • Python Core mirrors the shared ProgramData resolver behavior through python_core.utils.shared_data_path_resolver for Storage Guard secrets and other shared artifacts. Dev machines without ProgramData automatically fall back to %LocalAppData%/%AppData%, so never hard-code paths outside these helpers.

Endpoints

Endpoint Description Auth
GET /healthz Returns JSON with status, lastIssuedAtUtc, consecutiveFailures, and lastError. Mutual TLS + shared-secret
GET /v1/storage-guard/snapshot Streams the raw storage-guard.json that lives on disk. Mutual TLS + shared-secret
GET /v1/storage-guard/signature Streams storage-guard.sig so clients can verify SHA-512 + HMAC. Mutual TLS + shared-secret

Build & Service Notes

  • Project targets net8.0-windows and RID win-x64; add it to the central build scripts via Tools/Clean-Build/BuildApps.ps1 with scope CSharpApps.
  • Install/uninstall the Windows service using the repo-level tooling:
  • Tools/Privacy-Security/Install-StorageGuardService.ps1 (run elevated) registers the host as SmrtStorageGuard, points it at the staged Apps build, sets DOTNET/ASPNETCORE environment names (defaults to Development), and starts the service.
  • Tools/Privacy-Security/Uninstall-StorageGuardService.ps1 removes the registration when you need to tear it down or reinstall.
  • Certificates/secret provisioning live outside source control per Operational Data Policy. Use the same bootstrap flow as SmrtHubSupervisor when configuring thumbprints.

Local development quick start

  1. Build the host (Tools/Clean-Build/BuildApps.ps1 -Scope CSharpApps) so Apps/Debug/win-x64/Smrt.StorageGuard.ServiceHost is available.
  2. From an elevated PowerShell session, run Tools/Privacy-Security/Install-StorageGuardService.ps1 (defaults to Development environment). This registers the Windows service, applies the dev-only certificate bypass flags, and starts it automatically.
  3. The shared secret set is auto-provisioned on first run at %ProgramData%\SmrtHub\Config\storage-guard\storage-guard-secret.json; share this file with Supervisor/Test Harness tooling when running under different identities so every consumer sees both the current primary key and any trusted rollover keys.
  4. Snapshots land in %ProgramData%\SmrtHub\Logs\system-info\storage-guard.json alongside storage-guard.sig and the service logs (storage-guard-service-log*.txt/json). Legacy %LocalAppData% directories are migrated automatically on first write so developer profiles remain intact. 4b. Retention evidence lands in %ProgramData%\SmrtHub\Logs\system-info\retention\ (retention-verification.json, .sig, retention-health.json) and the retention-verifier log lives alongside those artifacts.
  5. SmrtSpace selection is per-user and lives under %AppData%/SmrtHub/Config/smrt-space/active_smrtspace.json (Operational Data Policy). The Storage Guard service itself does not depend on that file.
  6. When you are ready to exercise real mutual TLS, reinstall the service with -EnvironmentName Production, disable the development bypass flags in configuration, and restart the service.

Secret rotation checklist

  1. StorageGuardSecretStore.EnsureSet() already runs during service startup. Confirm the JSON contains the current Primary secret and any entries inside Trusted.
  2. To roll keys, add the upcoming secret to the Trusted collection (or let the helper generate one) and distribute the updated JSON to every host and consumer.
  3. Restart the service host (or call the new API when available) so it begins signing with the new primary secret. Because clients verify against AllSecrets, they continue working even if their copy still lists the previous primary.
  4. After every consumer deploys the refreshed JSON, remove the retired secret from Trusted to keep the trust store lean.
  • Smrt.Infrastructure.StorageGuard supplies the snapshot engine plus signing/verifier helpers.
  • SmrtHubSupervisor and Smrt.SupportBundle use StorageGuardSignedSnapshotClient to download and verify evidence before acting on it.
  • The shared-secret + signature schema is documented in README.Files/System/Policies/SmrtHub-Operational-Data-Policy-v1.0.README.md updates for Storage Guard.