| name | policy-codebase-reference |
| description | Reference guide for the Azure API Management policy toolkit codebase structure. Use this skill when you need to find existing policies, infrastructure, or naming conventions. |
Policy Toolkit Codebase Reference
This skill provides an inventory of the codebase structure, shared infrastructure, reference policy selection, and naming conventions for the Azure API Management policy toolkit.
File Path Conventions
Authoring & Compilation
| Artifact | Location | Example |
|---|
| Config record | src/Authoring/Configs/{PolicyName}Config.cs | RateLimitConfig.cs |
| Document attribute | src/Authoring/Attributes/DocumentAttribute.cs | — |
| Expression attribute | src/Authoring/Attributes/ExpressionAttribute.cs | — |
| Expression-allowed attribute | src/Authoring/Attributes/ExpressionAllowedAttribute.cs | — |
| Section interfaces | src/Authoring/I{Section}Context.cs | IInboundContext.cs |
| Compiler class | src/Core/Compiling/Policy/{PolicyName}Compiler.cs | RateLimitCompiler.cs |
| Compiler test class | test/Test.Core/Compiling/{PolicyName}Tests.cs | RateLimitTests.cs |
| Available policies doc | docs/AvailablePolicies.md | — |
| Compiler utilities | src/Core/Compiling/CompilerUtils.cs | — |
| Syntax extensions | src/Core/Compiling/SyntaxExtensions.cs | — |
| Diagnostics | src/Core/Compiling/Diagnostics/CompilationErrors.cs | — |
| IoC / auto-registration | src/Core/IoC/CompilerModule.cs | — |
| Test initialization | test/Test.Core/CompilerTestInitialize.cs | — |
| Assertion helpers | test/Test.Core/Assertions/ | CompilationResultAssertion.cs |
| Generic compiler utilities | src/Core/Compiling/Policy/GenericCompiler.cs | — |
| Add-policy guide | docs/AddPolicyGuide.md | — |
Gateway Emulator
| Artifact | Location | Example |
|---|
| Emulator handler class | src/Testing/Emulator/Policies/{PolicyName}Handler.cs | SetHeaderHandler.cs |
| Handler base classes | src/Testing/Emulator/Policies/PolicyHandler.cs | — |
| IPolicyHandler interface | src/Testing/Emulator/IPolicyHandler.cs | — |
| Section attribute | src/Testing/Emulator/Policies/SectionAttribute.cs | — |
| Argument extensions | src/Testing/Emulator/Policies/ArgumentsExtensions.cs | — |
| Policy exception | src/Testing/Emulator/PolicyExeption.cs | Note: filename has typo |
| SectionContextProxy | src/Testing/Emulator/SectionContextProxy.cs | — |
| GatewayContext | src/Testing/GatewayContext.cs | — |
| TestDocument | src/Testing/TestDocument.cs | — |
| Emulator test class | test/Test.Testing/Emulator/Policies/{PolicyName}Tests.cs | SetHeaderTests.cs |
| Emulator policy checklist | docs/EmulatorPolicyChecklist.md | — |
Naming Conventions
Authoring & Compilation
| Artifact | Convention | Example |
|---|
| Config record | {PolicyName}Config | RateLimitConfig |
| Sub-config record | {DescriptiveName} | ApiRateLimit, AddressRange |
| Compiler class | {PolicyName}Compiler | RateLimitCompiler |
| Compiler test class | {PolicyName}Tests | RateLimitTests |
| Context method | {PolicyName} | RateLimit |
| XML element name | kebab-case | rate-limit |
| Config namespace | Microsoft.Azure.ApiManagement.PolicyToolkit.Authoring | — |
| Compiler namespace | Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling.Policy | — |
| Compiler test namespace | Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling | — |
Gateway Emulator
| Artifact | Convention | Example |
|---|
| Handler class | {PolicyName}Handler | SetHeaderHandler |
| Emulator test class | {PolicyName}Tests | SetHeaderTests |
| PolicyName property | PascalCase method name from section interface | SetHeader |
| Handler namespace | Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Policies | — |
| Emulator test namespace | Test.Emulator.Emulator.Policies | — |
Note: JsonToXmlHandle.cs is a naming inconsistency in the source (missing the r in Handler). Do not rename it.
Copyright Header
Every new .cs file must start with:
Reference Policy Selection Guide
When implementing a new policy, choose the closest structural match as your reference:
| Policy Structure | Reference Config | Reference Compiler | Reference Tests |
|---|
| Simple attributes only | RateLimitByKeyConfig | RateLimitByKeyCompiler | RateLimitByKeyTests |
| Attributes + child elements | RateLimitConfig | RateLimitCompiler | RateLimitTests |
| Attributes + typed child arrays | IpFilterConfig | IpFilterCompiler | IpFilterTests |
| String-list child elements | ValidateJwtConfig | ValidateJwtCompiler | ValidateJwtTests |
| Complex nested configs | CorsConfig | CorsCompiler | CorsTests |
| Direct parameters (no config) | — | SetMethodCompiler | SetMethodTests |
Shared Infrastructure Inventory
Expression Support
[Document] attribute (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] attribute (src/Authoring/Attributes/ExpressionAttribute.cs) — Marks a method as a policy expression helper. Captures source file path via [CallerFilePath].
[ExpressionAllowed] attribute (src/Authoring/Attributes/ExpressionAllowedAttribute.cs) — Marks properties or parameters that accept policy expressions.
Expression<T> delegate (src/Authoring/Expression.cs) — delegate T Expression<out T>(IExpressionContext context).
IHaveExpressionContext interface (src/Authoring/IHaveExpressionContext.cs) — Base interface for all section contexts, providing IExpressionContext ExpressionContext { get; }.
Compiler Infrastructure
IMethodPolicyHandler interface (src/Core/Compiling/IMethodPolicyHandler.cs) — The primary compiler interface. Properties: string MethodName { get; }. Method: void Handle(IDocumentCompilationContext context, InvocationExpressionSyntax node).
IReturnValueMethodPolicyHandler interface (src/Core/Compiling/IReturnValueMethodPolicyHandler.cs) — For policies returning a value. Currently disabled (the LocalDeclarationStatementCompiler is commented out in CompilerModule.cs).
- Auto-registration (
src/Core/IoC/CompilerModule.cs) — Uses reflection to find and register all public, non-abstract classes in the Microsoft.Azure.ApiManagement.PolicyToolkit.Compiling.Policy namespace that implement IMethodPolicyHandler. No manual DI wiring needed for standard compilers.
CompilerUtils (src/Core/Compiling/CompilerUtils.cs) — Static utility class with methods for parameter extraction (ProcessParameter, TryExtractingConfig), expression processing, and syntax normalization. Also defines InitializerValue for property name → value mapping.
SyntaxExtensions (src/Core/Compiling/SyntaxExtensions.cs) — Extension methods for Roslyn syntax trees: attribute detection (ContainsAttributeOfType<T>), document class discovery (GetDocumentAttributedClasses), and document metadata extraction.
GenericCompiler.HandleList (src/Core/Compiling/Policy/GenericCompiler.cs) — Utility for compiling string arrays into repeated child XML elements.
CompilationErrors (src/Core/Compiling/Diagnostics/CompilationErrors.cs) — Static class with DiagnosticDescriptor fields for all compilation error types.
Compiler Test Infrastructure
CompilerTestInitialize (test/Test.Core/CompilerTestInitialize.cs) — Assembly-level MSTest setup. Creates Roslyn compilation with references to System, System.Xml.Linq, and the Authoring assembly. Provides the CompileDocument() extension method.
CompilationResultAssertion (test/Test.Core/Assertions/CompilationResultAssertion.cs) — FluentAssertions extension providing BeSuccessful() and DocumentEquivalentTo(string expectedXml).
Usings.cs (test/Test.Core/Usings.cs) — Global usings: FluentAssertions, Microsoft.VisualStudio.TestTools.UnitTesting, assertion helpers, test extensions.
Emulator Infrastructure
IPolicyHandler interface (src/Testing/Emulator/IPolicyHandler.cs) — The handler interface. Properties: string PolicyName { get; }. Method: object? Handle(GatewayContext context, object?[]? args).
PolicyHandler<T> base classes (src/Testing/Emulator/Policies/PolicyHandler.cs) — Three generic variants: single config, optional config, and two-parameter. All include CallbackSetup for test mocking.
SectionContextProxy<T> (src/Testing/Emulator/SectionContextProxy.cs) — Uses System.Reflection.DispatchProxy to dynamically route method calls to handlers. Discovers handlers via reflection on namespace + [Section] attribute.
[Section] attribute (src/Testing/Emulator/Policies/SectionAttribute.cs) — Constructor takes string scope (use nameof(IInboundContext), etc.). Multiple attributes can be stacked.
ArgumentsExtensions (src/Testing/Emulator/Policies/ArgumentsExtensions.cs) — Static utility for safe argument extraction from object?[]?: ExtractArgument<T>() (required single arg), ExtractOptionalArgument<T>() (nullable), and ExtractArguments<T1, T2>() (two-param handlers).
PolicyException (src/Testing/Emulator/PolicyExeption.cs) — Exception thrown when a handler fails. Carries Policy, Section, and PolicyArgs context. Note: filename has a typo (Exeption) — do not rename.
GatewayContext (src/Testing/GatewayContext.cs) — Central mock object with section proxies, mock stores (CertificateStore, CacheStore, ResponseExampleStore, LoggerStore), and expression context.
TestDocument (src/Testing/TestDocument.cs) — Orchestrates test execution across policy sections. Wraps IDocument and calls section methods through proxies.
FinishSectionProcessingException — Thrown by handlers (e.g., MockResponse, ReturnResponse) to terminate section processing early.
Emulator Test Infrastructure
.AsTestDocument() extension — Creates TestDocument from IDocument for fluent test setup.
SetupInbound()/SetupOutbound()/etc. — Returns MockPoliciesProvider<TSection> for mock configuration.
Usings.cs (test/Test.Testing/Usings.cs) — Global usings for FluentAssertions and MSTest.
Section Interfaces
Policies can be available in one or more pipeline sections:
| Section | Interface File | XML Section |
|---|
| Inbound | src/Authoring/IInboundContext.cs | <inbound> |
| Outbound | src/Authoring/IOutboundContext.cs | <outbound> |
| Backend | src/Authoring/IBackendContext.cs | <backend> |
| On-Error | src/Authoring/IOnErrorContext.cs | <on-error> |
| Fragment | src/Authoring/IFragmentContext.cs | N/A (reusable fragment) |
Note: IFragmentContext duplicates method signatures from other interfaces (see //TODO at top of file). Copy signatures verbatim when adding policies there.
Emulator Reference Handler Selection Guide
When implementing a new emulator handler, choose the closest structural match:
| Policy Structure | Reference Handler | Reference Test |
|---|
| Single config, simple state change | SetStatusHandler | SetStatusTests |
| Two parameters (name + values) | SetHeaderHandler | SetHeaderTests |
| Config with callback hooks only (no-op) | RateLimitHandler | RateLimitTests |
| Optional config | MockResponseHandler | MockResponseTests |
| Validation + short-circuit | CheckHeaderHandler | CheckHeaderTests |
| Authentication + token | AuthenticationManagedIdentityHandler | AuthenticationManagedIdentityHandlerTests |
| Cache interaction | CacheLookupValueHandler | CacheLookupValueTests |
| Logging/store interaction | LogToEventHubHandler | LogToEventHubTests |
| No-config (no-arg method) | BaseHandler | BaseTests |
| Custom flow control / wrapper | ReturnResponseHandler | — |
| AzureOpenAi variant (inherits Llm) | AzureOpenAiEmitTokenMetricHandler | — |
Common Pitfalls
| Pitfall | Rule |
|---|
Modifying .csproj files | Do not change Compiling.csproj or Testing.csproj unless explicitly required. Reformatting, reordering, or encoding changes (BOM, line endings) cause noisy diffs and will be rejected in review. |
Missing IFragmentContext entry | Every method added to a section interface (IInboundContext, IOutboundContext, etc.) must also be added to IFragmentContext.cs. See the authoring skill for details. |
| Missing expression tests | Every property marked [ExpressionAllowed] in a config must have a corresponding expression test [DataRow]. See the testing skill section 3 for the pattern. |
Build and Test Commands
dotnet build
dotnet test --project test/Test.Core
dotnet test --project test/Test.Testing
dotnet test --filter "FullyQualifiedName~{PolicyName}Tests"