Skip to main content

citadel-spoke-onboarding

Onboard a Foundry project as a spoke into an AI Citadel Governance Hub. Covers Access Contracts, APIM connections, product policies, JWT auth. USE FOR: citadel spoke onboarding, access contract, connect foundry to citadel, APIM connection, bring your own ai gateway, govern agent, citadel JWT auth, citadel product policy, unified ai api, citadel AGT, vnet-isolated citadel spoke, foundry-vnet-deploy spoke onboarding. DO NOT USE FOR: deploying the Citadel hub itself, APIM infrastructure, hub networking, hub provisioning, hub sizing, llm backend onboarding, deploying model backends, apim backend pools, hub policy fragment deployment, spoke-side VNet/peering creation (use foundry-vnet-deploy).

Zur Installation springen

Quellinformationen

Repository
aiappsgbb/awesome-gbb
Letzte Quellaktivität
17. September 2026 um 09:59
Erkannte Sprache von SKILL.md
Englisch
Sterne
6
Forks
3

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
5 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
citadel-spoke-onboarding
description
Onboard a Foundry project as a spoke into an AI Citadel Governance Hub. Covers Access Contracts, APIM connections, product policies, JWT auth. USE FOR: citadel spoke onboarding, access contract, connect foundry to citadel, APIM connection, bring your own ai gateway, govern agent, citadel JWT auth, citadel product policy, unified ai api, citadel AGT, vnet-isolated citadel spoke, foundry-vnet-deploy spoke onboarding. DO NOT USE FOR: deploying the Citadel hub itself, APIM infrastructure, hub networking, hub provisioning, hub sizing, llm backend onboarding, deploying model backends, apim backend pools, hub policy fragment deployment, spoke-side VNet/peering creation (use foundry-vnet-deploy).
metadata
{"version":"2.0.0"}
# Citadel Spoke Onboarding — Reference Guide How to connect a GenAI application or Microsoft Foundry project to an **existing** AI Citadel Governance Hub. Controls cover the traffic actually routed through the gateway, not every agent action or a compliance certification. > **Threadlight integration**: This skill is the **opt-in Phase 7** of > `threadlight-deploy`. It runs ONLY when SPEC § 11b sets > `governance_hub.required: yes` (the SPEC field is generic; the AI > Citadel hub is one reference implementation). The base agent deploy > (Phase 5 + 6) lands in the customer's tenant first; this skill > onboards it as a hub spoke afterwards as an additive step. Read > SPEC § 11b for the per-process governance posture (hub endpoint, > access contracts, JWT requirements, secret wiring). > > **Threadlight pilots MUST use Option B (Foundry Connection)** — see > `Consuming the Gateway from Your App` below. Option A (Key Vault > secret pull) violates the keyless-by-mandate posture: it requires > the agent to hold an APIM subscription key and read it from KV at > runtime. Option B threads the call through a Foundry APIM connection > so the agent does not retrieve the subscription key. The pinned connection > uses `authType: ApiKey`; this is **not end-to-end keyless**. Caller-to-Foundry > Entra authentication, connection-managed secret custody and downstream APIM > authentication are separate boundaries. JWT requires its own approved setup > and positive/negative runtime evidence; no MI-to-APIM JWT flow is implied. > If a customer insists on > Option A for a non-threadlight reason, document the deviation in > SPEC § 11b explicitly. > **Source:** [exact hub/spoke revision](https://github.com/Azure-Samples/ai-hub-gateway-solution-accelerator/tree/63f0f812474e713916dc909494d655246783a1d9). > The [pin record](references/upstream-pin.md) separates source comparison from > live compatibility. `citadel-v1` is a freshness signal, not a deployment input. > **Quick link:** <https://aka.ms/ai-hub-gateway> --- ## Key Concepts | Term | Meaning | |------|---------| | **Citadel Governance Hub** | Central control plane with Azure API Management (APIM) acting as the unified AI gateway. Already deployed — not your concern here. | | **Spoke** | An isolated workload environment (Foundry project, Container App, Function, etc.) that consumes AI services **through** the hub gateway. | | **Access Contract** | A Bicep parameter file (`.bicepparam`) + optional policy XML declaring what AI services a spoke needs, with what policies. Deployed as IaC. | | **Foundry Connection** | An APIM-type connection inside an Azure AI Foundry project that routes model calls through the Citadel gateway. | | **Service Code** | Short acronym mapping a category of AI services to APIM API IDs (e.g. `LLM`, `DOC`, `SRCH`, `OAIRT`). | --- ## What Gets Created Per Access Contract | Resource | Naming Pattern | Description | |----------|----------------|-------------| | **APIM Product** | `{code}-{BU}-{UseCase}-{ENV}` | One per service code, with attached APIs and policies | | **APIM Subscription** | `{product}-SUB-01` | Subscription with API key | | **Key Vault Secrets** (optional) | `{secretName}` | Endpoint URL + API key stored in KV | | **Foundry Connection** (optional) | `{prefix}-{code}` | APIM connection for Foundry agents | --- ## Prerequisites (Spoke Side) | Requirement | Details | |-------------|---------| | Running Citadel Hub | APIM deployed with published APIs matching your `apiNameMapping` | | Azure CLI + Bicep | Latest version with `az deployment sub create` support | | Permissions | `API Management Service Contributor` on APIM RG, `Key Vault Secrets Officer` on target KV (if used), `Contributor` on Foundry RG (if using Foundry connections) | | Foundry Project | Must exist if you want APIM connections inside Foundry | Before any operator Azure call, apply [`azure-tenant-isolation`](../azure-tenant-isolation/SKILL.md): paired isolated CLI/AZD context and the approved exact tenant/subscription. Assert the target immediately before writes. Read-only inventory grants no repair authority. --- ## Step-by-Step: Create an Access Contract ### 1. Scaffold the Contract Folder Materialize the exact reviewed hub revision, then follow `contracts/<businessunit-usecasename>/<environment>/`. Do not overwrite an existing checkout, deployed contract or policy to align a pin. ```bash PINNED_SHA="63f0f812474e713916dc909494d655246783a1d9" git clone --filter=blob:none --no-checkout https://github.com/Azure-Samples/ai-hub-gateway-solution-accelerator.git cd ai-hub-gateway-solution-accelerator git fetch --depth 1 origin "$PINNED_SHA" git checkout --detach "$PINNED_SHA" test "$(git rev-parse HEAD)" = "$PINNED_SHA" cd bicep/infra/citadel-access-contracts # Create contract folder mkdir -p contracts/myteam-myagent/dev cd contracts/myteam-myagent/dev # Copy templates cp ../../../main.bicepparam main.bicepparam cp ../../../policies/default-ai-product-policy.xml ai-product-policy.xml ``` > 📂 Full contract folder structure and module reference: > [citadel-access-contracts/](https://github.com/Azure-Samples/ai-hub-gateway-solution-accelerator/tree/citadel-v1/bicep/infra/citadel-access-contracts) > > ⚠️ Sample contracts were removed from the repo. Use `main.bicepparam` as your template base. > Review `allowedModels` explicitly: this revision's default LLM policy allows > `gpt-4.1,gpt-5.4-mini`, unlike the older policy's broader list. Existing > approved policies are not replaced automatically. Leave optional key rotation > and additional-gateway settings disabled unless separately approved. ### 2. Configure the Parameter File Edit `main.bicepparam`: ```bicep using '../../../main.bicep' // ── Hub coordinates (get these from your platform team) ── param apim = { subscriptionId: '<HUB-SUBSCRIPTION-ID>' resourceGroupName: '<HUB-APIM-RG>' name: '<HUB-APIM-NAME>' } // ── Secret storage ── param useTargetAzureKeyVault = true // false → credentials in deployment output param keyVault = { subscriptionId: '<SPOKE-SUBSCRIPTION-ID>' resourceGroupName: '<SPOKE-KV-RG>' name: '<SPOKE-KV-NAME>' } // ── Use-case identity ── param useCase = { businessUnit: 'MyTeam' useCaseName: 'MyAgent' environment: 'DEV' // DEV | TEST | PROD } // ── Map service codes → APIM API IDs ── // ⚠️ Order matters: endpoint secret stores the gateway URL for the FIRST API. // Put the API matching your SDK first (e.g. azure-openai-api for AzureOpenAI SDK). param apiNameMapping = { LLM: ['azure-openai-api', 'universal-llm-api', 'unified-ai-api'] } // ── Services to onboard ── param services = [ { code: 'LLM' endpointSecretName: 'MYAGENT-LLM-ENDPOINT' apiKeySecretName: 'MYAGENT-LLM-KEY' policyXml: loadTextContent('ai-product-policy.xml') // '' → use default } ] // ── Foundry integration (optional) ── param useTargetFoundry = true // false if not using Foundry agents param foundry = { subscriptionId: '<FOUNDRY-SUBSCRIPTION-ID>' resourceGroupName: '<FOUNDRY-RG>' accountName: '<FOUNDRY-ACCOUNT>' projectName: '<FOUNDRY-PROJECT>' } param foundryConfig = { connectionNamePrefix: '' // empty → auto from useCase naming deploymentInPath: 'false' // model name in request body isSharedToAll: false inferenceAPIVersion: '' // empty → APIM defaults deploymentAPIVersion: '' staticModels: [] listModelsEndpoint: '' getModelEndpoint: '' deploymentProvider: '' customHeaders: {} authConfig: {} } ``` ### 3. Customise the Product Policy (Optional) The [default policy](https://github.com/Azure-Samples/ai-hub-gateway-solution-accelerator/blob/citadel-v1/bicep/infra/citadel-access-contracts/policies/default-ai-product-policy.xml) includes model restrictions, token limits, and content safety. For custom policies, edit `ai-product-policy.xml`. Full policy reference: [citadel-access-contracts-policy.md](https://github.com/Azure-Samples/ai-hub-gateway-solution-accelerator/blob/citadel-v1/bicep/infra/citadel-access-contracts/citadel-access-contracts-policy.md) **Recommended policy ordering in `<inbound>`:** ```xml <inbound> <base /> <!-- 1. JWT Authentication (optional) --> <set-variable name="jwtRequired" value="true" /> <!-- 2. App Role Authorization (optional, requires JWT) --> <set-variable name="requiredRoles" value="Models.Read" /> <!-- 3. Model extraction and access control --> <include-fragment fragment-id="set-llm-requested-model" /> <set-variable name="allowedModels" value="gpt-5.4-mini,gpt-5.4-nano" /> <include-fragment fragment-id="validate-model-access" /> <!-- 4. Capacity management (subscription level) --> <!-- ⚠️ For Foundry agents with MCP tools, use ≥100K TPM. A single CI query with 10-20 tool calls consumes 50-80K tokens. 10K TPM causes server_error after the first tool call completes. --> <llm-token-limit counter-key="@(context.Subscription.Id)" tokens-per-minute="5000" estimate-prompt-tokens="false" tokens-consumed-header-name="consumed-tokens" remaining-tokens-header-name="remaining-tokens" token-quota="100000" token-quota-period="Monthly" retry-after-header-name="retry-after" /> <!-- 5. Usage attribution (optional) --> <set-variable name="appId" value="@(context.Request.Headers.GetValueOrDefault("x-app-id", context.Subscription?.Id ?? "Portal-Admin"))" /> <set-variable name="customDimension1" value="@(context.Request.Headers.GetValueOrDefault("x-sub-agent-id", "general-agent"))" /> <set-variable name="customDimension2" value="@(context.Request.Headers.GetValueOrDefault("x-enduser-id", "anonymous-enduser"))" /> <!-- 6. PII Anonymization (optional) --> <set-variable name="piiAnonymizationEnabled" value="true" /> <!-- 7. Content Safety (optional) --> <llm-content-safety backend-id="content-safety-backend" shield-prompt="true"> <categories output-type="EightSeverityLevels"> <category name="Hate" threshold="3" /> <category name="Violence" threshold="3" /> </categories> </llm-content-safety> <!-- 8. Response debug headers (dev/test only) --> <set-variable name="enableResponseHeaders" value="@(true)" /> </inbound> ``` **Per-model capacity limits** (instead of flat subscription-level): ```xml <include-fragment fragment-id="set-llm-requested-model" /> <choose> <when condition="@((string)context.Variables["requestedModel"] == "gpt-5.4-mini")"> <llm-token-limit counter-key="@(context.Subscription.Id + "-gpt-5.4-mini")" tokens-per-minute="10000" token-quota="100000" token-quota-period="Monthly" estimate-prompt-tokens="false" /> </when> <when condition="@((string)context.Variables["requestedModel"] == "DeepSeek-R1")"> <llm-token-limit counter-key="@(context.Subscription.Id + "-DeepSeek-R1")" tokens-per-minute="2000" token-quota="10000" token-quota-period="Weekly" estimate-prompt-tokens="false" /> </when> <otherwise> <llm-token-limit counter-key="@(context.Subscription.Id + "-default")" tokens-per-minute="1000" token-quota="5000" token-quota-period="Monthly" estimate-prompt-tokens="false" /> </otherwise> </choose> ``` **Throttling alerts** (in `<on-error>` section): ```xml <on-error> <base /> <set-variable name="productName" value="@(context.Product?.Name?.ToString() ?? "Portal-Admin")" /> <set-variable name="deploymentName" value="@((string)context.Variables.GetValueOrDefault<string>("requestedModel", "DefaultModel"))" /> <set-variable name="appId" value="@((string)context.Variables.GetValueOrDefault<string>("appId", context.Subscription?.Id ?? "Portal-Admin-Sub"))" /> <include-fragment fragment-id="raise-throttling-events" /> </on-error> ``` ### 4. Validate and Deploy ```powershell # Preview (what-if) az deployment sub what-if ` --location <REGION> ` --template-file ../../../main.bicep ` --parameters main.bicepparam # Deploy az deployment sub create `
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen