-
Notifications
You must be signed in to change notification settings - Fork 124
Network - 25415 - Enterprise generative AI applications are protected from prompt injection attacks through AI Gateway #835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds a new Network/Global Secure Access assessment (25415) to verify that Prompt Shield (AI Gateway) prompt-injection protections are configured and enforced.
Changes:
- Introduces
Test-Assessment-25415PowerShell test that queries prompt policies and evaluates enforcement via Baseline Profile or CA-assigned Security Profiles. - Adds accompanying markdown guidance content and a
%TestResult%insertion point for reporting.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/powershell/tests/Test-Assessment.25415.ps1 | Implements the assessment logic, Graph data collection, enforcement evaluation, and detailed markdown report tables. |
| src/powershell/tests/Test-Assessment.25415.md | Provides remediation steps and embeds the %TestResult% placeholder for generated output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… into Feature-25415
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams | ||
|
|
||
| foreach ($profileLink in $linkedProfiles) { | ||
| if ($profileLink.ProfileType -eq 'Baseline Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled') { |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Baseline profiles are added as "enabled" based only on ProfileState and PassesCriteria, but the policy link state is not considered. This can mark Prompt Shield as enforced even when the prompt policy link is disabled. Include a PolicyLinkState -eq 'enabled' check when adding to $enabledBaselineProfiles (similar to Test-Assessment.25408.ps1:89-94).
| if ($profileLink.ProfileType -eq 'Baseline Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled') { | |
| if ($profileLink.ProfileType -eq 'Baseline Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled' -and $profileLink.PolicyLinkState -eq 'enabled') { |
| PromptPolicyLinkState = $profileLink.PolicyLinkState | ||
| } | ||
| } | ||
| elseif ($profileLink.ProfileType -eq 'Security Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled') { |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security profiles are treated as enforcing Prompt Shield even if the prompt policy link itself is disabled, because the elseif condition doesn't check PolicyLinkState. Add -and $profileLink.PolicyLinkState -eq 'enabled' to avoid false positives when a policy is linked but disabled.
| elseif ($profileLink.ProfileType -eq 'Security Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled') { | |
| elseif ($profileLink.ProfileType -eq 'Security Profile' -and $profileLink.PassesCriteria -and $profileLink.ProfileState -eq 'enabled' -and $profileLink.PolicyLinkState -eq 'enabled') { |
| $securityProfilesSection += "| Profile Name | State | Priority | Prompt Policy | CA Policies Assigned | Is Baseline |`n" | ||
| $securityProfilesSection += "| :----------- | :---- | :------- | :------------ | :------------------- | :---------- |`n" | ||
| foreach ($profile in $enabledSecurityProfiles) { | ||
| $profilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$($profile.ProfileId)" | ||
| $policyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditPromptPolicyMenuBlade.MenuView/~/basics/policyId/$($profile.PromptPolicyId)" | ||
| $profileName = Get-SafeMarkdown -Text $profile.ProfileName | ||
| $policyName = Get-SafeMarkdown -Text $profile.PromptPolicyName | ||
| $isBaseline = if ($profile.ProfilePriority -eq $BASELINE_PROFILE_PRIORITY) { 'Yes' } else { 'No' } | ||
| $caCount = $profile.CAPolicyCount | ||
| $securityProfilesSection += "| [$profileName]($profilePortalLink) | $($profile.ProfileState) | $($profile.ProfilePriority) | [$policyName]($policyPortalLink) | $caCount | $isBaseline |`n" |
Copilot
AI
Jan 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$enabledSecurityProfiles only contains entries where ProfileType -eq 'Security Profile', so the computed Is Baseline column will always be "No". Removing this column (and the isBaseline calculation) would simplify the report and avoid confusion.
| $securityProfilesSection += "| Profile Name | State | Priority | Prompt Policy | CA Policies Assigned | Is Baseline |`n" | |
| $securityProfilesSection += "| :----------- | :---- | :------- | :------------ | :------------------- | :---------- |`n" | |
| foreach ($profile in $enabledSecurityProfiles) { | |
| $profilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$($profile.ProfileId)" | |
| $policyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditPromptPolicyMenuBlade.MenuView/~/basics/policyId/$($profile.PromptPolicyId)" | |
| $profileName = Get-SafeMarkdown -Text $profile.ProfileName | |
| $policyName = Get-SafeMarkdown -Text $profile.PromptPolicyName | |
| $isBaseline = if ($profile.ProfilePriority -eq $BASELINE_PROFILE_PRIORITY) { 'Yes' } else { 'No' } | |
| $caCount = $profile.CAPolicyCount | |
| $securityProfilesSection += "| [$profileName]($profilePortalLink) | $($profile.ProfileState) | $($profile.ProfilePriority) | [$policyName]($policyPortalLink) | $caCount | $isBaseline |`n" | |
| $securityProfilesSection += "| Profile Name | State | Priority | Prompt Policy | CA Policies Assigned |`n" | |
| $securityProfilesSection += "| :----------- | :---- | :------- | :------------ | :------------------- |`n" | |
| foreach ($profile in $enabledSecurityProfiles) { | |
| $profilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$($profile.ProfileId)" | |
| $policyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditPromptPolicyMenuBlade.MenuView/~/basics/policyId/$($profile.PromptPolicyId)" | |
| $profileName = Get-SafeMarkdown -Text $profile.ProfileName | |
| $policyName = Get-SafeMarkdown -Text $profile.PromptPolicyName | |
| $caCount = $profile.CAPolicyCount | |
| $securityProfilesSection += "| [$profileName]($profilePortalLink) | $($profile.ProfileState) | $($profile.ProfilePriority) | [$policyName]($policyPortalLink) | $caCount |`n" |
Enterprise generative AI applications are protected from prompt injection attacks through AI Gateway