Skip to content

Commit dc3a08b

Browse files
Refine and add instructions for APIM policies
1 parent cc4bd71 commit dc3a08b

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,3 +601,4 @@ Samples that require administrative or operational endpoints (cache loading, con
601601
### API Management Policy XML Instructions
602602

603603
- Policies should use camelCase for all variable names.
604+
- Policy expressions (`@(...)` and `@{...}`) may **only** reference .NET types and members on APIM's [allow-list](https://learn.microsoft.com/azure/api-management/api-management-policy-expressions#CLRTypes). Using anything outside the list (e.g. `System.Globalization.*`, `DateTime.TryParse`, `DateTime.ToUniversalTime`, `System.Text.Json`) causes a deploy-time `ValidationError: One or more fields contain incorrect values` with no further detail. Verify each type/member against the allow-list before writing the expression. See `.github/skills/apim-policies/SKILL.md` for common pitfalls and allowed replacements.

.github/skills/apim-policies/SKILL.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,30 @@ Policy expressions use C# syntax within `@()` for single statements or `@{}` for
167167
}" />
168168
```
169169

170+
### Allowed .NET Types and Members (CRITICAL)
171+
172+
Policy expressions may **only** reference the .NET Framework types and members on APIM's [allow-list](https://learn.microsoft.com/azure/api-management/api-management-policy-expressions#CLRTypes). Anything outside the list causes a deploy-time `ValidationError: One or more fields contain incorrect values` with no further detail, which is hard to diagnose.
173+
174+
Before using a type or member in a policy expression, verify it appears on the official allow-list. Common pitfalls:
175+
176+
- **Whole namespaces are absent.** `System.Globalization` (e.g. `DateTimeStyles`, `CultureInfo`), `System.Threading`, `System.IO` (except `StringReader`/`StringWriter`), `System.Net.Http`, `System.Reflection`, and `System.Diagnostics` are not allowed.
177+
- **`System.DateTime` is restricted.** Allowed members include `Parse`, `UtcNow`, `Now`, `AddSeconds`, `Subtract`, `ToString`, `Ticks`. **Not allowed:** `TryParse`, `TryParseExact`, `ParseExact`, `ToUniversalTime`, `ToLocalTime`, `SpecifyKind`. For round-trip-safe time math, prefer `System.DateTimeOffset` (`All` members allowed) and `ToUnixTimeSeconds()` / `ToUnixTimeMilliseconds()`.
178+
- **`System.Enum` is restricted to** `Parse`, `TryParse`, `ToString`. No `GetValues`, `GetNames`, `IsDefined`.
179+
- **`System.Text.RegularExpressions.Regex` is restricted to** the constructor plus `IsMatch`, `Match`, `Matches`, `Replace`, `Unescape`, `Split`. No `CompileToAssembly`, `CacheSize`.
180+
- **Numeric primitives are fully allowed**, so `int.TryParse`, `long.TryParse`, `double.TryParse` are safe.
181+
- **JSON via `Newtonsoft.Json`** is the only supported JSON library — do not use `System.Text.Json`.
182+
183+
When a member you need is not allowed, refactor to an equivalent that is. Examples:
184+
185+
| Disallowed | Allowed replacement |
186+
|---|---|
187+
| `DateTime.TryParse(s, ..., DateTimeStyles.RoundtripKind, out dt)` | Store as Unix epoch via `DateTimeOffset.UtcNow.ToUnixTimeSeconds()`, parse with `long.TryParse` |
188+
| `DateTime.ParseExact(s, fmt, CultureInfo.InvariantCulture)` | `DateTime.Parse(s)` (allowed) or epoch-based representation |
189+
| `Enum.GetValues(typeof(T))` | Hard-code the comparison values or store as a string |
190+
| `System.Text.Json.JsonSerializer.Deserialize<T>(s)` | `JsonConvert.DeserializeObject<T>(s)` |
191+
192+
If you are unsure whether a member is allowed, fetch the [allowed types table](https://learn.microsoft.com/azure/api-management/api-management-policy-expressions#CLRTypes) and confirm before writing the expression.
193+
170194
## Reference Documentation
171195

172196
- **Shared policies in this repo**: `shared/apim-policies/` (reusable policy XML fragments)

0 commit comments

Comments
 (0)