Skip to content

Write enhanced fragment loading diagnostics and expose to container in the security context#2830

Open
micromaomao wants to merge 3 commits into
microsoft:mainfrom
micromaomao:fragments-debug-dir
Open

Write enhanced fragment loading diagnostics and expose to container in the security context#2830
micromaomao wants to merge 3 commits into
microsoft:mainfrom
micromaomao:fragments-debug-dir

Conversation

@micromaomao

@micromaomao micromaomao commented Jul 20, 2026

Copy link
Copy Markdown
Member

This is useful as a debugging aid and not a security feature.

Enhance the existing fragment dumping code to also write the error string or a success marker, the decoded fragment content, and metadata, and place them in a findable place on Windows and Linux.

Example:

PS C:\Users\azureuser\wcow_skr_fragment> .\runp.ps1
Started pod wcow_skr_fragment with ID:
3150bc51b63c583689503d1c26fe1d08a6cdddc217ff5087f9875bcd09a4f231
PS C:\Users\azureuser\wcow_skr_fragment> $env:podId=azcrictl pods -q
PS C:\Users\azureuser\wcow_skr_fragment> azcrictl inject-fragment $env:podId 'acidevacr.azurecr.io/internal/aci/aci-cc-infra-fragment:transparent-fragment-signing-0-20260615.3'
time="2026-07-19T23:37:53Z" level=fatal msg="injecting policy fragment: rpc error: code = Unknown desc = failed to inject any fragment: guest modify: guest RPC failure: error loading security policy fragment: policyDecision< eyJkZWNpc2lvbiI6ImRlbnkiLCJpbnB1dCI6eyJmZWVkIjoiYWNpZGV2YWNyLmF6dXJlY3IuaW8vaW50ZXJuYWwvYWNpL2FjaS1jYy1pbmZyYS1mcmFnbWVudCIsImZyYWdtZW50X2xvYWRlZCI6ZmFsc2UsImhhc19oZWFkZXJfc3ZuIjpmYWxzZSwiaGVhZGVyX3N2biI6bnVsbCwiaXNzdWVyIjoiZGlkOng1MDk6MDpzaGEyNTY6d1ZrU000NlNEcHc0THV5RVlvSDZyNXltMDd3aEw1bFd4TmxHTi1VUHRmNDo6ZWt1OjEuMy42LjEuNC4xLjMxMS4xMC4zLjEzIiwibmFtZXNwYWNlIjoiYXp1cmVjb250YWluZXJpbnN0YW5jZSIsInJlY2VpcHRzIjpbXSwicnVsZSI6ImxvYWRfZnJhZ21lbnQifSwicmVhc29uIjp7ImVycm9ycyI6WyJtaXNzaW5nIHJlY2VpcHQgZnJvbSBlc3JwLWN0cy1kZXYuY29uZmlkZW50aWFsLWxlZGdlci5henVyZS5jb20iXX19 >policyDecision\nguest modify: guest RPC failure: error loading security policy fragment: policyDecision< eyJkZWNpc2lvbiI6ImRlbnkiLCJpbnB1dCI6eyJmZWVkIjoiYWNpZGV2YWNyLmF6dXJlY3IuaW8vaW50ZXJuYWwvYWNpL2FjaS1jYy1pbmZyYS1mcmFnbWVudCIsImZyYWdtZW50X2xvYWRlZCI6ZmFsc2UsImhhc19oZWFkZXJfc3ZuIjp0cnVlLCJoZWFkZXJfc3ZuIjowLCJpc3N1ZXIiOiJkaWQ6eDUwOTowOnNoYTI1Njp3VmtTTTQ2U0RwdzRMdXlFWW9INnI1eW0wN3doTDVsV3hObEdOLVVQdGY0Ojpla3U6MS4zLjYuMS40LjEuMzExLjEwLjMuMTMiLCJuYW1lc3BhY2UiOiJhenVyZWNvbnRhaW5lcmluc3RhbmNlIiwicmVjZWlwdHMiOltdLCJydWxlIjoibG9hZF9mcmFnbWVudCJ9LCJyZWFzb24iOnsiZXJyb3JzIjpbIm1pc3NpbmcgcmVjZWlwdCBmcm9tIGVzcnAtY3RzLWRldi5jb25maWRlbnRpYWwtbGVkZ2VyLmF6dXJlLmNvbSJdfX0= >policyDecision"
PS C:\Users\azureuser\wcow_skr_fragment> .\createc.ps1
a261dd550c2868f26bce5013edf96b9ae4f2040296c4ad74ee96b36479298f52
PS C:\Users\azureuser\wcow_skr_fragment> .\startc.ps1
a261dd550c2868f26bce5013edf96b9ae4f2040296c4ad74ee96b36479298f52
Started container wcow_skr_fragment_skr_cwcow_fragment_skr with ID:
a261dd550c2868f26bce5013edf96b9ae4f2040296c4ad74ee96b36479298f52
PS C:\Users\azureuser\wcow_skr_fragment> .\container.ps1 powershell

PS C:\app> dir C:\security-context-2340068210\


    Directory: C:\security-context-2340068210


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         7/19/2026  11:37 PM                fragments.debug
-a----          7/1/2026   7:47 AM          45056 amdsnppspapi.dll
-a----         7/19/2026  11:38 PM          13956 reference-info-base64
-a----         7/19/2026  11:38 PM           6412 security-policy-base64

PS C:\app> dir C:\security-context-2340068210\fragments.debug\b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c


    Directory: C:\security-context-2340068210\fragments.debug\b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/19/2026  11:37 PM            632 2.fail
-a----         7/19/2026  11:37 PM          83742 fragment
-a----         7/19/2026  11:37 PM          87785 fragment.cose
-a----         7/19/2026  11:37 PM            182 metadata.json

