- Overview
- Architecture
- Security Features
- Quick Start
- Cost Estimation
- Project Structure
- Roadmap
- Cleanup
- Additional Resources
- Contributing
- License
📖 Want to understand what you deployed? Read HOW_IT_WORKS.md for a detailed walkthrough of every component, why we chose these configurations, and what you should know before going to production.
🧪 Ready to explore hands-on? Check out the Lab Guides for step-by-step exercises verifying each security layer — WAF, AI Gateway, RBAC, monitoring, Defender, and agent security.
A self-contained Azure AI security demonstration platform featuring a RAG (Retrieval-Augmented Generation) chat application with enterprise-grade security controls. This project deploys everything from scratch using Bicep, pulls the azure-search-openai-demo app from upstream at build time, builds it in Azure Container Registry, and deploys to Azure Container Apps with optional Azure Front Door + WAF. No application code is stored in this repo—only infrastructure and a minimal Dockerfile.
| Component | Protection | Description |
|---|---|---|
| Front Door + WAF | Edge Security | OWASP managed rules, bot protection, DDoS mitigation |
| API Management | AI Gateway | Centralized AI endpoint management with managed identity auth + retry logic (optional rate limiting / token usage logging) |
| Defender for AI | AI Threat Detection | Tracked enhancement (not enabled by default): #14 |
| Defender for APIs | API Protection | Optional Defender for Cloud plan (enabled via add-on script) |
| Defender for Containers | Container Threat Detection | Optional Defender for Cloud plan (enabled via add-on script) |
| Defender for Storage | Data Protection | Optional (enabled via add-on script): malware scanning on upload, sensitive data discovery (PII/PCI/PHI) |
| Container Apps | Serverless Containers | Auto-scaling, managed environment, no infrastructure to manage |
| Defender for Cosmos DB | Database Security | Optional Defender for Cloud plan (enabled via add-on script) |
| AI Foundry + Agents | Agent Security | Optional IT Admin Agent with managed identity auth, Key Vault for secrets, RBAC-controlled access (set useAgents=true to deploy) |
| Managed Identities | Zero Secrets | No keys in code—all services authenticate via Azure AD |
Azure API Management acts as a centralized AI Gateway providing:
- Managed Identity Auth - APIM authenticates to Azure OpenAI using its managed identity (no keys)
- Retry Logic - Automatic retry with exponential backoff for 429s and 5xx errors
- Optional: Rate Limiting / Quotas - Add incrementally once the basic gateway flow is stable
- Optional: Token Usage Logging - Add incrementally; policy expressions can be finicky
Note: The default deployed policy set is intentionally minimal/known-good (auth + retry). Advanced policy logic (rate limiting, token parsing, extra tracing) should be added carefully and validated against APIM GatewayLogs.
- Azure subscription with Owner or Contributor access
- Azure Developer CLI (azd) installed
- Azure CLI installed and authenticated
- (Optional) GitHub Codespaces or VS Code with Dev Containers
The easiest way to deploy is with azd:
# Clone the repository (--recurse-submodules pulls the upstream app code)
git clone --recurse-submodules https://github.com/matthansen0/azure-ai-security-sandbox.git
cd azure-ai-security-sandbox
# Login to Azure (both are needed – azd for provisioning, az CLI for post-deploy hooks)
az login
azd auth login
# Deploy everything with one command
azd upThat's it! azd up will:
- Prompt you for an environment name and Azure region
- Provision all infrastructure via Bicep
- Clone azure-search-openai-demo from GitHub, build the image in ACR, and deploy to Container Apps
- Configure Front Door routing if
useAFDis true - Output the application URL
⏱️ Deployment Time: Full deployment takes 30-50 minutes depending on configuration:
Resource Time Most resources < 30 seconds Cosmos DB ~1-2 minutes APIM (BasicV2) ~5-10 minutes APIM (Developer) ~20-40 minutes Front Door + WAF ~10-15 minutes AFD WAF propagation ~30-45 minutes Fastest iteration: Use
--parameter useAFD=false --parameter useAPIM=falseto deploy in ~5 minutes.
To skip Front Door for faster iteration, disable it during provisioning:
azd up --parameter useAFD=falseTo skip API Management (APIM AI Gateway) for faster iteration:
azd up --parameter useAPIM=falseOr disable both for the fastest development cycle:
azd up --parameter useAFD=false --parameter useAPIM=falseTo deploy with the optional IT Admin Agent (adds AI Foundry Hub + Project, Key Vault, and agent Container App):
azd up --parameter useAgents=trueWhen Front Door is disabled, APP_PUBLIC_URL points directly to the Container App FQDN.
azd provision # Just provision infrastructure (no code deploy needed)
azd down # Tear down all resources
azd env list # List environments
azd monitor # Open Azure Portal monitoringYou can customize the deployment with optional parameters:
# Deploy to a specific region
azd up --location canadacentralOther useful parameters:
# Disable Azure Front Door (use Container Apps URL directly)
azd up --parameter useAFD=false
# Disable Azure API Management (AI Gateway)
azd up --parameter useAPIM=false
### Optional: Enable Defender Plans (Add-on)
This repo keeps subscription-wide Defender enablement out of the core `azd up` path.
WARNING: Defender plans are enabled at the subscription scope (billing + coverage). If you run this in a shared subscription, it will apply beyond this sandbox.
To enable the Defender plans used by this architecture (after `azd up`):
```bash
./scripts/enable-defender.sh --confirmTo roll back subscription-wide plan changes made by the script:
./scripts/disable-defender.sh --confirmThis add-on enables subscription-wide plans for: Containers, APIs, Storage, and Cosmos DB.
It also applies Defender for Storage advanced settings (malware scanning + sensitive data discovery) to the sandbox storage account.
Note on Defender for AI: availability and the underlying plan name can vary (and may appear under a different pricing name in az security pricing list). If you want it included, first list your available plans and then add the appropriate plan name via additionalPricingPlanNames in infra/addons/defender/main.bicep.
Tracking work: docs/issues/defender-for-ai.md
State tracking: the script writes a local state file under .defender/ so you can roll back subscription-wide plan changes later.
### Troubleshooting
#### Bicep tooling not working in Codespaces
If Bicep files don’t light up (no syntax highlighting / validation) or provisioning complains about missing Bicep:
- Confirm the `Bicep` extension is installed (`ms-azuretools.vscode-bicep`).
- Rebuild the Codespace (this forces extension re-install).
- Ensure the Bicep CLI is installed: `az bicep install --upgrade`.
This repo’s devcontainer runs `az bicep install --upgrade` automatically on creation, but an older Codespace may need a rebuild.
#### Soft-Deleted Cognitive Services Resource
Azure Cognitive Services (OpenAI) has **enforced soft-delete** (90-day retention). If you delete and redeploy with the same environment name, you may see:
FlagMustBeSetForRestore: An existing resource with ID '...' has been soft-deleted. To restore the resource, you must specify 'restore' to be 'true' in the property.
**Fix:** Redeploy with the restore flag:
```bash
azd up --parameter restoreSoftDeletedOpenAi=true
Or purge the soft-deleted resource first:
az cognitiveservices account list-deleted
az cognitiveservices account purge --name <name> --resource-group <rg> --location <location>
azd upAzure API Management has soft-delete with 48-hour retention. Service names are globally unique, so if you delete and redeploy with the same name, you may see conflicts.
Fix: Purge the soft-deleted APIM service first:
az apim deletedservice list --subscription <subscription-id>
az apim deletedservice purge --service-name <name> --location <location>
azd up- Resource Group with all resources
- Log Analytics Workspace for monitoring
- Azure OpenAI with GPT-4o and embedding models
- Azure AI Search for document indexing
- Azure Storage for document blobs
- Azure Cosmos DB for chat history
- Azure Container Apps running the RAG application (cloned from upstream and built in ACR at deploy time)
- Azure API Management as AI Gateway for managed identity auth + retry logic (optional rate limiting/token tracking) (set
useAPIM=falseto skip) - Azure Front Door + WAF for edge protection (WAF defaults to Detection mode, set
useAFD=falseto skip) - Microsoft Defender for Cloud is not enabled in the core deployment; enable plans and per-resource Defender settings via the add-on script
- (Optional) IT Admin Agent - AI-powered troubleshooting agent with tool calling (set
useAgents=true) - (Optional) Azure AI Foundry Hub + Project for agent management (deployed with agents)
- (Optional) Azure Key Vault for AI Foundry secrets (deployed with agents)
Estimated costs for running the sandbox (low/dev usage). Actual costs vary based on usage.
| Configuration | Daily | Monthly |
|---|---|---|
| Full deployment (BasicV2 APIM + AFD) | ~$11-12 | ~$320-350 |
| Full + Agents (adds AI Foundry + agent) | ~$12-14 | ~$370-420 |
| No APIM, No AFD (fastest iteration) | ~$3-4 | ~$95-120 |
Cost breakdown by resource:
| Resource | Monthly Cost | Notes |
|---|---|---|
| API Management (BasicV2) | ~$180 | Use useAPIM=false to skip |
| Front Door Premium + WAF | ~$45 | Base + WAF policy |
| AI Search (Basic) | ~$75 | Fixed tier cost |
| Azure OpenAI | ~$5-20 | Pay per token (GPT-4o + embeddings) |
| Cosmos DB (Serverless) | ~$5-10 | Pay per RU |
| Container Apps | ~$5-20 | Consumption-based |
| Container Registry (Basic) | ~$5 | Image storage |
| Storage Account | ~$1-2 | Blob storage for docs |
| Log Analytics + App Insights | ~$5-10 | Pay per GB ingested |
| AI Foundry Hub + Project | ~$0-5 | Optional (useAgents=true); management plane |
| Key Vault | ~$1-2 | Optional (useAgents=true); secrets for Foundry |
| Agent Container App | ~$5-10 | Optional (useAgents=true); consumption-based |
💡 Cost-saving tips:
- Use
--parameter useAFD=falseto skip Front Door during development (~$45/mo savings)- Use
--parameter useAPIM=falseto skip APIM for local testing (~$180/mo savings)- Remember to
azd down --force --purgewhen not using the environment
After deployment completes, use the Front Door URL (also shown as APP_PUBLIC_URL in azd up outputs).
https://<your-frontdoor-endpoint>.azurefd.net
- APIM + Defender for APIs validation (end-to-end)
- Real architecture diagrams (not ASCII)
- SQL data source + Defender for SQL
- Azure AI Content Safety integration
- Microsoft Purview for DLP
- Data & AI Security Dashboard
- Private endpoint deployment option
azd down --force --purgeIf you enabled Defender plans via the add-on script and want to revert subscription-wide changes, run:
./scripts/disable-defender.sh --confirmThe --purge flag triggers a postdown hook that automatically purges soft-deleted Cognitive Services and APIM resources, preventing conflicts on future deployments.
- Azure OpenAI Landing Zone Reference Architecture
- Azure AI Adoption Framework
- Microsoft Defender for Cloud
Contributions welcome! Please open an issue first for major changes.
MIT License - see LICENSE for details.
