test(ssh): use native signing archive fixtures

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-07-15 08:32:20 -04:00
co-authored by Orca
parent 0c43b83e82
commit 85c70c5e90
2 changed files with 105 additions and 55 deletions
@@ -88,7 +88,10 @@ afterEach(async () => {
describe('SSH relay runtime archive extraction', () => {
it('reconstructs exact POSIX and Windows runtime trees into exclusive directories', async () => {
for (const tupleId of ['darwin-arm64', 'win32-x64']) {
// Why: NTFS cannot materialize the executable modes needed to construct a POSIX tar fixture.
const tuples =
process.platform === 'win32' ? [`win32-${process.arch}`] : ['darwin-arm64', 'win32-x64']
for (const tupleId of tuples) {
const value = await fixture(tupleId)
const outputDirectory = join(value.root, 'reconstructed')
const result = await extractSshRelayRuntimeArchive({
@@ -106,7 +109,8 @@ describe('SSH relay runtime archive extraction', () => {
})
it('rejects modified archives and existing outputs without retaining partial trees', async () => {
const modified = await fixture('darwin-x64')
const modifiedTuple = process.platform === 'win32' ? `win32-${process.arch}` : 'darwin-x64'
const modified = await fixture(modifiedTuple)
await writeFile(modified.archive.path, 'not the authenticated archive')
const rejectedOutput = join(modified.root, 'rejected')
await expect(
@@ -9,7 +9,9 @@ import { expectedSshRelayRuntimeClosureEntries } from './ssh-relay-runtime-closu
import { sshRelayRuntimeCompatibility } from './ssh-relay-runtime-compatibility.mjs'
import { computeSshRelayRuntimeContentId } from './ssh-relay-runtime-identity.mjs'
import { finalizeSshRelayRuntimeNativeSigning } from './ssh-relay-runtime-native-signing-finalization.mjs'
import { buildSshRelayRuntimeNativeSigningPlan } from './ssh-relay-runtime-native-signing-plan.mjs'
import { prepareSshRelayRuntimeNativeSigningStage } from './ssh-relay-runtime-native-signing-stage.mjs'
import { parseSshRelayRuntimeNativeSigningStageReport } from './ssh-relay-runtime-native-signing-stage-report.mjs'
const temporaryDirectories = []
const SOURCE_DATE_EPOCH = 1_788_739_200
@@ -19,7 +21,8 @@ function digest(bytes) {
return `sha256:${createHash('sha256').update(bytes).digest('hex')}`
}
function toolchain() {
function toolchain(tupleId) {
const platformTool = tupleId.startsWith('win32-') ? 'linker' : 'strip'
return Object.fromEntries(
[
'buildNode',
@@ -30,7 +33,7 @@ function toolchain() {
'archive',
'nodeAddonApi',
'nodeGyp',
'strip'
platformTool
].map((name, index) => [
name,
{ version: `${name} fixture`, sha256: `sha256:${(index + 1).toString(16).repeat(64)}` }
@@ -38,13 +41,17 @@ function toolchain() {
)
}
async function fixture() {
async function fixture(
tupleId = process.platform === 'win32' ? `win32-${process.arch}` : 'darwin-arm64'
) {
const root = await mkdtemp(join(tmpdir(), 'ssh-relay-signing-finalization-'))
temporaryDirectories.push(root)
const sourceRuntimeRoot = join(root, 'source-runtime')
await mkdir(sourceRuntimeRoot)
const entries = []
for (const entry of expectedSshRelayRuntimeClosureEntries('darwin-arm64')) {
// Why: Windows finalization must create a ZIP because NTFS cannot supply POSIX tar modes.
const os = tupleId.startsWith('win32-') ? 'win32' : 'darwin'
for (const entry of expectedSshRelayRuntimeClosureEntries(tupleId)) {
const path = join(sourceRuntimeRoot, ...entry.path.split('/'))
if (entry.type === 'directory') {
await mkdir(path, { recursive: true, mode: entry.mode })
@@ -58,10 +65,10 @@ async function fixture() {
}
const base = {
identitySchemaVersion: 1,
tupleId: 'darwin-arm64',
os: 'darwin',
architecture: 'arm64',
compatibility: sshRelayRuntimeCompatibility['darwin-arm64'],
tupleId,
os,
architecture: tupleId.includes('arm64') ? 'arm64' : 'x64',
compatibility: sshRelayRuntimeCompatibility[tupleId],
nodeVersion: '24.18.0',
dependencies: { nodePtyVersion: '1.1.0', parcelWatcherVersion: '2.5.6' },
entries
@@ -74,11 +81,30 @@ async function fixture() {
expandedSize: files.reduce((total, entry) => total + entry.size, 0)
}
const returnedRoot = join(root, 'returned')
const preserved = new Set([
'node_modules/node-pty/build/Release/conpty/OpenConsole.exe',
'node_modules/node-pty/build/Release/conpty/conpty.dll'
])
const assessments =
os === 'win32'
? buildSshRelayRuntimeNativeSigningPlan(sourceIdentity).signingCandidates.map((entry) =>
preserved.has(entry.path)
? {
path: entry.path,
sourceSha256: entry.sourceSha256,
status: 'valid-upstream',
signerSubject: 'CN=Microsoft Corporation',
signerThumbprint: 'D'.repeat(40)
}
: { path: entry.path, sourceSha256: entry.sourceSha256, status: 'unsigned' }
)
: []
const report = await prepareSshRelayRuntimeNativeSigningStage({
identity: sourceIdentity,
runtimeRoot: sourceRuntimeRoot,
stagingRoot: returnedRoot,
platform: 'darwin'
platform: os,
assessWindowsImpl: async () => assessments
})
for (const entry of report.signingFiles) {
await appendFile(join(returnedRoot, ...entry.path.split('/')), ':signed')
@@ -86,18 +112,8 @@ async function fixture() {
const nodeRelease = JSON.parse(
await readFile(new URL('../ssh-relay-node-release-v24.18.0.json', import.meta.url), 'utf8')
)
const selection = {
tupleId: report.tupleId,
platform: report.platform,
policy: report.policy,
immutableVendorFiles: report.immutableVendorFiles,
signingFiles: report.signingFiles,
preservedUpstreamFiles: report.preservedUpstreamFiles,
verificationFiles: [...report.immutableVendorFiles, ...report.signingFiles].map(
({ path, role, sourceSha256, sourceSize }) => ({ path, role, sourceSha256, sourceSize })
)
}
return { root, sourceRuntimeRoot, returnedRoot, sourceIdentity, selection, nodeRelease }
const { selection } = parseSshRelayRuntimeNativeSigningStageReport(sourceIdentity, report)
return { root, tupleId, sourceRuntimeRoot, returnedRoot, sourceIdentity, selection, nodeRelease }
}
function nativeReport(sourceIdentity, finalIdentity, selection) {
@@ -106,18 +122,41 @@ function nativeReport(sourceIdentity, finalIdentity, selection) {
.filter((entry) => entry.type === 'file')
.map((entry) => [entry.path, entry])
)
const immutable = new Set(selection.immutableVendorFiles.map((entry) => entry.path))
const signing = new Set(selection.signingFiles.map((entry) => entry.path))
return {
tupleId: finalIdentity.tupleId,
sourceContentId: sourceIdentity.contentId,
finalContentId: finalIdentity.contentId,
verifiedFiles: selection.verificationFiles.map((entry) => ({
path: entry.path,
role: entry.role,
sha256: finalFiles.get(entry.path).sha256,
signerKind: entry.role === 'node' ? 'official-node' : 'orca-built',
authority: `Developer ID Application: Fixture (${entry.role === 'node' ? 'HX7739G8FX' : 'ABCDEFGHIJ'})`,
teamIdentifier: entry.role === 'node' ? 'HX7739G8FX' : 'ABCDEFGHIJ'
}))
verifiedFiles: selection.verificationFiles.map((entry) => {
const signerKind = immutable.has(entry.path)
? 'official-node'
: signing.has(entry.path)
? 'orca-built'
: 'preserved-upstream'
const base = {
path: entry.path,
role: entry.role,
sha256: finalFiles.get(entry.path).sha256,
signerKind
}
return sourceIdentity.os === 'win32'
? {
...base,
signerSubject:
signerKind === 'official-node'
? 'CN=OpenJS Foundation'
: signerKind === 'orca-built'
? 'CN=SignPath Foundation'
: 'CN=Microsoft Corporation',
signerThumbprint: (signerKind === 'preserved-upstream' ? 'D' : 'A').repeat(40)
}
: {
...base,
authority: `Developer ID Application: Fixture (${signerKind === 'official-node' ? 'HX7739G8FX' : 'ABCDEFGHIJ'})`,
teamIdentifier: signerKind === 'official-node' ? 'HX7739G8FX' : 'ABCDEFGHIJ'
}
})
}
}
@@ -130,14 +169,17 @@ function finalizationInput(value, outputDirectory) {
gitCommit: GIT_COMMIT,
builder: 'https://github.com/stablyai/orca/ssh-relay-runtime-native-signing-fixture',
runner: {
os: 'macOS',
architecture: 'ARM64',
os: value.sourceIdentity.os === 'win32' ? 'Windows' : 'macOS',
architecture: value.sourceIdentity.architecture.toUpperCase(),
environment: 'fixture',
requestedLabel: 'macos-15',
image: { os: 'macos', version: 'fixture' }
requestedLabel: value.sourceIdentity.os === 'win32' ? 'windows-fixture' : 'macos-15',
image: { os: value.sourceIdentity.os, version: 'fixture' }
},
toolchain: toolchain(value.tupleId),
nativeVerificationTool: {
name: value.sourceIdentity.os === 'win32' ? 'Get-AuthenticodeSignature' : 'codesign',
version: 'fixture-v1'
},
toolchain: toolchain(),
nativeVerificationTool: { name: 'codesign', version: 'fixture-v1' },
verifiedAt: '2026-07-15T12:00:00.000Z',
verifyNativeImpl: ({ sourceIdentity, finalIdentity, selection }) =>
nativeReport(sourceIdentity, finalIdentity, selection),
@@ -158,25 +200,29 @@ afterEach(async () => {
describe('SSH relay runtime native signing finalization', () => {
it('emits only final signed-byte assets after native verification and smoke', async () => {
const value = await fixture()
const outputDirectory = join(value.root, 'final')
const result = await finalizeSshRelayRuntimeNativeSigning(
finalizationInput(value, outputDirectory)
)
const tuples =
process.platform === 'win32' ? [`win32-${process.arch}`] : ['darwin-arm64', 'win32-x64']
for (const tupleId of tuples) {
const value = await fixture(tupleId)
const outputDirectory = join(value.root, 'final')
const result = await finalizeSshRelayRuntimeNativeSigning(
finalizationInput(value, outputDirectory)
)
expect(result.finalContentId).not.toBe(value.sourceIdentity.contentId)
expect(result.returnedFiles).toHaveLength(3)
expect(await readdir(result.assetsRoot)).toHaveLength(4)
expect(
(await readdir(result.assetsRoot)).some((name) => name.endsWith('.manifest-tuple.json'))
).toBe(true)
expect(await readdir(result.evidenceRoot)).toEqual(
expect.arrayContaining([
'darwin-arm64.final-identity.json',
'darwin-arm64.finalization.json',
'darwin-arm64.native-verification.json'
])
)
expect(result.finalContentId).not.toBe(value.sourceIdentity.contentId)
expect(result.returnedFiles).toHaveLength(3)
expect(await readdir(result.assetsRoot)).toHaveLength(4)
expect(
(await readdir(result.assetsRoot)).some((name) => name.endsWith('.manifest-tuple.json'))
).toBe(true)
expect(await readdir(result.evidenceRoot)).toEqual(
expect.arrayContaining([
`${value.tupleId}.final-identity.json`,
`${value.tupleId}.finalization.json`,
`${value.tupleId}.native-verification.json`
])
)
}
})
it('removes the complete output when native trust fails', async () => {