PS C:\app> cat C:\security-context-2340068210\fragments.debug\b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c\2.fail
error loading security policy fragment: policyDecision< ... >policyDecision
> base64 -d | jq
...
{
  "decision": "deny",
  "input": {
    "feed": "acidevacr.azurecr.io/internal/aci/aci-cc-infra-fragment",
    "fragment_loaded": false,
    "has_header_svn": true,
    "header_svn": 0,
    "issuer": "did:x509:0:sha256:wVkSM46SDpw4LuyEYoH6r5ym07whL5lWxNlGN-UPtf4::eku:1.3.6.1.4.1.311.10.3.13",
    "namespace": "azurecontainerinstance",
    "receipts": [],
    "rule": "load_fragment"
  },
  "reason": {
    "errors": [
      "missing receipt from esrp-cts-dev.confidential-ledger.azure.com"
    ]
  }
}
PS C:\app> exit
PS C:\Users\azureuser\wcow_skr_fragment> azcrictl inject-fragment $env:podId 'acidevacr.azurecr.io/internal/aci/aci-cc-ttl:transparent-fragment-signing-0-20260615.1'
sha256:2cacf5a79d1d6f28eeeb8ff5e30bb634a6caffb6afd85b9e4549a90556cd45f3
PS C:\Users\azureuser\wcow_skr_fragment> azcrictl inject-fragment $env:podId 'acidevacr.azurecr.io/internal/aci/aci-cc-infra-fragment:transparent-fragment-signing-0-20260615.3'
sha256:b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c

PS C:\app> dir C:\security-context-2340068210\fragments.debug\b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c


    Directory: C:\security-context-2340068210\fragments.debug\b59e1ac5ea85d58a515d1369b05f21245f76627858803ccbdb543e0b3b64362c


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/19/2026  11:37 PM            632 2.fail
-a----         7/19/2026  11:41 PM              0 6.succeed
-a----         7/19/2026  11:37 PM          83742 fragment
-a----         7/19/2026  11:37 PM          87785 fragment.cose
-a----         7/19/2026  11:37 PM            182 metadata.json

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.

Pull request overview

This PR enhances security policy fragment injection diagnostics by persisting decoded fragment artifacts (COSE, payload, metadata, and per-request outcome markers) in a predictable guest location, and exposing those diagnostics to the workload container via the existing security-context mechanism (LCOW and WCOW).

Changes:

  • Add per-fragment dump directory keyed by fragment SHA, writing fragment.cose, decoded fragment, metadata.json, and {n}.succeed / {n}.fail markers.
  • Introduce guest paths for fragment diagnostics (/tmp/fragments for LCOW, C:\InjectedFragments for WCOW).
  • Mount/map the fragments diagnostics directory into the container under <security-context-dir>/fragments.debug after policy enforcement.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
pkg/securitypolicy/securitypolicy_options.go Implements enhanced fragment dump (COSE/payload/metadata) and per-request success/failure markers; creates fragments directory during policy setup.
internal/guestpath/paths.go Adds constants for LCOW/WCOW fragments diagnostics storage locations inside the UVM.
internal/guest/runtime/hcsv2/uvm.go Adds a post-enforcement bind mount to expose fragments diagnostics into the LCOW container’s security-context directory.
internal/gcs-sidecar/handlers.go Adds a post-enforcement mapped directory to expose fragments diagnostics into the WCOW container’s security-context directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +77 to +79
if err := os.MkdirAll(fragmentsPath(), 0755); err != nil {
return fmt.Errorf("failed to create injected fragments directory: %w", err)
}
Comment on lines +241 to +246
if err := os.MkdirAll(thisFragmentDir, 0755); err != nil {
return fmt.Errorf("failed to create injected fragment directory: %w", err)
}
if err := writeFileIfNotExists(filepath.Join(thisFragmentDir, "fragment.cose"), raw, 0644); err != nil {
return fmt.Errorf("failed to write fragment.cose: %w", err)
}
Comment on lines +261 to +263
if err := writeFileIfNotExists(filepath.Join(thisFragmentDir, "fragment"), unpacked.Payload, 0644); err != nil {
return fmt.Errorf("failed to write injected fragment payload: %w", err)
}
Comment on lines +41 to +45
// Global counter for fragment injection requests, used to create unique
// error / success marker files even when the same fragment is injected
// multiple times.
var FragmentRequestId atomic.Uint64

Comment on lines +748 to +755
if securityContextDir != "" {
settings.OCISpecification.Mounts = append(settings.OCISpecification.Mounts, specs.Mount{
Destination: path.Join("/", filepath.Base(securityContextDir), "fragments.debug"),
Type: "bind",
Source: guestpath.LCOWFragmentsPath,
Options: []string{"bind", "ro"},
})
}
Comment on lines +186 to +192
if securityContextDir != "" {
container.MappedDirectories = append(container.MappedDirectories, hcsschema.MappedDirectory{
HostPath: guestpath.WCOWFragmentsPath,
ContainerPath: filepath.Join(`C:\`, filepath.Base(securityContextDir), "fragments.debug"),
ReadOnly: true,
})
}
Write the error string or a success marker, the decoded fragment content,
and headers, and place them in a findable place on Windows and Linux.

Assisted-by: GitHub-Copilot copilot-review
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
…\fragments.debug

[cherry-pick of 43dcfafab onto main]

Assisted-by: GitHub-Copilot copilot-review
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
…ragments.debug

Assisted-by: GitHub-Copilot copilot-review
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
@micromaomao
micromaomao force-pushed the fragments-debug-dir branch from 988c0c2 to 4600cb1 Compare July 20, 2026 16:09
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