Skip to content

Commit a3c9852

Browse files
authored
Merge pull request #439 from microsoft/feature-marco
ajakupov-microsoft PR merge into main
2 parents 4fa8d23 + ccc8615 commit a3c9852

262 files changed

Lines changed: 199586 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Agentic Governance Hub
2+
3+
Welcome to the **Agentic Governance Hub** MicroHack. In this hands-on lab you'll deploy a
4+
**Citadel Agentic Governance Hub** — a centralized Azure API Management gateway that
5+
governs every LLM/agent call in your organization — and drive it through nine guided,
6+
notebook-based exercises covering backend onboarding, access contracts, PII handling,
7+
multi-framework agents, hosted agents, and agent-to-agent / MCP publishing.
8+
9+
- [**Introduction**](#introduction)
10+
- [**Learning objectives**](#learning-objectives)
11+
- [**Scenario**](#scenario)
12+
- [**Requirements**](#requirements)
13+
- [**Challenges**](#challenges)
14+
- [**Repository layout**](#repository-layout)
15+
- [**Contributors**](#contributors)
16+
17+
## Introduction
18+
19+
This MicroHack teaches you how to put **governance in front of AI**: a single Azure API
20+
Management gateway (the **Citadel Governance Hub**) that every model call and every agent
21+
routes through, so an organization gets consistent RBAC, rate-limiting/capacity control,
22+
PII handling, and audit trails — no matter which model, which agent framework, or which
23+
protocol (chat completions, Responses API, A2A, MCP) a team chooses to build with.
24+
25+
Your lab automation ([`labautomation/`](labautomation/)) provisions a dedicated **Hub**
26+
(APIM + a Foundry account for governance) and **Spoke** (a sample Foundry workload) per
27+
attendee. The nine challenges then walk you through the **unchanged Citadel workshop
28+
notebooks** — each one a self-contained, already-documented exercise — in the order the
29+
governance model builds up: onboard a backend, expose it universally, add access
30+
contracts (RBAC + capacity), drive those contracts from real agent frameworks, add PII
31+
processing, unify multiple providers behind one API, then graduate to hosted agents
32+
governed end-to-end, agent-to-agent publishing, and MCP tool publishing.
33+
34+
## Learning objectives
35+
36+
By completing this MicroHack you will be able to:
37+
38+
- Onboard a new LLM backend into a governance gateway and prove it through multiple API
39+
shapes (Azure OpenAI, Universal LLM API, streaming).
40+
- Provision **Access Contracts** that enforce model-level RBAC and capacity limits, and
41+
understand how token-bucket throttling behaves under load.
42+
- Drive the same governed access contract from three different agent frameworks
43+
(Microsoft Agent Framework, Foundry Agent SDK, LangChain).
44+
- Configure PII anonymization/deanonymization and PII blocking at the gateway, with usage
45+
analytics.
46+
- Compare model-provider access patterns (Azure OpenAI, Foundry inference, Responses API,
47+
Gemini-compatible) behind one **Unified AI API**.
48+
- Build and deploy a **Foundry Hosted Agent** governed end-to-end by the **Agent
49+
Governance Toolkit (AGT)**, and read its audit trail in Application Insights.
50+
- Publish a Foundry Agent as a governed **Agent-to-Agent (A2A)** endpoint through APIM.
51+
- Understand how an **MCP server** is published and consumed through APIM, including
52+
where this lab's automation stops short (Entra app-registration/app-role setup) and
53+
what a facilitator needs to add to unlock that exercise.
54+
55+
## Scenario
56+
57+
You are onboarding your organization onto a **Citadel Agentic Governance Hub**: a single
58+
Azure API Management gateway that every model call and every agent must pass through, so
59+
platform, security, and compliance teams get one place to see and control AI usage.
60+
61+
Your lab automation deploys:
62+
63+
- A **Hub** resource group containing APIM, a governance Foundry account/project, Log
64+
Analytics, Application Insights, Cosmos DB (usage tracking), Event Hub, and Key Vault.
65+
- A **Spoke** resource group (folded into the same RG) containing a sample Foundry
66+
account/project and Azure Container Registry — where you build and deploy the agents
67+
the later challenges call for.
68+
69+
Each challenge exercises one governance capability against these resources, using the
70+
Citadel workshop's own Jupyter notebooks — unmodified, and already fully documented with
71+
their own numbered sections, so the challenge files here exist to orient you and point
72+
you at the right notebook, not to restate what's already in it.
73+
74+
## Requirements
75+
76+
To complete this MicroHack you'll need:
77+
78+
- Your lab's attendee credentials (`HackboxCredential` values) from the MicroHack
79+
dashboard — resource group, subscription, and the Spoke Foundry/Key Vault/ACR names.
80+
- `azd` installed, so [`setup-notebook-env.ps1`](labautomation/README.md#notebook-environment-setup)
81+
can bridge those credentials into a local `azd` environment the (unchanged) workshop
82+
notebooks read via `azd env get-value`.
83+
- The Azure CLI (`az`), logged in (`az login`) against your lab's subscription/tenant.
84+
- The workshop's Python environment set up (`uv sync` — see
85+
[`challenges/workshop/readme.md`](challenges/workshop/readme.md) — or
86+
`pip install -r requirements.txt` from the `challenges/workshop/` folder).
87+
- Comfort running and reading Jupyter notebooks in VS Code.
88+
89+
> [!TIP]
90+
> **You're ready to start when** you've run `setup-notebook-env.ps1` once with your
91+
> dashboard's credentials (see [Challenge 1, Part A](challenges/challenge-01.md)) and can
92+
> open the first workshop notebook without any `azd env get-value` errors.
93+
94+
## Challenges
95+
96+
This MicroHack is divided into nine challenges. Challenges 1–6 build up the core
97+
governance model (backends → universal API → access contracts → agent frameworks → PII →
98+
unified API); challenges 7–8 graduate to hosted, governed agents and agent-to-agent
99+
publishing; challenge 9 covers MCP publishing and is **optional/instructor-led**, since it
100+
needs infrastructure this lab's automation doesn't provision on its own.
101+
102+
### Challenge structure
103+
104+
Each challenge follows the same anatomy, so you always know where to look:
105+
106+
| Section | Description |
107+
|---------|-------------|
108+
| 🎯 **Objective** | What you'll achieve and why it matters |
109+
| 🧭 **Context** | The Hub/Spoke resources and prerequisites this exercise relies on |
110+
|**Tasks** | Confirm your notebook bridge, then run the notebook's own sections in order |
111+
| 🏁 **Success criteria** | A checklist to confirm you're done |
112+
| 🛠️ **Troubleshooting** | Common problems and their fixes |
113+
| 🚀 **Go further** | Optional stretch goals if you finish early |
114+
| 📚 **Learning resources** | Docs to go deeper |
115+
116+
### Challenge list
117+
118+
- **Challenge 1**: **[Onboard a New LLM Backend](challenges/challenge-01.md)** *(35 min)* — onboard a backend into the hub and prove it through multiple API shapes.
119+
- **Challenge 2**: **[Universal LLM API Across Every Model](challenges/challenge-02.md)** *(25 min)* — validate `/models` against every model with no RBAC restriction.
120+
- **Challenge 3**: **[Access Contracts: Model RBAC & Capacity](challenges/challenge-03.md)** *(35 min)* — three access contracts enforcing `allowedModels` and capacity limits.
121+
- **Challenge 4**: **[Drive Access Contracts from Agent Frameworks](challenges/challenge-04.md)** *(30 min)* — the same contracts, driven from three different agent frameworks.
122+
- **Challenge 5**: **[PII Anonymization, Blocking & Analytics](challenges/challenge-05.md)** *(35 min)* — mask, block, and analyze PII at the gateway.
123+
- **Challenge 6**: **[Unified AI API Across Providers](challenges/challenge-06.md)** *(35 min)* — one API surface across Azure OpenAI, Foundry inference, Responses API, and Gemini-compatible patterns.
124+
- **Challenge 7**: **[Build a Governed Hosted Agent with AGT](challenges/challenge-07.md)** *(40 min)* — deploy a Foundry Hosted Agent governed end-to-end by the Agent Governance Toolkit.
125+
- **Challenge 8**: **[Publish a Foundry Agent as an A2A Endpoint](challenges/challenge-08.md)** *(35 min)* — publish and call an agent-to-agent endpoint through APIM.
126+
- **Challenge 9** *(optional / instructor-led)*: **[HR MCP via APIM](challenges/challenge-09.md)** *(variable)* — publish and consume an MCP server through APIM; requires facilitator-provisioned infrastructure beyond this lab's automation.
127+
128+
> [!TIP]
129+
> It's tempting to race through, but pause after each challenge and read the notebook's
130+
> own `📊 Results Summary` cell — that's where the "why this matters for governance"
131+
> payoff actually lands.
132+
133+
## Repository layout
134+
135+
```
136+
05_AI_Governance/
137+
README.md This file
138+
challenges/ Challenge instructions (challenge-01.md … challenge-09.md)
139+
labautomation/ Platform entry point — provisions the Hub + Spoke per attendee
140+
deploy-lab.ps1 Called once per attendee by the MicroHack platform
141+
run-local.ps1 Local-only dry-run wrapper (not used by the platform)
142+
setup-notebook-env.ps1 Bridges dashboard credentials into a local azd environment
143+
README.md Full provisioning + notebook-environment-setup reference
144+
reference/
145+
ai-hub-gateway-solution-accelerator/
146+
workshop/ The 9 unchanged Citadel workshop notebooks this MicroHack is built on
147+
```
148+
149+
## Contributors
150+
151+
| Name | Role |
152+
|------|------|
153+
| Alibek Jakupov | Author & maintainer |
154+
155+
## Contributing
156+
157+
This project welcomes contributions and suggestions. Most contributions require you to agree to a
158+
Contributor License Agreement (CLA). For details, visit [https://cla.opensource.microsoft.com](https://cla.opensource.microsoft.com).
159+
160+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
161+
162+
## Trademarks
163+
164+
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
165+
trademarks or logos is subject to and must follow
166+
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Application name
2+
name: ai-citadel-governance-hub
3+
metadata:
4+
template: ai-citadel-governance-hub
5+
infra:
6+
path: bicep/infra
7+
provider: bicep
8+
services:
9+
usageProcessingLogicApp:
10+
project: ./src/usage-ingestion-logicapp
11+
language: js
12+
host: function
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
{
2+
"analysisServicesServers": "as",
3+
"apiManagementService": "apim-",
4+
"apiCenterService": "apic-",
5+
"appConfigurationConfigurationStores": "appcs-",
6+
"appManagedEnvironments": "cae-",
7+
"appContainerApps": "ca-",
8+
"authorizationPolicyDefinitions": "policy-",
9+
"automationAutomationAccounts": "aa-",
10+
"blueprintBlueprints": "bp-",
11+
"blueprintBlueprintsArtifacts": "bpa-",
12+
"cacheRedis": "redis-",
13+
"cdnProfiles": "cdnp-",
14+
"cdnProfilesEndpoints": "cdne-",
15+
"cognitiveServicesAccounts": "cog-",
16+
"cognitiveServicesFormRecognizer": "cog-fr-",
17+
"cognitiveServicesTextAnalytics": "cog-ta-",
18+
"computeAvailabilitySets": "avail-",
19+
"computeCloudServices": "cld-",
20+
"computeDiskEncryptionSets": "des",
21+
"computeDisks": "disk",
22+
"computeDisksOs": "osdisk",
23+
"computeGalleries": "gal",
24+
"computeSnapshots": "snap-",
25+
"computeVirtualMachines": "vm",
26+
"computeVirtualMachineScaleSets": "vmss-",
27+
"containerInstanceContainerGroups": "ci",
28+
"containerRegistryRegistries": "cr",
29+
"containerServiceManagedClusters": "aks-",
30+
"databricksWorkspaces": "dbw-",
31+
"dataFactoryFactories": "adf-",
32+
"dataLakeAnalyticsAccounts": "dla",
33+
"dataLakeStoreAccounts": "dls",
34+
"dataMigrationServices": "dms-",
35+
"dBforMySQLServers": "mysql-",
36+
"dBforPostgreSQLServers": "psql-",
37+
"devicesIotHubs": "iot-",
38+
"devicesProvisioningServices": "provs-",
39+
"devicesProvisioningServicesCertificates": "pcert-",
40+
"documentDBDatabaseAccounts": "cosmos-",
41+
"eventGridDomains": "evgd-",
42+
"eventGridDomainsTopics": "evgt-",
43+
"eventGridEventSubscriptions": "evgs-",
44+
"eventHubNamespaces": "evhns-",
45+
"eventHubNamespacesEventHubs": "evh-",
46+
"hdInsightClustersHadoop": "hadoop-",
47+
"hdInsightClustersHbase": "hbase-",
48+
"hdInsightClustersKafka": "kafka-",
49+
"hdInsightClustersMl": "mls-",
50+
"hdInsightClustersSpark": "spark-",
51+
"hdInsightClustersStorm": "storm-",
52+
"hybridComputeMachines": "arcs-",
53+
"insightsActionGroups": "ag-",
54+
"insightsComponents": "appi-",
55+
"keyVaultVaults": "kv-",
56+
"kubernetesConnectedClusters": "arck",
57+
"kustoClusters": "dec",
58+
"kustoClustersDatabases": "dedb",
59+
"logicIntegrationAccounts": "ia-",
60+
"logicWorkflows": "logic-",
61+
"machineLearningServicesWorkspaces": "mlw-",
62+
"managedIdentityUserAssignedIdentities": "id-",
63+
"managementManagementGroups": "mg-",
64+
"migrateAssessmentProjects": "migr-",
65+
"networkApplicationGateways": "agw-",
66+
"networkApplicationSecurityGroups": "asg-",
67+
"networkAzureFirewalls": "afw-",
68+
"networkBastionHosts": "bas-",
69+
"networkConnections": "con-",
70+
"networkDnsZones": "dnsz-",
71+
"networkExpressRouteCircuits": "erc-",
72+
"networkFirewallPolicies": "afwp-",
73+
"networkFirewallPoliciesWebApplication": "waf",
74+
"networkFirewallPoliciesRuleGroups": "wafrg",
75+
"networkFrontDoors": "fd-",
76+
"networkFrontdoorWebApplicationFirewallPolicies": "fdfp-",
77+
"networkLoadBalancersExternal": "lbe-",
78+
"networkLoadBalancersInternal": "lbi-",
79+
"networkLoadBalancersInboundNatRules": "rule-",
80+
"networkLocalNetworkGateways": "lgw-",
81+
"networkNatGateways": "ng-",
82+
"networkNetworkInterfaces": "nic-",
83+
"networkNetworkSecurityGroups": "nsg-",
84+
"networkNetworkSecurityGroupsSecurityRules": "nsgsr-",
85+
"networkNetworkWatchers": "nw-",
86+
"networkPrivateDnsZones": "pdnsz-",
87+
"networkPrivateLinkServices": "pl-",
88+
"networkPublicIPAddresses": "pip-",
89+
"networkPublicIPPrefixes": "ippre-",
90+
"networkRouteFilters": "rf-",
91+
"networkRouteTables": "rt-",
92+
"networkRouteTablesRoutes": "udr-",
93+
"networkTrafficManagerProfiles": "traf-",
94+
"networkVirtualNetworkGateways": "vgw-",
95+
"networkVirtualNetworks": "vnet-",
96+
"networkVirtualNetworksSubnets": "snet-",
97+
"networkVirtualNetworksVirtualNetworkPeerings": "peer-",
98+
"networkVirtualWans": "vwan-",
99+
"networkVpnGateways": "vpng-",
100+
"networkVpnGatewaysVpnConnections": "vcn-",
101+
"networkVpnGatewaysVpnSites": "vst-",
102+
"notificationHubsNamespaces": "ntfns-",
103+
"notificationHubsNamespacesNotificationHubs": "ntf-",
104+
"operationalInsightsWorkspaces": "log-",
105+
"portalDashboards": "dash-",
106+
"powerBIDedicatedCapacities": "pbi-",
107+
"purviewAccounts": "pview-",
108+
"privateEndpoints": "pe-",
109+
"recoveryServicesVaults": "rsv-",
110+
"resourcesResourceGroups": "rg-",
111+
"searchSearchServices": "srch-",
112+
"serviceBusNamespaces": "sb-",
113+
"serviceBusNamespacesQueues": "sbq-",
114+
"serviceBusNamespacesTopics": "sbt-",
115+
"serviceEndPointPolicies": "se-",
116+
"serviceFabricClusters": "sf-",
117+
"signalRServiceSignalR": "sigr",
118+
"sqlManagedInstances": "sqlmi-",
119+
"sqlServers": "sql-",
120+
"sqlServersDataWarehouse": "sqldw-",
121+
"sqlServersDatabases": "sqldb-",
122+
"sqlServersDatabasesStretch": "sqlstrdb-",
123+
"storageStorageAccounts": "st",
124+
"storageStorageAccountsVm": "stvm",
125+
"storSimpleManagers": "ssimp",
126+
"streamAnalyticsCluster": "asa-",
127+
"synapseWorkspaces": "syn",
128+
"synapseWorkspacesAnalyticsWorkspaces": "synw",
129+
"synapseWorkspacesSqlPoolsDedicated": "syndp",
130+
"synapseWorkspacesSqlPoolsSpark": "synsp",
131+
"timeSeriesInsightsEnvironments": "tsi-",
132+
"webServerFarms": "plan-",
133+
"webSitesAppService": "app-",
134+
"webSitesAppServiceEnvironment": "ase-",
135+
"webSitesFunctions": "func-",
136+
"webStaticSites": "stapp-"
137+
}

0 commit comments

Comments
 (0)