Skip to content

Add policy-gated ETW logging for sidecar GCS - #1

Draft
marma-dev wants to merge 2 commits into
mainfrom
sidecar-gcs-etw-logging
Draft

marma-dev wants to merge 2 commits into
mainfrom
sidecar-gcs-etw-logging

Conversation

@marma-dev

@marma-dev marma-dev commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Emit sidecar GCS diagnostics through a dedicated Microsoft.Virtualization.GCSSidecar ETW provider using the existing etwlogrus hook.
  • Keep emission disabled until the validated confidential policy permits allow_runtime_logging; reuse existing Log Forward Service provider policy for collection without adding a new permission.
  • Include the provider in default collection at Information level and merge provider-name/GUID case variants without duplicate subscriptions.

Validation performed

  • Changed-package Windows suites, targeted Rego logging-policy tests, Go vet, sidecar/host builds, and Linux shared-policy test cross-compilation passed.
  • Live VBS C-WCOW with Secure Boot enabled confirmed sidecar forwarding and continued host parsing with the timestamp fix in Handle formatting markers in forwarded ETW timestamps #2. Runtime logging denied: zero sidecar events while other providers continued forwarding.
  • Fixed case-insensitive overrides and added canonical/lowercase/uppercase name and GUID regression coverage; provider and sidecar suites passed, and CI-pinned golangci-lint reported zero issues.
  • Ordinary non-confidential WCOW (NanoServer LTSC 2025, guest 10.0.26100.33674) booted with default options, confirmed SIDECAR_ABSENT, and completed its guest command with exit code 0.
  • Separately tested active Log Forward Service collection on the stock 10.0.28000.2178 VBS guest with the new provider absent and its canonical GUID requested: 216 events from other providers continued forwarding without a UVM startup failure.

Compatibility and coverage notes

  • Handle formatting markers in forwarded ETW timestamps #2 fixes the host timestamp parsing issue exposed by live testing and is required for correct consumption of the sidecar events.
  • Existing policies using default sources must allow the new provider or enable provider dropping; otherwise existing fail-close behavior may reject UVM startup.
  • Ordinary-WCOW startup and active absent-provider collection were validated separately: the LTSC 2025 guest does not advertise Log Forward Service support. An ordinary forwarding-capable WCOW image has not been tested end-to-end.
  • The existing launcher output-processing teardown hang and forced-shutdown partial-record diagnostic remain outside this PR; all test UVMs are stopped.

@marma-dev
marma-dev requested a balanced review from Copilot October 24, 2026 18:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

4 open issues
What changed in this PR

Adds a dedicated, policy-gated ETW provider for sidecar GCS diagnostics and wires runtime logging authorization into both standard Logrus output and ETW hook emission.

Changes:

  • Introduces WithRuntimeLoggingChanged + functional options on SecurityOptions and centralizes runtime logging configuration.
  • Adds sidecar ETW provider identity (Microsoft.Virtualization.GCSSidecar) to ETW GUID map and default log sources, plus tests.
  • Registers the sidecar ETW provider/hook in gcs-sidecar and documents policy + collection behavior.
File Description
pkg/​securitypolicy/​securitypolicy_options.go Adds runtime logging callback + functional options and centralizes runtime logging configuration.
pkg/​securitypolicy/​runtime_logging_test.go Tests runtime logging configuration behavior and callback invocation rules.
internal/​vm/​vmutils/​etw/​etw_map.go Adds sidecar provider name constant + GUID mapping.
internal/​vm/​vmutils/​etw/​default-sources.go Enables sidecar provider in default ETW sources at Information level.
internal/​vm/​vmutils/​etw/​sidecar_test.go Validates default sidecar provider config and deduping at the same casing.
internal/​vm/​vmutils/​etw/​sidecar_windows_test.go Validates provider registration GUID matches trusted GUID on Windows.
internal/​gcs-sidecar/​logging.go Adds RuntimeLoggingHook to gate hook emission independent of writer output.
internal/​gcs-sidecar/​logging_test.go Tests gating behavior and concurrency safety of the runtime logging hook.
internal/​gcs-sidecar/​logging_policy_test.go Tests policy gating for sidecar provider subscription forwarding.
internal/​gcs-sidecar/​host.go Threads SecurityOptions functional options through sidecar host initialization.
internal/​gcs-sidecar/​bridge.go Threads SecurityOptions functional options through bridge construction.
cmd/​gcs-sidecar/​main.go Registers ETW provider + gated hook and connects it to validated policy decisions.
docs/​sidecar-gcs-logging.md Documents provider, policy gating, configuration, and compatibility behavior.

Review effort: Lite

Comment thread internal/vm/vmutils/etw/sidecar_test.go Outdated
Comment on lines +12 to +18
for _, level := range []string{"Information", "Verbose"} {
var user LogSourcesInfo
if level == "Verbose" {
user.LogConfig.Sources = []Source{{Type: "ETW", Providers: []EtwProvider{
{ProviderName: SidecarProviderName, Level: level},
}}}
}
Comment thread cmd/gcs-sidecar/main.go
Comment on lines +197 to +211
var loggingOptions []func(*securitypolicy.SecurityOptions)
// Keep the provider registered until process exit, as in the host shim.
provider, err := etw.NewProvider(logsources.SidecarProviderName, nil)
if err != nil {
logrus.WithError(err).Error("failed to register sidecar ETW provider")
} else if hook, err := etwlogrus.NewHookFromProvider(provider); err != nil {
logrus.WithError(err).Error("failed to initialize sidecar ETW hook")
if err := provider.Close(); err != nil {
logrus.WithError(err).Error("failed to close sidecar ETW provider")
}
} else {
gatedHook := sidecar.NewRuntimeLoggingHook(hook)
logrus.AddHook(gatedHook)
loggingOptions = append(loggingOptions, securitypolicy.WithRuntimeLoggingChanged(gatedHook.SetAllowed))
}
Comment on lines +5 to +11
"testing"
)

func TestSidecarDefaultLogSource(t *testing.T) {
// Updating sources mutates the shared defaults; restore them after the test.
original := cloneLogSourcesInfo(defaultLogSourcesInfo)
t.Cleanup(func() { defaultLogSourcesInfo = original })
Comment on lines +74 to +82
// WithRuntimeLoggingChanged observes the validated policy's runtime logging
// decision. The callback must not block or reenter SecurityOptions.
func WithRuntimeLoggingChanged(callback func(bool)) func(*SecurityOptions) {
return func(s *SecurityOptions) {
s.runtimeLoggingChanged = callback
}
}

func NewSecurityOptions(enforcer SecurityPolicyEnforcer, enforcerSet bool, uvmReferenceInfo string, uvmHashEnvelopeReferenceInfo string, logWriter io.Writer, options ...func(*SecurityOptions)) *SecurityOptions {
@marma-dev

Copy link
Copy Markdown
Owner Author

Validated the private Rego-enabled sidecar in a VBS C-WCOW UVM with Secure Boot enabled: ETW logs reached the host and subsequent events continued parsing with the host timestamp fix in #2. Runtime logging denied: zero sidecar events while other ETW providers continued forwarding.

Manish Ranjan Mahanta added 2 commits November 5, 2026 21:52
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
@marma-dev
marma-dev force-pushed the sidecar-gcs-etw-logging branch from 06b5d20 to 03b8e51 Compare November 5, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants