ARM RPC Guidelines and TypeSpec Linting Coverage
Introduction
Section titled βIntroductionβAzure Resource Manager (ARM) defines a set of Resource Provider Contract (RPC) guidelines that all ARM resource providers must follow. TypeSpec encodes many of these guidelines into linting rules that run during compilation, helping service authors catch violations early.
This page maps each RPC guideline to the TypeSpec linting rules that cover or partially cover it, identifies gaps, and categorizes uncovered guidelines. Where TypeSpec linting cannot enforce a guideline β whether due to infrastructure, runtime, or design concerns β service owners are responsible for verifying compliance through other means such as runtime tests, design reviews, or manual validation.
Coverage Legend
Section titled βCoverage Legendβ| Symbol | Meaning |
|---|---|
| β | Fully covered by TypeSpec linting rule or ARM TypeSpec templates |
| πΆ | Partially covered β some aspects checked, service owners must verify the rest |
| β | No linting coverage |
| π§ | Enforced by TypeSpec ARM templates/patterns rather than a linting rule |
| ποΈ | Internal ARM infrastructure concern β not in the customer-facing API description |
| π | Service runtime behavior β must be verified through runtime testing |
| π | Design guidance β requires human judgment, must be verified through design reviews |
| π£ | New linting rule needed β a TypeSpec linting rule could be added to improve or complete coverage |
RPC Rules Coverage by Rule Number
Section titled βRPC Rules Coverage by Rule NumberβThe following table lists each ARM RPC rule by its rule number and maps it to the TypeSpec linting rules that provide coverage. For πΆ partially covered rules, the Notes column describes what is and is not covered, and service owners are responsible for verifying the uncovered aspects β specific suggestions are provided where possible.
| RPC Rule | Description | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| RPC003 | Tracked resource types must support move | β ποΈ | β | Resource move is configured in the ARM manifest, not in the TypeSpec API specification. Service owners must configure resource move support in the ARM manifest. |
| RPC004 | URI must follow ARM standard guidelines (well-formed GET/PUT/DELETE URI tuples) | π§ | arm/arm-resource-path-segment-invalid-chars, arm/arm-resource-key-invalid-chars | Enforced by TypeSpec ARM resource templates (TrackedResource, ProxyResource) which generate correct URI structures. Path character rules provide additional validation. |
| RPC005 | Provisioning state semantics must be followed (terminal/non-terminal states) | πΆ π | arm/arm-resource-provisioning-state | The rule checks that provisioningState is an open union containing the correct terminal states (Succeeded, Failed, Canceled). Runtime behavior (transitioning states on PUT/PATCH/DELETE) cannot be linted. Service owners must verify correct provisioning state transitions through integration tests covering resource lifecycle (create, update, delete). |
| RPC006 | Tracked resource types must support GET, PUT, PATCH, DELETE & LIST | πΆ π£ | arm/arm-resource-operation, arm/no-resource-delete-operation | arm-resource-operation validates operations have correct decorators. no-resource-delete-operation checks resources with createOrUpdate also have delete. Gap: No single rule validates the complete set of required operations (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources β a linting rule could and should be added. Service owners should verify the complete operation set through API design review until such a rule exists. |
| RPC007 | Resource types must support PATCH for Tags | β | arm/arm-resource-patch, arm/patch-envelope | arm-resource-patch checks that if a resource has tags, PATCH includes it. patch-envelope validates PATCH includes envelope properties (identity, managedBy, plan, sku, tags). |
| RPC008 | PUT, GET, PATCH & LIST must return the same resource schema | β | arm/arm-resource-operation-response | Directly implements RPC 008 β validates that PUT, GET, PATCH, and LIST operations all return the same resource schema. |
| RPC009 | Use PUT for replace, PATCH for partial update (JSON merge-patch) | π§ | β | Enforced by ARM TypeSpec operation templates: ResourceCreateOrUpdate for PUT and ResourceUpdate for PATCH generate the correct patterns. |
| RPC010 | Use PUT or PATCH to update a resource, not POST | β π π£ | β | No rule prevents using POST for what should be a resource update. arm/arm-resource-invalid-action-verb ensures actions use POST/GET verbs but does not check intent. Service owners must verify through API design review that POST is not used for operations that semantically perform a full resource update. |
| RPC011.a | PUT on parent must not implicitly create tracked child resources | β π π£ | β | No rule detects implicit child resource creation in PUT request bodies. Service owners must review PUT request schemas during API design review to ensure tracked child resources are not implicitly created. |
| RPC011.b | PUT on parent should avoid implicitly creating proxy child resources | β π π£ | β | Same gap as RPC011.a. This rule is still being refined. Service owners should review PUT request schemas for implicit proxy child creation. |
| RPC012 | Secret property semantics (no secrets in GET/PUT/PATCH responses, use POST list* action) | πΆ π π | arm/secret-prop | Checks properties with sensitive names (password, key, token, etc.) are marked @secret. Service owners must additionally verify that: (1) secrets are omitted from GET/PUT/PATCH responses (runtime integration tests), and (2) secret retrieval is only via POST list* actions (API design review). |
| RPC013 | Resource must define a property bag; should include provisioningState | β | arm/arm-resource-provisioning-state, arm/arm-resource-invalid-envelope-property | arm-resource-provisioning-state checks for a properly configured provisioningState. arm-resource-invalid-envelope-property ensures RP-specific properties are inside the properties bag. ARM base types enforce the property bag structure. |
| RPC014 | POST action must operate on single resource | πΆ π | arm/arm-resource-invalid-action-verb | Validates that actions use POST or GET verbs. Service owners must verify through API design review that POST actions target individual resource instances, not collections. |
| RPC015 | PUT APIs that only return 200 (should also support 201/202 for creation) | β | arm/arm-put-operation-response-codes | Validates that PUT operations have the appropriate status codes including 201 for creation. |
| RPC016 | Responses must include id, name, type; RP content inside properties | β | arm/arm-resource-invalid-envelope-property, arm/arm-resource-operation-response | arm-resource-invalid-envelope-property validates envelope properties come from Azure.ResourceManager namespace. ARM base types enforce id, name, type. arm-resource-operation-response ensures consistent schema across operations. |
| RPC019 | No resources of other types in response (RBAC violation / info leak) | β π π£ | β | No rule detects when a response includes full content of resources of different types. Service owners must review response schemas during API design review to ensure responses do not embed full representations of other resource types, which could create RBAC bypass or information leakage. Related to ARG001. |
| RPC020 | Circular dependencies between resources (read-only back-references) | β π | β | No rule detects writable circular references between resources. Service owners must review resource relationships during API design review to ensure circular dependencies use readOnly back-references, so ARM template dependency ordering can be resolved. |
| RPC021 | operationResults must be a top-level resource type | β ποΈ | β | /operationResults API placement is an ARM platform pattern, not described in TypeSpec resource provider specs. Service owners must configure this through the ARM platform. |
| RPC022 | Identifiers for operationResults must be unique (use GUIDs, not hashes) | β ποΈ | β | Identifier generation strategy is a runtime implementation concern internal to ARM. Service owners must ensure their implementation uses GUIDs for operation result identifiers. |
| RPC023 | DELETE should always be honored (never reject DELETE on bad state) | β π | β | Whether DELETE is accepted regardless of resource state is a runtime implementation concern. Service owners must verify through runtime tests that DELETE is never rejected due to resource state. |
| RPC024 | Prefer header-based async timeout over manifest-based | β ποΈ | β | Async timeout configuration is in the ARM manifest, not in the TypeSpec API specification. Service owners must configure this in the ARM manifest. |
| RPC025 | 201 is the recommended async pattern (201 + provisioningState + Azure-AsyncOperation) | πΆ π | arm/arm-put-operation-response-codes, arm/lro-location-header, arm/retry-after | PUT response codes, LRO Location header, and Retry-After are checked. Service owners must verify through integration tests that their preferred async pattern follows the 201 + provisioningState + Azure-AsyncOperation recommendation, as no rule specifically enforces this preference over alternatives. |
| RPC026 | Resource provider must implement subscription lifecycle contract | β ποΈ | β | Subscription lifecycle (register/unregister) is an internal ARM contract, not part of the customer-facing TypeSpec spec. POST /register in operations API is covered by arm/missing-operations-endpoint. Service owners must implement the subscription lifecycle contract as specified by the ARM platform. |
| RPC027 | SystemData support (createdBy, createdAt, etc.) | π§ | β | Enforced by ARM TypeSpec base types β TrackedResource and ProxyResource automatically include systemData in the resource model. |
| RPC028 | Async operation tracking URI must follow ARM guidelines | πΆ π | arm/lro-location-header | Validates 202 responses include a Location header. Service owners must verify through integration tests that the Location URI format follows ARM guidelines and points to the ARM front door, as the specific URI format is not validated. |
| RPC029 | FQDNs must use auto-generated domain name labels (prevent subdomain takeover) | β π | β | Domain label generation strategy is a runtime implementation concern. Service owners must verify through runtime testing that FQDNs use the AzureDNS Deterministic Names library to prevent subdomain takeover. |
| RPC030 | Avoid excessive resource type nesting (max 3 levels for tracked) | β | arm/beyond-nesting-levels | Ensures tracked resources use 3 or fewer levels of nesting. |
| RPC031 | Unsupported query parameters (sub, subId, subscription, subscriptionId) | β ποΈ | β | ARM proxy behavior for query parameters is handled by the ARM platform. Service owners do not need to take action β this is enforced by the ARM front door. |
RPC Rules Coverage Summary
Section titled βRPC Rules Coverage Summaryβ| Coverage Level | Count | Rules |
|---|---|---|
| β Fully covered or enforced by templates | 12 | RPC004, RPC007, RPC008, RPC009, RPC013, RPC015, RPC016, RPC027, RPC030 (linting); RPC004, RPC009, RPC027 (templates) |
| πΆ Partially covered | 6 | RPC005 (π), RPC006 (π£), RPC012 (π π), RPC014 (π), RPC025 (π), RPC028 (π) |
| β ποΈ Not lintable β internal ARM infrastructure | 6 | RPC003, RPC021, RPC022, RPC024, RPC026, RPC031 |
| β π Not lintable β service runtime behavior | 2 | RPC023, RPC029 |
| β π Not lintable β design guidance | 5 | RPC010 (π£), RPC011.a (π£), RPC011.b (π£), RPC019 (π£), RPC020 |
Detailed Coverage by Topic
Section titled βDetailed Coverage by TopicβThe following sections provide a more detailed breakdown of coverage organized by topic area, with links to specific rule documentation.
Section 1: ARM Resource Path Structure
Section titled βSection 1: ARM Resource Path Structureβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 1.1 Tracked resource paths under subscription/RG | RPC-Put-V1-01, RPC-Get-V1-11 | π§ | β | Enforced by TrackedResource base type, which generates correct path structure automatically. |
| 1.2 Proxy resource paths | β | π§ | β | Enforced by ProxyResource base type. |
| 1.3 Resource provider namespace consistency | RPC-Put-V1-06 | π§ | β | Enforced by @armProviderNamespace decorator which sets the namespace in paths. |
| 1.4 Operations API endpoint required | RPC-Operations-V1 | β | arm/missing-operations-endpoint | Checks that every ARM namespace includes an Operations interface. |
Section 2: ARM Resource Model Rules
Section titled βSection 2: ARM Resource Model Rulesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 2.1 PUT response must be an ARM Resource | RPC-Put-V1-12 | β | arm/arm-resource-operation-response, arm/arm-put-operation-response-codes | RPC 008 validates PUT/GET/PATCH/LIST return the same resource schema. PUT response codes are also validated. ARM base types ensure x-ms-azure-resource is set. |
| 2.2 Tracked resources must have all required operations | RPC-Get-V1-01, RPC-Put-V1-01, RPC-Patch-V1-03, RPC-Delete-V1-01 | πΆ π£ | arm/arm-resource-operation, arm/no-resource-delete-operation | arm-resource-operation validates operations have correct decorators. no-resource-delete-operation checks that resources with createOrUpdate also have delete. Gap: No single rule validates the complete operation set (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources β a linting rule could and should be added. Service owners should verify the complete operation set through API design review until such a rule exists. |
| 2.3 Nested resources must have List under parent | β | β π£ | β | Gap: No rule validates that nested resources define a List operation under their parent β a linting rule could and should be added. Service owners must verify this during API design review until such a rule exists. |
| 2.3 Nesting depth limit | β | β | arm/beyond-nesting-levels | Ensures tracked resources use 3 or fewer nesting levels. |
| 2.3 No embedded nested resources in parent GET | ARG001 | β π | β | No rule prevents embedding child resources inline in parent GET response. Service owners must verify during API design review that parent GET responses do not embed full child resources. See also Section 10.1. |
| 2.4 Resource references use fully qualified ARM resource IDs | β | π§ π | β | TypeSpec provides the armResourceIdentifier scalar in Azure.Core for this purpose, which enforces the arm-id format and allows specifying allowed resource types and scopes. However, no linting rule can reliably detect that a plain string property is intended to hold a resource reference β that requires domain knowledge. Service owners must use armResourceIdentifier for properties that reference other ARM resources and verify this through API design review. See ARM Resource Types. |
Section 3: PUT Operation Rules
Section titled βSection 3: PUT Operation Rulesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 3.1 Resources must expose PUT for creation | β | π§ | β | Enforced by ARM TypeSpec operation templates (ResourceCreateOrUpdate). |
| 3.1 PUT must be idempotent | β | β π | β | Service runtime behavior β cannot be validated through API specification. Service owners must verify PUT idempotency through integration tests that repeat PUT requests and confirm no side effects. |
| 3.2 PUT must not expose secrets in response | β | πΆ π | arm/secret-prop | Checks that properties with sensitive names are marked @secret. Service owners must additionally verify that secrets are omitted from PUT responses through response payload inspection in integration tests. |
Section 4: PATCH Operation Rules
Section titled βSection 4: PATCH Operation Rulesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 4.1 PATCH body must not have required properties | RPC-Patch-V1-10 | β | arm/arm-resource-patch | Validates PATCH request body model properties. ARM TypeSpec templates automatically generate separate update models. |
| 4.2 Tracked resource PATCH must support tags | RPC-Patch-V1-03 | β | arm/arm-resource-patch, arm/patch-envelope | arm-resource-patch checks tags are included. patch-envelope validates envelope properties (identity, managedBy, plan, sku, tags) match the resource. |
| 4.2 Resources should have updateable properties | β | β | arm/empty-updateable-properties | Checks that resources with update operations have at least one updateable property. |
| 4.3 PATCH must not expose secrets in response | β | πΆ π π | arm/secret-prop | Checks sensitive property names are marked @secret. Service owners must additionally verify through API design review that secret properties are correctly identified, and through integration tests that secrets are omitted from PATCH responses. |
Section 5: DELETE Operation Rules
Section titled βSection 5: DELETE Operation Rulesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 5.1 DELETE response codes (200, 204, default; 202 for async) | RPC-Delete-V1-01, RPC-Async-V1-09 | β | arm/arm-delete-operation-response-codes | Validates correct status codes for both sync and async DELETE operations. |
| 5.2 DELETE must not have a request body | β | π§ | β | Enforced by ARM TypeSpec operation templates which do not include a body parameter for DELETE. |
Section 6: Long-Running Operations (LRO)
Section titled βSection 6: Long-Running Operations (LRO)β| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 6.1 LRO 202 must include Location or Azure-AsyncOperation header | RPC-Async-V1 | β | arm/lro-location-header | Validates 202 responses include a Location header. |
| 6.1 LRO 200/201 response must have a schema | RPC-Async-V1 | β | arm/no-response-body | Checks that non-204 success responses have a body and 202/204 responses do not. |
| 6.1 LRO Retry-After header | β | β | arm/retry-after | Checks that LRO responses (201/202) include a Retry-After header. |
| 6.2 Operation results as root-level resources | β | β ποΈ | β | Internal ARM infrastructure concern β /operationResults placement is an ARM platform pattern, not described in TypeSpec specs. Service owners must configure this through the ARM platform. |
Section 7: Secret Handling & Sensitive Data
Section titled βSection 7: Secret Handling & Sensitive Dataβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 7.1 No secrets in GET/PUT/PATCH responses | β | πΆ π π | arm/secret-prop | Validates that properties with sensitive names are marked @secret. The @secret decorator drives correct code generation, but the rule does not verify secrets are omitted from specific response types. Service owners must verify through API design review that all sensitive properties are identified, and through integration tests that secrets are excluded from GET/PUT/PATCH responses. |
7.1 Secret retrieval via POST list* action | β | β π | β | No rule validates that secrets are exposed only via POST list* actions for granular RBAC control. Service owners must verify this design pattern through API design review. |
7.2 x-ms-secret annotation | RPC-v1-13 | β | arm/secret-prop | Checks that sensitive properties are annotated with @secret, which generates x-ms-secret: true. |
Section 8: Property Design Best Practices
Section titled βSection 8: Property Design Best Practicesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 8.1 Prefer enums over booleans | β | β π | β | Design guidance requiring human judgment. Booleans are sometimes appropriate. Service owners must evaluate during API design review. |
| 8.2 Use objects instead of strings for structured values | β | β π | β | Design guidance requiring human judgment. Service owners must evaluate during API design review. |
| 8.3 Use enums for finite value sets | β | πΆ π | core/no-enum | Azure Core recommends extensible unions over enums, which aligns with ARMβs preference for extensible types. Service owners should verify through API design review that free-form strings that should be constrained are modeled as extensible unions. |
| 8.4 Visibility and mutability | β | πΆ π | core/key-visibility-required | Checks key properties have visibility settings. Service owners must verify through API design review that create-only, read-only, and other mutability constraints are properly annotated on all properties. |
| 8.5 Avoid writable circular dependencies | β | β π | β | No rule detects writable circular references between resources. Service owners must review resource dependency graphs during API design review to ensure circular dependencies use readOnly back-references for correct ARM template dependency ordering. |
Section 9: Inline Properties vs. Nested Resources
Section titled βSection 9: Inline Properties vs. Nested Resourcesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 9.1β9.2 When to use inline vs. nested resources | β | β π | β | Design guidance requiring human judgment based on lifecycle, RBAC, and collection size. Service owners must make this decision during API design review. |
| 9.3 Never model both inline and nested | β | β π | β | No rule detects when a collection is modeled as both an inline array property and a nested resource type. Service owners must verify during API design review that each entity is modeled exclusively as either inline or nested. |
Section 10: Azure Resource Graph (ARG) Compatibility
Section titled βSection 10: Azure Resource Graph (ARG) Compatibilityβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 10.1 No embedded child resources in parent GET (ARG001) | ARG001 | β π | β | No rule prevents embedding child resources or child counts in parent resource GET responses. Service owners must verify during API design review that parent GET responses do not include full child resource representations. |
| 10.2 No customer data in control plane properties (ARG002) | ARG002 | β π | β | Data classification concern β cannot be reliably detected through API specification linting. Service owners must verify through data classification review that control plane properties do not contain customer data. |
| 10.3 Do not remove properties between API versions (ARG003) | ARG003 | πΆ | core/non-breaking-versioning | Checks for backward compatible versioning changes. Service owners should additionally verify through API version comparison testing that no properties are removed between versions, as the rule may not catch all scenarios. |
Section 11: API Version Practices
Section titled βSection 11: API Version Practicesβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 11.1 Uniform versioning within a service | β | π§ | β | Enforced by TypeSpec versioning model β all resource types in a namespace share the same version enum. |
| 11.2 Incremental version progression | β | β π£ | β | Gap: GA versions must have a later date than preview. Since versions are represented as an enum type in TypeSpec, a linting rule could detect incorrect versioning patterns. Service owners must verify version progression through their release process and CI/CD pipeline checks until such a rule exists. |
| API version parameter required | β | β | core/operation-missing-api-version, arm/arm-resource-operation | Both rules validate operations include an api-version parameter. |
| Version format validation | β | β | arm/arm-resource-invalid-version-format | Checks that version strings use valid ARM version formats. |
Section 12: POST Actions
Section titled βSection 12: POST Actionsβ| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes |
|---|---|---|---|---|
| 12.1 POST actions must use POST or GET verbs | β | β | arm/arm-resource-invalid-action-verb | Validates that action operations use only POST or GET HTTP verbs. |
| 12.1 POST response codes | β | β | arm/arm-post-operation-response-codes | Validates correct status codes for POST operations. |
| 12.2 POST to create resources | β | β π | β | POST creation is not allowed for ARM services. This constraint is not detectable by examining the API description alone. Service owners must verify through API design review that POST is not used for resource creation in ARM resource provider APIs. |
Additional ARM TypeSpec Rules
Section titled βAdditional ARM TypeSpec RulesβThe following TypeSpec linting rules enforce ARM conventions that are not explicitly called out as individual RPC guidelines but support overall ARM compliance:
| TypeSpec Rule | Description |
|---|---|
arm/arm-common-types-version | Requires specifying the ARM common-types version using @armCommonTypesVersion. |
arm/arm-no-record | Prevents use of Record types for ARM resources, which produce additionalProperties in OpenAPI. |
arm/arm-resource-duplicate-property | Warns about duplicate properties in resource definitions. |
arm/arm-resource-interface-requires-decorator | Requires @armResourceOperations decorator on resource interfaces. |
arm/arm-resource-name-pattern | Requires a pattern restriction on resource name parameters. |
arm/improper-subscription-list-operation | Ensures tenant and extension resources donβt define list-by-subscription operations. |
arm/missing-x-ms-identifiers | Requires array properties to describe identifying properties with x-ms-identifiers. |
arm/no-empty-model | Prevents ARM properties with type: object that donβt reference a model definition. |
arm/unsupported-type | Checks for unsupported ARM types. |
Rules Not Enforceable Through Linting β Service Owner Responsibility
Section titled βRules Not Enforceable Through Linting β Service Owner ResponsibilityβThe following RPC rules cannot be validated through API specification linting. Service owners are responsible for verifying compliance through the mechanisms described below.
β ποΈ Internal ARM Infrastructure
Section titled ββ ποΈ Internal ARM InfrastructureβThese rules describe internal ARM platform concerns that are configured through the ARM manifest or other ARM platform mechanisms, not through the TypeSpec API specification.
| RPC Rule | Description | How to Verify |
|---|---|---|
| RPC003 | Tracked resource types must support move | Configure resource move support in the ARM manifest. |
| RPC021 | operationResults must be a top-level resource type | Configure through the ARM platform. |
| RPC022 | Identifiers for operationResults must be unique (use GUIDs) | Verify in service implementation that operation result identifiers use GUIDs. |
| RPC024 | Prefer header-based async timeout over manifest-based | Configure in the ARM manifest. |
| RPC026 | Resource provider must implement subscription lifecycle contract | Implement the subscription lifecycle contract as specified by the ARM platform. |
| RPC031 | Unsupported query parameters | Enforced by the ARM front door β no service action required. |
β π Service Runtime Behavior
Section titled ββ π Service Runtime BehaviorβThese rules describe runtime behavior that can only be validated through testing, not through API specification.
| RPC Rule | Description | How to Verify |
|---|---|---|
| RPC005 (runtime aspects) | Provisioning state transitions on PUT/PATCH/DELETE | Integration tests covering resource lifecycle (create, update, delete) and validating terminal states (Succeeded, Failed, Canceled). |
| RPC023 | DELETE should always be honored (never reject on bad state) | Runtime tests confirming DELETE is accepted regardless of resource state. |
| RPC029 | FQDNs must use auto-generated domain name labels | Runtime tests verifying FQDNs use the AzureDNS Deterministic Names library to prevent subdomain takeover. |
| 3.1 | PUT must be idempotent | Integration tests repeating PUT requests and confirming no side effects. |
| 10.2 (ARG002) | No customer data in control plane properties | Data classification review of control plane properties. |
β π Design Guidance Requiring Human Judgment
Section titled ββ π Design Guidance Requiring Human JudgmentβThese rules require domain knowledge or design judgment that automated linting cannot provide. Service owners must verify compliance through API design reviews.
| RPC Rule | Description | What to Look For in Design Review |
|---|---|---|
| RPC010 | Use PUT or PATCH to update a resource, not POST | Verify POST is not used for operations that semantically update a resource. |
| RPC011.a | PUT on parent must not implicitly create tracked child resources | Review PUT request schemas for properties that would create child resources as a side effect. |
| RPC011.b | PUT on parent should avoid implicitly creating proxy child resources | Same as RPC011.a for proxy child resources. |
| RPC019 | No resources of other types in response (RBAC/info leak) | Review response schemas to ensure they do not embed full representations of other resource types. |
| RPC020 | Circular dependencies between resources | Review resource dependency graphs to ensure circular dependencies use readOnly back-references. |
| 2.3 | No embedded nested resources in parent GET | Verify parent GET responses do not embed full child resource representations. |
| 2.4 | Resource references use fully qualified ARM resource IDs | Verify all properties referencing other ARM resources use the armResourceIdentifier scalar. |
| 7.1 | Secret retrieval via POST list* action only | Verify secrets are exposed only via POST list* actions for granular RBAC control. |
| 8.1 | Prefer enums over booleans | Evaluate whether booleans should be replaced with extensible enums. |
| 8.2 | Use objects instead of strings for structured values | Evaluate whether string properties contain structured data that should be modeled as objects. |
| 9.1β9.2 | When to use inline vs. nested resources | Evaluate lifecycle, RBAC, and collection size to choose between inline properties and nested resources. |
| 9.3 | Never model both inline and nested | Verify each entity is modeled exclusively as either inline or nested. |
| 10.1 (ARG001) | No embedded child resources in parent GET | Verify parent GET responses do not include full child resource representations. |
| 12.2 | POST to create resources | POST creation is not allowed for ARM services. Verify POST is not used for resource creation in ARM APIs. Not detectable from API description alone. |
Partially Covered Rules β Service Owner Verification Required
Section titled βPartially Covered Rules β Service Owner Verification RequiredβThe following rules are partially covered by TypeSpec linting, but service owners must verify the uncovered aspects as described below.
| RPC Rule | What Linting Covers | What Service Owners Must Verify |
|---|---|---|
| RPC005 π | arm-resource-provisioning-state checks that provisioningState is an open union containing the correct terminal states (Succeeded, Failed, Canceled). | Correct provisioning state transitions during resource lifecycle (create, update, delete). Verify through integration tests. |
| RPC006 π£ | arm-resource-operation validates operation decorators. no-resource-delete-operation checks delete exists with createOrUpdate. | The complete operation set (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) β this is an actionable gap where a linting rule could be added. Verify through API design review until then. |
| RPC012 π π | secret-prop checks sensitive property names are marked @secret. | (1) Secrets are omitted from GET/PUT/PATCH responses β verify through integration tests inspecting response payloads. (2) Secret retrieval is only via POST list* actions β verify through API design review. |
| RPC014 π | arm-resource-invalid-action-verb validates POST/GET verb usage. | POST actions target individual resource instances, not collections. Verify through API design review. |
| RPC025 π | PUT response codes, LRO Location header, and Retry-After are validated. | The preferred async pattern (201 + provisioningState + Azure-AsyncOperation) is followed. Verify through integration tests. |
| RPC028 π | LRO Location header presence is validated for 202 responses. | The Location URI format follows ARM guidelines and points to the ARM front door. Verify through API design review and integration tests. |
| 7.1 π π | secret-prop validates sensitive property annotations. | All sensitive properties are correctly identified β verify through API design review. Secrets are excluded from GET/PUT/PATCH response payloads β verify through integration tests. |
| 8.3 π | no-enum recommends extensible unions over fixed enums. | Free-form strings that should be constrained are modeled as extensible unions. Verify through API design review. |
| 8.4 π | key-visibility-required checks key property visibility. | Create-only, read-only, and other mutability constraints are properly annotated on all properties. Verify through API design review. |
| 10.3 (ARG003) π π | non-breaking-versioning checks backward compatible versioning. | Breaking changes at the API level can be checked through API description comparison. Runtime breaking changes require runtime testing to detect. |
Actionable Gaps β Where Future Linting Rules Could Help
Section titled βActionable Gaps β Where Future Linting Rules Could HelpβThe following areas are customer-facing API concerns where new TypeSpec linting rules could potentially be added to improve automated coverage. Until such rules are implemented, service owners must verify these through API design reviews.
| Area | RPC Rule(s) | Gap Description | Potential Linting Approach |
|---|---|---|---|
| π£ Complete operation set | RPC006, 2.2 | No single rule validates that tracked resources have all required operations (GET, PUT, PATCH, DELETE, ListByRG, ListBySub). | A rule could check each tracked resource type against the required operation set and report missing operations. |
| π£ Nested resource List | 2.3 | No rule validates that nested/child resources define a List operation scoped to their parent. | A rule could verify each child resource has a List operation at the parent scope. |
| π£ Version progression | 11.2 | No rule validates that GA versions have a later date than preview versions. | Since versions are represented as an enum type in TypeSpec, a rule could check that GA version date strings are chronologically later than their corresponding preview versions. |
| π£ Implicit child creation | RPC011.a, RPC011.b | No rule detects implicit child resource creation in PUT request bodies. | A rule could flag PUT request schemas that contain arrays or properties matching known child resource type shapes. |
| π£ POST vs. PUT/PATCH intent | RPC010 | No rule detects when POST is used for what should be a resource update. | Difficult to automate β would require heuristics on POST operation naming and body schemas. |
| π£ Cross-resource type resp. | RPC019 | No rule detects when a response embeds full content of other resource types. | A rule could flag response models containing properties typed as other ARM resource types. |