Skip to content
Open
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
14 changes: 14 additions & 0 deletions .chronus/changes/hide-cmk-internal-2026-6-12-17-1-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
changeKind: feature
packages:
- "@azure-tools/typespec-azure-resource-manager"
---

Hide `CustomerManagedKeyEncryption`, `KeyEncryptionKeyIdentity`, and `KeyEncryptionKeyIdentityType` common types by marking them `internal`. Add public replacement types `CustomerManagedKeyEncryptionV4`, `KeyEncryptionKeyIdentityV4`, and `KeyEncryptionKeyIdentityTypeV4` in the `Azure.ResourceManager.Foundations` namespace.

```tsp
// Use the new Foundations types instead of the internal CommonTypes types:
model EncryptionConfig {
customerManagedKey?: Azure.ResourceManager.Foundations.CustomerManagedKeyEncryptionV4;
}
```
2 changes: 1 addition & 1 deletion .github/workflows/external-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
# Also pack TypeSpec core packages
cd core
pnpm chronus pack --pack-destination ../tgz-packages --exclude standalone
pnpm chronus pack --pack-destination ../tgz-packages --exclude standalone --exclude typespec-vs
cd ..
echo "Created tgz packages:"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ union InfrastructureEncryption {

/** The type of identity to use. */
@added(Versions.v4)
union KeyEncryptionKeyIdentityType {
internal union KeyEncryptionKeyIdentityType {
/** System assigned identity */
SystemAssignedIdentity: "systemAssignedIdentity",

Expand All @@ -32,7 +32,7 @@ union KeyEncryptionKeyIdentityType {

/** All identity configuration for Customer-managed key settings defining which identity should be used to auth to Key Vault. */
@added(Versions.v4)
model KeyEncryptionKeyIdentity {
internal model KeyEncryptionKeyIdentity {
/** The type of identity to use. Values can be systemAssignedIdentity, userAssignedIdentity, or delegatedResourceIdentity. */
identityType?: KeyEncryptionKeyIdentityType;

Expand All @@ -49,7 +49,7 @@ model KeyEncryptionKeyIdentity {

/** Customer-managed key encryption properties for the resource. */
@added(Versions.v4)
model CustomerManagedKeyEncryption {
internal model CustomerManagedKeyEncryption {
/** All identity configuration for Customer-managed key settings defining which identity should be used to auth to Key Vault. */
keyEncryptionKeyIdentity?: KeyEncryptionKeyIdentity;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "@typespec/rest";

import "./backcompat.tsp";
import "./deprecation.tsp";
import "./encryption.tsp";
import "../common-types/common-types.tsp";
import "../decorators.tsp";
import "../responses.tsp";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Azure.Core;

namespace Azure.ResourceManager.Foundations;

/** The type of identity to use. */
union KeyEncryptionKeyIdentityTypeV4 {
/** System assigned identity */
SystemAssignedIdentity: "systemAssignedIdentity",

/** User assigned identity */
UserAssignedIdentity: "userAssignedIdentity",

/** Delegated identity */
DelegatedResourceIdentity: "delegatedResourceIdentity",

string,
}

/** All identity configuration for Customer-managed key settings defining which identity should be used to auth to Key Vault. */
model KeyEncryptionKeyIdentityV4 {
/** The type of identity to use. Values can be systemAssignedIdentity, userAssignedIdentity, or delegatedResourceIdentity. */
identityType?: KeyEncryptionKeyIdentityTypeV4;

/** User assigned identity to use for accessing key encryption key Url. Ex: /subscriptions/fa5fc227-a624-475e-b696-cdd604c735bc/resourceGroups/<resource group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myId. Mutually exclusive with identityType systemAssignedIdentity. */
userAssignedIdentityResourceId?: Azure.Core.armResourceIdentifier;

/** application client identity to use for accessing key encryption key Url in a different tenant. Ex: f83c6b1b-4d34-47e4-bb34-9d83df58b540 */
federatedClientId?: uuid;

/** delegated identity to use for accessing key encryption key Url. Ex: /subscriptions/fa5fc227-a624-475e-b696-cdd604c735bc/resourceGroups/<resource group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myId. Mutually exclusive with identityType systemAssignedIdentity and userAssignedIdentity - internal use only. */
delegatedIdentityClientId?: uuid;
}

/** Customer-managed key encryption properties for the resource. */
model CustomerManagedKeyEncryptionV4 {
/** All identity configuration for Customer-managed key settings defining which identity should be used to auth to Key Vault. */
keyEncryptionKeyIdentity?: KeyEncryptionKeyIdentityV4;

/** key encryption key Url, versioned or non-versioned. Ex: https://contosovault.vault.azure.net/keys/contosokek/562a4bb76b524a1493a6afe8e536ee78 or https://contosovault.vault.azure.net/keys/contosokek. */
keyEncryptionKeyUrl?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Tester } from "#test/tester.js";
import { TesterInstance } from "@typespec/compiler/testing";
import { beforeEach, describe, it } from "vitest";

let runner: TesterInstance;

beforeEach(async () => {
runner = await Tester.createInstance();
});

describe("CustomerManagedKeyEncryptionV4 foundations type", () => {
it("can be used in a service spec as a property type", async () => {
const diagnostics = await runner.diagnose(
`
@armProviderNamespace
@service
namespace Microsoft.Contoso;

model EncryptionConfig {
customerManagedKey?: Azure.ResourceManager.Foundations.CustomerManagedKeyEncryptionV4;
}
`,
);
expectDiagnosticEmpty(diagnostics);
});

it("exposes keyEncryptionKeyIdentity and keyEncryptionKeyUrl properties", async () => {
const diagnostics = await runner.diagnose(
`
@armProviderNamespace
@service
namespace Microsoft.Contoso;

model EncryptionConfig {
customerManagedKey?: Azure.ResourceManager.Foundations.CustomerManagedKeyEncryptionV4;
}

model UsesIdentity {
identity?: Azure.ResourceManager.Foundations.KeyEncryptionKeyIdentityV4;
}
`,
);
expectDiagnosticEmpty(diagnostics);
});

it("KeyEncryptionKeyIdentityTypeV4 union can be referenced", async () => {
const diagnostics = await runner.diagnose(
`
@armProviderNamespace
@service
namespace Microsoft.Contoso;

model IdentityConfig {
identityType?: Azure.ResourceManager.Foundations.KeyEncryptionKeyIdentityTypeV4;
}
`,
);
expectDiagnosticEmpty(diagnostics);
});

it("CustomerManagedKeyEncryption is internal and cannot be used outside Azure.ResourceManager", async () => {
const diagnostics = await runner.diagnose(
`
@armProviderNamespace
@service
namespace Microsoft.Contoso;

model EncryptionConfig {
customerManagedKey?: Azure.ResourceManager.CommonTypes.CustomerManagedKeyEncryption;
}
`,
);
expectDiagnosticNotEmpty(diagnostics);
});

it("Encryption wrapper type remains public and usable", async () => {
const diagnostics = await runner.diagnose(
`
@service(#{ title: "Test" })
@versioned(Microsoft.Contoso.Versions)
@armProviderNamespace
namespace Microsoft.Contoso;

enum Versions {
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v4)
v4;
}

model ResourceProperties {
encryption?: Azure.ResourceManager.CommonTypes.Encryption;
}
`,
);
expectDiagnosticEmpty(diagnostics);
});
});

function expectDiagnosticEmpty(diagnostics: readonly any[]) {
if (diagnostics.length > 0) {
throw new Error(
`Expected no diagnostics but got ${diagnostics.length}: ${diagnostics.map((d) => `${d.code}: ${d.message}`).join(", ")}`,
);
}
}

function expectDiagnosticNotEmpty(diagnostics: readonly any[]) {
if (diagnostics.length === 0) {
throw new Error("Expected diagnostics but got none");
}
}
Loading
Loading