Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a9ffe80
feat(isolation-session): bind MSI runtime via coresident explicit-load
dalegg Aug 7, 2026
5427e7b
fix(isolation-session): harden coresident explicit-load per code review
dalegg Aug 7, 2026
8b480b7
isosession: emit ungated diagnostic on fail-closed explicit override
dalegg Aug 7, 2026
20e621e
isosession: check in the OS-produced SDK nuget for in-repo bindgen
dalegg Aug 7, 2026
4a60266
isolation_session: generate WinRT bindings from the pinned nuget at b…
dalegg Aug 7, 2026
2b14ecc
isolation_session: align runtime identity to 2608
dalegg Aug 7, 2026
fb0b189
isosession: activate via reg-free private CLSID, drop LoadLibrary
dalegg Aug 10, 2026
23777dd
IsoSession SDK nupkg: 2026.08 runtime shim + SxS-fixed manifest + v2 …
dalegg Aug 10, 2026
654ee37
isosession: repack SDK nuget with 2026_08 reg-key App.dll + fix probe…
dalegg Aug 10, 2026
c344e73
wxc build.rs: stage IsoSessionApp.runtimeversion next to wxc-exec
dalegg Aug 10, 2026
4e5d896
Update IsolationSession 2608 SDK package
dalegg Aug 20, 2026
d8bafdc
Integrate lifted IsolationSession SDK activation
dalegg Sep 1, 2026
c6688ed
Add inbox and lifted IsolationSession build modes
dalegg Sep 9, 2026
6b7fdf3
Consume completed IsoSession runtime manifest
dalegg Sep 24, 2026
5ea82d6
Repin lean IsolationSession SDK package
dalegg Sep 24, 2026
dc5f046
Make IsolationSession inbox/lifted modes consistent across SDKs
dalegg Oct 1, 2026
101bfe0
IsoSession Runtime version checks (#1376)
daamenik Oct 5, 2026
88ecf62
Prepare lifted IsolationSession SDK integration and CI
dalegg Oct 6, 2026
bd2a0f6
Consume published IsolationSession SDK package
dalegg Oct 6, 2026
9aca872
Finalize IsolationSession SDK package integration
dalegg Oct 6, 2026
bd09ace
Fix packaged IsolationSession lockfile lookup
dalegg Oct 7, 2026
1040b76
Use configured NuGet restore for lifted IsolationSession
dalegg Oct 7, 2026
b5d77b2
Harden lifted IsolationSession package integration
dalegg Oct 7, 2026
6401f0c
Retrigger CI after dependency feed seeding
dalegg Oct 7, 2026
9427284
Fix lifted restore inputs for workspace builds
dalegg Oct 7, 2026
319472d
Complete lifted cross-host and Node packaging validation
dalegg Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions .azure-pipelines/Update.Feed.Dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Seeds the public shine-oss MxcDependencies feed with every crates.io crate in
# src/Cargo.lock.
# Seeds the public shine-oss MxcDependencies feeds with the dependencies pinned
# by src/Cargo.lock and the IsolationSession SDK package constants.
#
# This pipeline cannot be run with `/azp run`; run it manually from shine-oss
# (Run pipeline at https://dev.azure.com/shine-oss/mxc/_build?definitionId=33).
Expand All @@ -21,17 +21,26 @@ jobs:
- checkout: self
persistCredentials: true

# Overlay only the lockfile from the PR head onto the trusted checkout. cargo is never
# run and only Cargo.lock (data) is read, so no PR code executes. Review the PR's
# Cargo.lock first.
# Overlay only dependency-pin data from the PR head onto the trusted
# checkout. Neither Cargo nor the Rust source is executed: the script
# parses Cargo.lock and three string constants from the build helper.
# Review both files before running this manually triggered pipeline.
- script: |
set -euo pipefail
git fetch origin "pull/${{ parameters.prNumber }}/head"
git checkout FETCH_HEAD -- src/Cargo.lock
echo "Overlaid Cargo.lock from PR #${{ parameters.prNumber }}"
displayName: Overlay Cargo.lock from PR
git checkout FETCH_HEAD -- \
src/Cargo.lock \
src/mxc-sdk/build/build_mxc_build_common.rs
echo "Overlaid dependency pins from PR #${{ parameters.prNumber }}"
displayName: Overlay dependency pins from PR

- script: python3 .azure-pipelines/scripts/seed_feed.py
displayName: Seed the MxcDependencies feed from Cargo.lock
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- task: NuGetAuthenticate@1
displayName: Authenticate to MxcDependencies

- script: python3 .azure-pipelines/scripts/seed_feed.py --nuget-only
displayName: Seed the IsolationSession SDK package into MxcDependencies
88 changes: 81 additions & 7 deletions .azure-pipelines/scripts/seed_feed.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
#!/usr/bin/env python3
"""Seed the public MxcDependencies cargo feed from src/Cargo.lock.
"""Seed the public MxcDependencies feeds from pinned repository dependencies.

The feed can be read without credentials, so cargo does not send a token when it reads.
As a result, cargo cannot make Azure Artifacts pull a missing crate from its crates.io
upstream. This script instead sends an authenticated request for each locked crate, which
makes the feed fetch and cache it. Later credential-free reads then resolve every dependency.
The Cargo feed can be read without credentials, so cargo does not send a token when it
reads. As a result, cargo cannot make Azure Artifacts pull a missing crate from its
crates.io upstream. This script instead sends an authenticated request for each locked
crate, which makes the feed fetch and cache it. Later credential-free reads then resolve
every dependency.

The script only reads Cargo.lock and never runs cargo or build scripts, so it is safe to run
against a fork's lockfile.
The NuGet mode reads the pinned IsolationSession package identity and hash, downloads that
public package, verifies it, and publishes it through the authenticated NuGet client.
"""
import hashlib
import json
import os
import re
import subprocess
import sys
import tempfile
import tomllib
import urllib.request
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import NamedTuple

FEED_INDEX_URL = "https://pkgs.dev.azure.com/shine-oss/mxc/_packaging/MxcDependencies/Cargo/index"
CARGO_LOCK = "src/Cargo.lock"
ISOLATION_SESSION_PIN = "src/mxc-sdk/build/build_mxc_build_common.rs"
NUGET_FEED_URL = (
"https://pkgs.dev.azure.com/shine-oss/mxc/"
"_packaging/MxcDependencies/nuget/v3/index.json"
)
MAX_WORKERS = 16
REQUEST_TIMEOUT = 30 # seconds; fail a stuck request instead of hanging the job

Expand Down Expand Up @@ -82,7 +93,70 @@ def _read_locked_crates() -> list[Crate]:
]


def _read_isolation_session_pin() -> tuple[str, str, str]:
content = Path(ISOLATION_SESSION_PIN).read_text(encoding="utf-8")

def constant(name: str) -> str:
match = re.search(
rf'pub const {name}: &str =\s*"([^"]+)";',
content,
)
if not match:
raise RuntimeError(f"Could not read {name} from {ISOLATION_SESSION_PIN}")
return match.group(1)

return (
constant("PACKAGE_ID"),
constant("PACKAGE_VERSION"),
constant("PACKAGE_SHA256"),
)


def _seed_nuget_package() -> None:
package_id, version, expected_hash = _read_isolation_session_pin()
lower_id = package_id.lower()
file_name = f"{lower_id}.{version}.nupkg"
source_url = f"https://api.nuget.org/v3-flatcontainer/{lower_id}/{version}/{file_name}"

with tempfile.TemporaryDirectory() as directory:
package_path = Path(directory) / file_name
print(f"Downloading {package_id} {version} from NuGet.org for feed seeding")
with urllib.request.urlopen(source_url, timeout=REQUEST_TIMEOUT) as response:
package_path.write_bytes(response.read())

actual_hash = hashlib.sha256(package_path.read_bytes()).hexdigest()
if actual_hash.lower() != expected_hash.lower():
raise RuntimeError(
f"{package_id} {version} hash mismatch: "
f"expected {expected_hash}, got {actual_hash}"
)

subprocess.run(
[
"dotnet",
"nuget",
"push",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Medium (proportionality) — Constrain the newly authenticated NuGet publication path.

Attribution: introduced_by_change — the manually triggered trusted pipeline overlays PACKAGE_ID, version and SHA-256 from the PR, downloads from a fixed NuGet.org endpoint, then uses this new authenticated nuget push to the governed feed. The expected hash is self-attested by the same PR; the PR description asks for standing Contributor permission for the build identity.

This does not let arbitrary PR code run and still requires an authorized pipeline trigger. It does broaden the long-lived write permission and package IDs eligible for publication beyond consuming this pinned, already-seeded package.

Fix: Prefer read-through/upstream acquisition; otherwise allowlist the IsolationSession package identity and use a narrowly scoped publishing identity/permission for this manual operation.

str(package_path),
"--source",
NUGET_FEED_URL,
"--api-key",
"AzureDevOps",
"--skip-duplicate",
],
check=True,
)
print(f"Seeded {package_id} {version} into MxcDependencies")


def main() -> int:
if sys.argv[1:] == ["--nuget-only"]:
try:
_seed_nuget_package()
except (OSError, RuntimeError, subprocess.CalledProcessError) as error:
print(f"Failed to seed IsolationSession SDK package: {error}")
return 1
return 0

token = os.environ.get("SYSTEM_ACCESSTOKEN")
if not token:
print("SYSTEM_ACCESSTOKEN is not set; cannot authenticate to the feed")
Expand Down
150 changes: 150 additions & 0 deletions .github/workflows/Build.Windows.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ name: Windows Build

on:
workflow_call:
inputs:
run_isolation_session_lifted:
description: Run x64 Cargo validation against the published lifted IsolationSession SDK package.
required: false
default: false
type: boolean

jobs:
build:
Expand Down Expand Up @@ -120,3 +126,147 @@ jobs:
src/target/${{ matrix.target }}/release/wxc-test-driver.exe
if-no-files-found: error
retention-days: 1

isolation-session-lifted:
name: x64 isolation_session_lifted
if: inputs.run_isolation_session_lifted
runs-on: windows-2025
defaults:
run:
working-directory: src
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Surface toolchain file at repo root
shell: bash
working-directory: ${{ github.workspace }}
run: cp src/rust-toolchain.toml rust-toolchain.toml

- uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0
with:
target: x86_64-pc-windows-msvc
override: false
rustflags: ''

- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: |
8.0.x
10.0.x

- name: Point cargo at the MxcDependencies feed
uses: ./.github/actions/setup-cargo-feed

- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: src -> target
key: x86_64-pc-windows-msvc-isolation-session-lifted-v1
cache-on-failure: false

- name: Test lifted SDK and compile FFI tests
run: |
cargo test --locked --release --target x86_64-pc-windows-msvc `
-p mxc-sdk --features isolation_session_lifted
cargo test --locked --release --target x86_64-pc-windows-msvc `
-p mxc_ffi --features isolation_session_lifted --no-run

- name: Build lifted CLI
run: cargo build --locked --release --target x86_64-pc-windows-msvc
-p wxc --no-default-features --features isolation_session_lifted

- name: Build and test lifted .NET SDK
working-directory: sdk/dotnet
shell: pwsh
run: |
dotnet build Microsoft.Mxc.Sdk.slnx -p:MxcIsolationSessionLifted=true
if ($LASTEXITCODE -ne 0) { throw "dotnet build exited $LASTEXITCODE" }

$testExe = 'Microsoft.Mxc.Sdk.Tests\bin\Debug\net8.0\Microsoft.Mxc.Sdk.Tests.exe'
if (-not (Test-Path -LiteralPath $testExe -PathType Leaf)) {
throw "The xUnit v3 test executable was not built: $testExe"
}

$log = Join-Path $env:RUNNER_TEMP 'dotnet-test-isolation-session-lifted.log'
& $testExe -automated sync -noColor 2>&1 |
Tee-Object -FilePath $log
$code = $LASTEXITCODE
if ($code -ne 0) { throw "The lifted managed tests exited $code" }
$summary = Get-Content -LiteralPath $log |
Where-Object { $_ -match '"\$type":"test-assembly-finished"' } |
Select-Object -Last 1 |
ConvertFrom-Json
if ($null -eq $summary -or $summary.TestsTotal -eq 0) {
throw 'The lifted run passed no tests, so it did not establish managed coverage.'
}
if ($summary.TestsFailed -ne 0 -or $summary.TestsNotRun -ne 0) {
throw "The lifted managed run was incomplete: $($summary | ConvertTo-Json -Compress)"
}

$pinLog = Join-Path $env:RUNNER_TEMP 'dotnet-test-isolation-session-lifted-pin.log'
& $testExe -automated sync -noColor `
-method '*IsolationSessionBuildSwitch*' 2>&1 |
Tee-Object -FilePath $pinLog
$code = $LASTEXITCODE
if ($code -ne 0) { throw "The lifted build-switch pin exited $code" }
$pinSummary = Get-Content -LiteralPath $pinLog |
Where-Object { $_ -match '"\$type":"test-assembly-finished"' } |
Select-Object -Last 1 |
ConvertFrom-Json
if (
$null -eq $pinSummary -or
$pinSummary.TestsTotal -ne 1 -or
$pinSummary.TestsFailed -ne 0 -or
$pinSummary.TestsSkipped -ne 0 -or
$pinSummary.TestsNotRun -ne 0
) {
throw 'The IsolationSession build-switch test did not run and pass in lifted mode.'
}

- name: Pack lifted .NET SDK
working-directory: sdk/dotnet
shell: pwsh
run: |
dotnet pack Microsoft.Mxc.Sdk/Microsoft.Mxc.Sdk.csproj `
--configuration Release `
-p:MxcIsolationSessionLifted=true `
-p:MxcPackSingleRid=true `
-p:MxcPackageRid=win-x64
if ($LASTEXITCODE -ne 0) { throw "dotnet pack exited $LASTEXITCODE" }

$packages = @(Get-ChildItem Microsoft.Mxc.Sdk\bin\Release\*.nupkg)
if ($packages.Count -ne 1) {
throw "Expected exactly one packed SDK, found $($packages.Count)."
}
Add-Type -AssemblyName System.IO.Compression.FileSystem
$archive = [System.IO.Compression.ZipFile]::OpenRead($packages[0].FullName)
try {
$entries = @($archive.Entries | ForEach-Object FullName)
foreach ($entry in @(
'runtimes/win-x64/native/IsoSessionApp.dll',
'runtimes/win-x64/native/IsoSession.manifest'
)) {
if ($entry -notin $entries) {
throw "Packed SDK is missing lifted runtime entry: $entry"
}
}
}
finally {
$archive.Dispose()
}

- name: Verify adjacent activation payload
shell: pwsh
run: |
$releaseDir = 'target\x86_64-pc-windows-msvc\release'
$requiredFiles = @(
'wxc-exec.exe',
'IsoSessionApp.dll',
'IsoSession.manifest'
)

foreach ($file in $requiredFiles) {
$path = Join-Path $releaseDir $file
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
throw "Lifted build did not stage required file: $path"
}
}
2 changes: 2 additions & 0 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ jobs:
windows:
needs: dependency-feed-check
uses: ./.github/workflows/Build.Windows.Job.yml
with:
run_isolation_session_lifted: true

linux:
needs: dependency-feed-check
Expand Down
Loading
Loading