.github/skills/policy-authoring/SKILL.md
Conventions and patterns for creating policy authoring types in the Azure API Management policy toolkit. Use this skill when creating or modifying config records in src/Authoring/Configs/ or adding methods to section context interfaces.
npx skillsauth add azure/azure-api-management-policy-toolkit policy-authoringInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill describes how to create authoring types (config records and context interface methods) for policies in the Azure API Management policy toolkit.
src/Authoring/Configs/{PolicyName}Config.cs// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.Azure.ApiManagement.PolicyToolkit.Authoring;
/// <summary>
/// Configuration for the {xml-element-name} policy.<br/>
/// {Brief description of what the policy does.}
/// </summary>
public record {PolicyName}Config
{
/// <summary>
/// {Property description}. Policy expressions are allowed.
/// </summary>
[ExpressionAllowed]
public required {Type} {PropertyName} { get; init; }
/// <summary>
/// Optional. {Property description}.
/// </summary>
public {Type}? {OptionalPropertyName} { get; init; }
}
[Document] (src/Authoring/Attributes/DocumentAttribute.cs) — Marks a class as a policy document. Optional name parameter; Scope and Type properties control document scope and type.[Expression] (src/Authoring/Attributes/ExpressionAttribute.cs) — Marks a method as a policy expression (captures source file path via [CallerFilePath]). Used by the compiler to identify expression helper methods.[ExpressionAllowed] (src/Authoring/Attributes/ExpressionAllowedAttribute.cs) — Marks config properties or parameters that accept policy expressions.required keyword + init setter.?) + init setter. Do not use required.[ExpressionAllowed] attribute. Add "Policy expressions are allowed." to the XML doc.enum type (preferred for fixed, type-safe values)string property with XML doc listing allowed values (for values documented outside code)public record types in the same file.ApiRateLimit, AddressRange, MatchCondition), not generic names like Item or Element./// <summary> XML documentation covering:
Simple attributes with expression support — RateLimitByKeyConfig.cs:
public record RateLimitByKeyConfig
{
[ExpressionAllowed]
public required int Calls { get; init; }
[ExpressionAllowed]
public required int RenewalPeriod { get; init; }
[ExpressionAllowed]
public required string CounterKey { get; init; }
[ExpressionAllowed]
public bool? IncrementCondition { get; init; }
public string? RetryAfterHeaderName { get; init; }
}
Nested sub-records — RateLimitConfig.cs:
public record RateLimitConfig
{
public required int Calls { get; init; }
public required int RenewalPeriod { get; init; }
public string? RetryAfterHeaderName { get; init; }
public ApiRateLimit[]? Apis { get; init; }
}
public record ApiRateLimit : EntityLimitConfig
{
public OperationRateLimit[]? Operations { get; init; }
}
public abstract record EntityLimitConfig
{
public string? Name { get; init; }
public string? Id { get; init; }
public required int Calls { get; init; }
public required int RenewalPeriod { get; init; }
}
Typed child arrays — IpFilterConfig.cs:
public record IpFilterConfig
{
/// <summary>
/// The action to apply: 'allow' or 'deny'. Policy expressions are allowed.
/// </summary>
[ExpressionAllowed]
public required string Action { get; init; }
/// <summary>
/// Optional. IP addresses. Policy expressions are allowed.
/// </summary>
[ExpressionAllowed]
public string[]? Addresses { get; init; }
/// <summary>
/// Optional. IP address ranges.
/// </summary>
public AddressRange[]? AddressRanges { get; init; }
}
/// <summary>
/// An IP address range with 'from' and 'to' octets.
/// </summary>
public record AddressRange
{
/// <summary>
/// The starting IP address. Policy expressions are allowed.
/// </summary>
[ExpressionAllowed]
public required string From { get; init; }
/// <summary>
/// The ending IP address. Policy expressions are allowed.
/// </summary>
[ExpressionAllowed]
public required string To { get; init; }
}
Constrained values with enum — AdvancedPolicyConfig.cs (example pattern):
/// <summary>
/// The caching behavior for the policy action.
/// </summary>
public enum CachingBehavior
{
/// <summary>Cache the response.</summary>
Store,
/// <summary>Reuse a cached response if available.</summary>
Validate,
/// <summary>Bypass cache entirely.</summary>
Bypass
}
public record AdvancedPolicyConfig
{
/// <summary>
/// Required. The caching behavior: 'Store', 'Validate', or 'Bypass'.
/// </summary>
public required CachingBehavior Behavior { get; init; }
}
Add method signatures to the appropriate section interfaces. Policies may appear in one or more sections:
src/Authoring/IInboundContext.cssrc/Authoring/IOutboundContext.cssrc/Authoring/IBackendContext.cssrc/Authoring/IOnErrorContext.cssrc/Authoring/IFragmentContext.cs/// <summary>
/// {Description of the policy behavior}.<br/>
/// Compiled to <a href="{documentation-url}">{xml-element-name}</a> policy.
/// </summary>
/// <param name="config">
/// Configuration for the {xml-element-name} policy.
/// </param>
void {MethodName}({PolicyName}Config config);
Config suffix (e.g., RateLimit for RateLimitConfig).IHaveExpressionContext, giving access to ExpressionContext.[ExpressionAllowed] on the parameter itself.void SetMethod(string method)). Use this pattern only for policies with 1–2 simple parameters and no optional fields.IFragmentContext DuplicationIFragmentContext currently duplicates method signatures from the section-specific interfaces (see the //TODO comment at the top of the file). Every time you add a policy method to any section interface, you must also add the same signature to IFragmentContext.cs. Copy the exact same method signature verbatim. Do not attempt to refactor this pattern.
tools
Conventions and patterns for writing policy compilation tests in the Azure API Management policy toolkit. Use this skill when creating or modifying test files in test/Test.Core/Compiling/.
tools
Conventions and patterns for creating gateway emulator policy handlers in the Azure API Management policy toolkit. Use this skill when creating or modifying handler classes in src/Testing/Emulator/Policies/.
tools
Conventions and patterns for writing gateway emulator policy handler tests in the Azure API Management policy toolkit. Use this skill when creating or modifying test files in test/Test.Testing/Emulator/Policies/.
tools
Conventions and patterns for creating policy compilers in the Azure API Management policy toolkit. Use this skill when creating or modifying compiler classes in src/Core/Compiling/Policy/.