GovUK.Dfe.AI.Agents.Guardrails
0.0.1-prerelease.1665
Prefix Reserved
dotnet add package GovUK.Dfe.AI.Agents.Guardrails --version 0.0.1-prerelease.1665
NuGet\Install-Package GovUK.Dfe.AI.Agents.Guardrails -Version 0.0.1-prerelease.1665
<PackageReference Include="GovUK.Dfe.AI.Agents.Guardrails" Version="0.0.1-prerelease.1665" />
<PackageVersion Include="GovUK.Dfe.AI.Agents.Guardrails" Version="0.0.1-prerelease.1665" />
<PackageReference Include="GovUK.Dfe.AI.Agents.Guardrails" />
paket add GovUK.Dfe.AI.Agents.Guardrails --version 0.0.1-prerelease.1665
#r "nuget: GovUK.Dfe.AI.Agents.Guardrails, 0.0.1-prerelease.1665"
#:package GovUK.Dfe.AI.Agents.Guardrails@0.0.1-prerelease.1665
#addin nuget:?package=GovUK.Dfe.AI.Agents.Guardrails&version=0.0.1-prerelease.1665&prerelease
#tool nuget:?package=GovUK.Dfe.AI.Agents.Guardrails&version=0.0.1-prerelease.1665&prerelease
GovUK.Dfe.AI.Agents.Guardrails
Makes sure every model deployment, or agent version, your GovUK.Dfe.AI.Agents agents use has an Azure AI Foundry guardrail. Foundry then blocks:
- harmful content (hate, sexual, violence, self-harm)
- jailbreak attempts
- instructions hidden in documents and tool output
- protected material
Set up
dotnet add package GovUK.Dfe.AI.Agents.Guardrails
"AiAgents": {
"Guardrails": {
"SubscriptionId": "<subscription id>",
"ResourceGroup": "<resource group>",
"Name": "briefing-guardrail",
"Deployments": [ "gpt-5.1" ]
}
}
builder.Services.AddAgents(builder.Configuration, agents => agents
.AddAgents(BriefingAgents.All)
.AddGuardrails());
Apply once, check everywhere
| Where | What to do | Role on the Foundry resource |
|---|---|---|
| A provisioning job | Call await guardrails.ApplyAsync(ct) (IFoundryGuardrailsService). This creates or updates the guardrail and assigns it to each deployment, writing only what differs |
Cognitive Services Contributor (Reader when nothing differs) |
| Every app | Nothing. At startup, the app checks each deployment has the guardrail and that it hasn't been weakened | Reader |
- Scope: both roles are on the Foundry resource, not the project: guardrails and deployments belong to the resource. Agents still need only Foundry User on the project.
- Infrastructure as code instead: create the guardrail in Bicep or Terraform and skip
ApplyAsync; apps still check it, with only Reader. - Missing or weakened: startup fails, saying what's wrong (
"RequireAtStartup": falseonly warns). - Resource Manager unreachable: startup warns, so an outage doesn't stop new instances
(
"FailWhenUnreachable": truefails instead).
Models through a connection
When Foundry:DefaultModel is <connection>/<model>, the deployments aren't in your Foundry resource, so put the
guardrail on the agents:
"Guardrails": {
"SubscriptionId": "<subscription id>",
"ResourceGroup": "<resource group>",
"Name": "briefing-guardrail",
"Targets": "Agents"
}
- No
Deployments;ApplyAsynccreates or updates only the guardrail and blocklists. - Every agent version the app creates gets the guardrail, by its full Resource Manager ID (it becomes
Foundry:Guardrail). - The startup check confirms each pinned or externally managed version has it, e.g.
agent 'rsd-trust-agent' version 4 uses no guardrail. Fix by provisioning a new version. "Targets": "Deployments, Agents"does both.
Settings
| Setting | Default | Purpose |
|---|---|---|
SubscriptionId, ResourceGroup |
Required | Where the Foundry resource is |
AccountName |
The resource in Foundry:Endpoint |
Set only if the deployments are on another Foundry resource |
Name |
Required | The guardrail's name in Foundry |
Targets |
Deployments |
Where the guardrail goes: Deployments, Agents, or both |
Deployments |
Required for Deployments |
Every model deployment your agents use |
BlockFrom |
Medium |
Lowest harm severity blocked in prompts and answers. Low blocks the most |
PromptShields |
true |
Blocks jailbreak attempts |
IndirectAttacks |
true |
Blocks instructions hidden in documents and tool output |
CheckBlocklists |
false |
Checks each run's question and evidence against Blocklists in the app (see below) |
ScanPrompts |
false |
Scans each run's question with Prompt Shields before it's sent (see below) |
ScanEvidence |
false |
Scans each run's evidence with Prompt Shields before it's sent (see below) |
ContentSafetyEndpoint |
The Foundry resource's own | The Content Safety endpoint ScanPrompts and ScanEvidence call |
ProtectedMaterial |
true |
Blocks answers that reproduce protected text or code |
Blocklists |
None | Your own blocked terms and patterns (see below) |
RequireAtStartup |
true |
Fails startup when a deployment or agent version lacks the guardrail |
FailWhenUnreachable |
false |
Fails startup when the guardrail can't be checked, e.g. Resource Manager is unreachable |
Authentication |
The default identity | A separate identity for Resource Manager (or agents.UseGuardrailsCredential(...) in code) |
Blocklists
Block your own terms, such as project code names or case reference formats:
"Blocklists": {
"case-references": { "Terms": [ "Project Falcon" ], "Patterns": [ "CASE-\\d{6}" ] }
}
ApplyAsync creates each blocklist with exactly these entries, for prompts and answers. The startup check reports a
blocklist that's detached or missing entries, by count only. Load sensitive terms from Key Vault, not appsettings.json.
When a guardrail blocks something
The run fails with an inner AgentGuardrailException (Stage: prompt, answer or evidence), counted by
dfe.ai_agents.guardrail.blocks. In parallel and sequential runs, the agent gets a fallback result instead. Core
reports blocks with or without this package.
Checking input in the app
A Foundry guardrail doesn't cover everything an agent is sent:
- Evidence passed in an agent's input is never scanned for planted instructions: Foundry only scans documents in Chat Completions requests and the output of its own tools (Azure AI Search, OpenAPI and others).
- A model behind your own gateway (an API Management connection) gets no Foundry guardrail at all: Microsoft leaves safety for those models to you (Bring your own model). The startup check can confirm the guardrail is on an agent version while nothing enforces it.
So the app can check each run's input itself, after redaction and before anything is sent. A match blocks the run like
a guardrail block, with the reason in AgentGuardrailException.Reason:
| Setting | Checks | How | Blocks with Stage |
|---|---|---|---|
CheckBlocklists |
The question and the evidence against Blocklists |
In the app, no call to Azure; first | prompt or evidence |
ScanPrompts |
The question, for jailbreak attempts | Prompt Shields, one call | prompt |
ScanEvidence |
The evidence, for planted instructions | Prompt Shields, one call per 9,000 characters, up to 4 at a time | evidence |
- Identity:
ScanPromptsandScanEvidenceneed Cognitive Services User on the Foundry resource, athttps://<resource>.cognitiveservices.azure.com/(orContentSafetyEndpoint). - Cost: the two scans run side by side, about 100–200 ms for a typical run; blocklists cost nothing.
- Fails closed: if input can't be scanned, e.g. because the role is missing, the run fails rather than sending it.
- Release gate: test cases with
"guardrailMustBlock": trueprove each check works. - Your own: register an
IInputShieldinstead, for other checks.
Not included
PII filtering: Foundry's PII filter needs a preview API, and this package uses GA APIs only. If you need it, turn it on in the Foundry portal; the startup check leaves it alone.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Azure.ResourceManager.CognitiveServices (>= 1.6.0)
- GovUK.Dfe.AI.Agents (>= 0.0.1-prerelease.1869)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-prerelease.1665 | 0 | 10/20/2026 |
| 0.0.1-prerelease.1602 | 0 | 10/20/2026 |
| 0.0.1-prerelease.1541 | 33 | 10/19/2026 |
| 0.0.1-prerelease.1481 | 36 | 10/19/2026 |
| 0.0.1-prerelease.1422 | 47 | 10/19/2026 |
| 0.0.1-prerelease.1365 | 36 | 10/19/2026 |
| 0.0.1-prerelease.1309 | 40 | 10/16/2026 |
| 0.0.1-prerelease.1254 | 44 | 10/16/2026 |
| 0.0.1-prerelease.1200 | 37 | 10/16/2026 |
| 0.0.1-prerelease.1149 | 37 | 10/16/2026 |
| 0.0.1-prerelease.1099 | 43 | 10/16/2026 |
| 0.0.1-prerelease.1050 | 39 | 10/16/2026 |
| 0.0.1-prerelease.1002 | 46 | 10/16/2026 |
| 0.0.1-prerelease.955 | 42 | 10/16/2026 |
| 0.0.1-prerelease.909 | 38 | 10/16/2026 |
| 0.0.1-prerelease.864 | 36 | 10/16/2026 |
| 0.0.1-prerelease.820 | 45 | 10/16/2026 |
| 0.0.1-prerelease.777 | 44 | 10/16/2026 |
| 0.0.1-prerelease.735 | 41 | 10/16/2026 |
| 0.0.1-prerelease.694 | 41 | 10/16/2026 |