Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions dstack/kms/auth-simple/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ raw NitroTPM evidence by itself.
| `allowedTcbStatuses` | No | Allowed verifier-derived TCB status strings. Defaults to `["UpToDate"]`; non-up-to-date SNP/TDX statuses remain fail-closed unless explicitly allowlisted for testing. |
| `allowedAdvisoryIds` | No | Advisory IDs permitted in `advisoryIds`. Defaults to `[]`, which rejects any advisory. |
| `kms.mrAggregated` | Yes | Allowed KMS early aggregate MR values (boot-mr-done). |
| `kms.devices` | No | Allowed KMS device IDs |
| `kms.devices` | No | Allowed KMS device IDs. Empty denies all unless `kms.allowAnyDevice` is true. |
| `kms.allowAnyDevice` | No | If true, skip device ID check for KMS |
| `apps.<appId>.composeHashes` | No | Allowed compose hashes for this app |
| `apps.<appId>.devices` | No | Allowed device IDs for this app |
| `apps.<appId>.devices` | No | Allowed device IDs for this app. Empty denies all unless `allowAnyDevice` is true. |
| `apps.<appId>.allowAnyDevice` | No | If true, skip device ID check for this app |

For experimental AMD SEV-SNP dry-run authorization, keep the default fail-closed TCB policy unless you intentionally want the auth webhook to accept non-up-to-date verifier-derived SNP `BootInfo`. To exercise the dry-run path without enabling key release, allowlist the recomputed SNP `mrAggregated`, `osImageHash`, app/compose identity, device/chip identity, and any non-default `allowedTcbStatuses`/`allowedAdvisoryIds` values explicitly. KMS still rejects SNP before returning app keys, KMS keys, or app certificates.
Expand Down
46 changes: 46 additions & 0 deletions dstack/kms/auth-simple/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ describe('auth-simple', () => {
expect(json.isAllowed).toBe(false);
expect(json.reason).toContain('MR');
});
it('rejects KMS boot with an empty device allowlist', async () => {
writeTestConfig({
gatewayAppId: '0xgateway',
osImages: ['0x1fbb0cf9cc6cfbf23d6b779776fabad2c5403d643badb9e5e238615e4960a78a'],
kms: {
mrAggregated: ['0xabc123'],
devices: [],
allowAnyDevice: false
}
});

const res = await app.fetch(new Request('http://localhost/bootAuth/kms', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(baseBootInfo)
}));
const json = await res.json();

expect(json.isAllowed).toBe(false);
expect(json.reason).toContain('device');
});

it('allows KMS boot with allowAnyDevice', async () => {
writeTestConfig({
gatewayAppId: '0xgateway',
Expand Down Expand Up @@ -352,6 +374,30 @@ describe('auth-simple', () => {
expect(json.reason).toContain('device');
});

it('rejects app boot with an empty device allowlist', async () => {
writeTestConfig({
gatewayAppId: '0xgateway',
osImages: ['0x1fbb0cf9cc6cfbf23d6b779776fabad2c5403d643badb9e5e238615e4960a78a'],
apps: {
'0xapp123': {
composeHashes: ['0xcompose456'],
devices: [],
allowAnyDevice: false
}
}
});

const res = await app.fetch(new Request('http://localhost/bootAuth/app', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(baseBootInfo)
}));
const json = await res.json();

expect(json.isAllowed).toBe(false);
expect(json.reason).toContain('device');
});

it('allows app boot with allowAnyDevice', async () => {
writeTestConfig({
gatewayAppId: '0xgateway',
Expand Down
4 changes: 2 additions & 2 deletions dstack/kms/auth-simple/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class ConfigBackend {
// check device ID
if (!config.kms.allowAnyDevice) {
const allowedDevices = config.kms.devices.map(normalizeHex);
if (allowedDevices.length > 0 && !allowedDevices.includes(deviceId)) {
if (!allowedDevices.includes(deviceId)) {
return {
isAllowed: false,
reason: 'KMS is not allowed to boot on this device',
Expand Down Expand Up @@ -195,7 +195,7 @@ class ConfigBackend {
// check device ID
if (!appConfig.allowAnyDevice) {
const allowedDevices = appConfig.devices.map(normalizeHex);
if (allowedDevices.length > 0 && !allowedDevices.includes(deviceId)) {
if (!allowedDevices.includes(deviceId)) {
return {
isAllowed: false,
reason: 'app is not allowed to boot on this device',
Expand Down
Loading