diff --git a/dstack/kms/auth-eth/test/DstackApp.t.sol b/dstack/kms/auth-eth/test/DstackApp.t.sol index 646bd827e..9f590d2e3 100644 --- a/dstack/kms/auth-eth/test/DstackApp.t.sol +++ b/dstack/kms/auth-eth/test/DstackApp.t.sol @@ -265,9 +265,11 @@ contract DstackAppTest is Test { vm.startPrank(owner); app.addDevice(deviceId); app.addComposeHash(composeHash); - app.setRequireTcbUpToDate(true); vm.stopPrank(); + string[] memory advisoryIds = new string[](1); + advisoryIds[0] = "INTEL-SA-00614"; + IAppAuth.AppBootInfo memory bootInfo = IAppAuth.AppBootInfo({ appId: address(app), composeHash: composeHash, @@ -277,10 +279,17 @@ contract DstackAppTest is Test { mrSystem: bytes32(0), osImageHash: bytes32(0), tcbStatus: "OutOfDate", - advisoryIds: new string[](0) + advisoryIds: advisoryIds }); + // Legacy 5-arg init skips the TCB check (specification.md ยง3.4). This deliberately + // diverges from auth-simple's strict default; see auth-simple/index.test.ts. (bool allowed, string memory reason) = app.isAppAllowed(bootInfo); + assertTrue(allowed); + + vm.prank(owner); + app.setRequireTcbUpToDate(true); + (allowed, reason) = app.isAppAllowed(bootInfo); assertFalse(allowed); assertEq(reason, "TCB status is not up to date"); diff --git a/dstack/kms/auth-simple/index.test.ts b/dstack/kms/auth-simple/index.test.ts index 32ad06772..9794091e1 100644 --- a/dstack/kms/auth-simple/index.test.ts +++ b/dstack/kms/auth-simple/index.test.ts @@ -374,6 +374,30 @@ describe('auth-simple', () => { expect(json.isAllowed).toBe(true); }); + + // Stricter than a legacy DstackApp by design; see DstackApp.t.sol + // test_IsAppAllowed_RejectsOutdatedTcbWhenRequired. + it('rejects app boot with out-of-date TCB or unallowlisted advisory ID', async () => { + writeTestConfig({ + gatewayAppId: '0xgateway', + osImages: [baseBootInfo.osImageHash], + apps: { '0xapp123': { composeHashes: ['0xcompose456'], allowAnyDevice: true } } + }); + + for (const [patch, reason] of [ + [{ tcbStatus: 'OutOfDate' }, 'TCB status is not allowed'], + [{ advisoryIds: ['INTEL-SA-00614'] }, 'advisory ID is not allowed'], + ] as const) { + const res = await app.fetch(new Request('http://localhost/bootAuth/app', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...baseBootInfo, ...patch }) + })); + const json = await res.json(); + expect(json.isAllowed).toBe(false); + expect(json.reason).toBe(reason); + } + }); }); describe('hex normalization', () => {