UNPKG

@azure-tools/typespec-azure-resource-manager

Version:

TypeSpec Azure Resource Manager library

58 lines 2.6 kB
import { UsageFlags, createAddDecoratorCodeFix, createRule, isSecret, paramMessage, resolveUsages, } from "@typespec/compiler"; import { $ } from "@typespec/compiler/typekit"; function isKeyValuePairKeyProp(property) { return (property.name === "key" && property.model?.properties.has("value") === true && property.model?.properties.size === 2); } export const secretProprule = createRule({ name: "secret-prop", description: `RPC-v1-13: Check that property with names indicating sensitive information(e.g. contains auth, password, token, secret, etc.) are marked with @secret decorator.`, severity: "warning", url: "https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/secret-prop", messages: { default: paramMessage `Property '${"propertyName"}' looks like it contains sensitive information. Consider marking it with @secret decorator to ensure it is handled securely.`, }, create(context) { const usages = resolveUsages(context.program.getGlobalNamespaceType()); return { modelProperty: (property) => { if (!property.model || !usages.isUsedAs(property.model, UsageFlags.Output)) { return; } const tk = $(context.program); if (isPotentialSensitiveProperty(property.name) && !isSecret(context.program, property) && !isSecret(context.program, property.type) && property.type === tk.builtin.string && !isKeyValuePairKeyProp(property)) { context.reportDiagnostic({ target: property, format: { propertyName: property.name, }, codefixes: [createAddDecoratorCodeFix(property, "secret")], }); } }, }; }, }); const sensitiveKeywords = [ "access", "credential", "secret", "password", "key", "token", "auth", "connection", ].map((keyword) => keyword.toUpperCase()); /** Set of keyword that shouldn't be flagged */ const excludeKeywords = ["publicKey"].map((keyword) => keyword.toUpperCase()); function isPotentialSensitiveProperty(propertyName) { const upperName = propertyName.toUpperCase(); return (sensitiveKeywords.some((keyword) => upperName.endsWith(keyword)) && !excludeKeywords.some((keyword) => upperName.endsWith(keyword))); } //# sourceMappingURL=secret-prop.js.map