Microsoft Copilot Studio + AxonFlow Integration
Overview
Microsoft Copilot Studio is Microsoft's enterprise AI agent platform for building, customizing, and deploying agents that connect to Microsoft 365, Power Platform, and 1,400+ systems. It supports multi-agent orchestration, GPT-4 family models, and integrates with Microsoft Entra ID for governance.
AxonFlow adds real-time policy enforcement, cross-system audit trails, and fine-grained access control to ensure Copilot Studio agents operate within enterprise compliance requirements.
Together, they enable enterprises to deploy AI agents across Microsoft 365 with full governance, observability, and cost control.
Why Use AxonFlow with Copilot Studio?
Copilot Studio Strengths
- Native Microsoft 365 integration (Teams, Outlook, SharePoint)
- Multi-agent orchestration capabilities
- 1,400+ Power Platform and MCP connectors
- GPT-4 family model support
- Microsoft Entra ID authentication
- WhatsApp, web, and custom channel deployment
AxonFlow Strengths
- Real-time inference governance (block/allow/modify at request time)
- Cross-platform audit trails (unified logging across all AI systems)
- Granular policy enforcement (per-agent, per-user, per-department)
- Cost control and allocation (budget limits, chargeback tracking)
- PII protection (automatic masking before model inference)
- Model-agnostic governance (works with any LLM provider)
The Perfect Combination
Copilot Studio handles: Agent building, Microsoft 365 integration, Power Platform connectors
AxonFlow handles: Inference governance, compliance audit, cost control, policy enforcement
Integration Architecture
AxonFlow integrates with Copilot Studio using Gateway Mode, which provides policy pre-checks before LLM calls and audit logging after:
[Copilot Studio Agent]
|
v
[Power Automate Flow]
|
v
[AxonFlow Pre-Check] --> Policy Evaluation
|
v (if approved)
[Azure OpenAI / External LLM]
|
v
[AxonFlow Audit] --> Compliance Logging
|
v
[Response to Copilot Studio]
Note: AxonFlow uses its own API for governance, not an OpenAI-compatible endpoint. Integration requires calling AxonFlow's pre-check and audit endpoints around your LLM calls.
Quick Start
Prerequisites
- Microsoft Copilot Studio license
- AxonFlow running locally or deployed (see Getting Started)
- Azure subscription (for Azure OpenAI)
- Power Platform admin access
AxonFlow API Overview
AxonFlow Gateway Mode uses two main endpoints:
| Endpoint | Purpose |
|---|---|
POST /api/policy/pre-check | Policy evaluation before LLM call |
POST /api/audit/llm-call | Audit logging after LLM call completes |
Required Headers:
Content-Type: application/jsonX-Client-Secret: your-client-secretX-License-Key: your-license-key(optional, for enterprise features)
Integration Pattern: Power Automate Flow
Create a Power Automate cloud flow that wraps Azure OpenAI calls with AxonFlow governance:
Step 1: Create the Governance Flow
Flow Name: AxonFlow-Governed-LLM-Call
Trigger: When a HTTP request is received
Actions:
1. Pre-Check with AxonFlow
2. If approved → Call Azure OpenAI
3. Audit the call with AxonFlow
4. Return response
Step 2: Pre-Check Action (HTTP)
{
"method": "POST",
"uri": "https://your-axonflow.example.com/api/policy/pre-check",
"headers": {
"Content-Type": "application/json",
"X-Client-Secret": "@{parameters('AxonFlowClientSecret')}"
},
"body": {
"user_token": "@{triggerBody()?['user_token']}",
"client_id": "copilot-studio-@{triggerBody()?['agent_id']}",
"query": "@{triggerBody()?['user_message']}",
"data_sources": [],
"context": {
"department": "@{outputs('GetUserProfile')?['department']}",
"agent_type": "copilot-studio"
}
}
}
Step 3: Condition - Check Approval
Condition: body('PreCheckAxonFlow')?['approved'] is equal to true
If Yes:
→ Proceed to Azure OpenAI call
If No:
→ Return blocked message
Step 4: Call Azure OpenAI (HTTP)
{
"method": "POST",
"uri": "https://your-aoai.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-15-preview",
"headers": {
"Content-Type": "application/json",
"api-key": "@{parameters('AzureOpenAIKey')}"
},
"body": {
"messages": [
{
"role": "system",
"content": "@{triggerBody()?['system_prompt']}"
},
{
"role": "user",
"content": "@{triggerBody()?['user_message']}"
}
]
}
}
Step 5: Audit Action (HTTP)
{
"method": "POST",
"uri": "https://your-axonflow.example.com/api/audit/llm-call",
"headers": {
"Content-Type": "application/json",
"X-Client-Secret": "@{parameters('AxonFlowClientSecret')}"
},
"body": {
"context_id": "@{body('PreCheckAxonFlow')?['context_id']}",
"client_id": "copilot-studio-@{triggerBody()?['agent_id']}",
"response_summary": "@{substring(body('CallAzureOpenAI')?['choices'][0]?['message']?['content'], 0, 200)}",
"provider": "azure-openai",
"model": "gpt-4",
"token_usage": {
"prompt_tokens": "@{body('CallAzureOpenAI')?['usage']?['prompt_tokens']}",
"completion_tokens": "@{body('CallAzureOpenAI')?['usage']?['completion_tokens']}",
"total_tokens": "@{body('CallAzureOpenAI')?['usage']?['total_tokens']}"
},
"latency_ms": "@{div(sub(ticks(utcNow()), ticks(outputs('PreCheckAxonFlow')?['headers']?['Date'])), 10000)}"
}
}
Step 6: Return Response
{
"statusCode": 200,
"body": {
"response": "@{body('CallAzureOpenAI')?['choices'][0]?['message']?['content']}",
"governed": true,
"context_id": "@{body('PreCheckAxonFlow')?['context_id']}"
}
}
Configure Copilot Studio Agent
In Copilot Studio, create an action that calls the Power Automate flow:
- Open your agent in Copilot Studio
- Go to Actions > Add an action
- Select Call a Power Automate flow
- Choose the
AxonFlow-Governed-LLM-Callflow - Map inputs:
user_token: User identifier from conversationagent_id: Current agent IDuser_message: User's inputsystem_prompt: Agent's system instructions
- Map outputs: Response text
Integration Patterns
Pattern 1: Per-Department Policy Routing
Route different Copilot Studio agents through department-specific AxonFlow contexts:
{
"context": {
"department": "@{if(contains(triggerBody()?['agent_name'], 'HR'), 'hr', if(contains(triggerBody()?['agent_name'], 'Finance'), 'finance', if(contains(triggerBody()?['agent_name'], 'Sales'), 'sales', 'default')))}",
"data_tier": "@{if(equals(outputs('GetDepartment'), 'finance'), 'restricted', if(equals(outputs('GetDepartment'), 'hr'), 'sensitive', 'standard'))}"
}
}
Pattern 2: Microsoft 365 Context Enrichment
Enrich AxonFlow requests with Microsoft 365 context using Office 365 connector:
Actions in Power Automate:
1. Office365Users.GetMyProfile
2. Office365Groups.ListGroupsUserBelongsTo
3. Build context for AxonFlow
Pre-check body with enriched context:
{
"user_token": "@{outputs('GetMyProfile')?['id']}",
"client_id": "copilot-studio-@{triggerBody()?['agent_id']}",
"query": "@{triggerBody()?['user_message']}",
"context": {
"user_email": "@{outputs('GetMyProfile')?['mail']}",
"user_department": "@{outputs('GetMyProfile')?['department']}",
"user_title": "@{outputs('GetMyProfile')?['jobTitle']}",
"user_groups": "@{join(outputs('ListGroups')?['value'], ',')}",
"tenant_id": "@{outputs('GetMyProfile')?['tenantId']}"
}
}
Pattern 3: Error Handling with Fallback
Handle AxonFlow unavailability gracefully:
Scope: TryGovernedCall
Actions:
- PreCheckAxonFlow
- CallAzureOpenAI
- AuditAxonFlow
Configure Run After for Scope:
- If TryGovernedCall Failed or TimedOut:
→ DirectAzureOpenAICall (fallback without governance)
→ Log to Application Insights (governance bypassed)
Pattern 4: Multi-Agent Orchestration
When using Copilot Studio's multi-agent features, pass orchestration context:
{
"context": {
"orchestrator_id": "@{triggerBody()?['orchestrator_id']}",
"sub_agent_id": "@{triggerBody()?['sub_agent_id']}",
"conversation_id": "@{triggerBody()?['conversation_id']}",
"agent_chain": "@{triggerBody()?['agent_chain']}"
}
}
AxonFlow Policy Configuration
Create policies that match your Copilot Studio agent types. Register these in AxonFlow:
{
"policies": [
{
"name": "copilot-studio-hr-policy",
"description": "Policy for Copilot Studio HR agents",
"enabled": true,
"rules": [
{
"type": "content_filter",
"config": {
"blocked_patterns": ["salary details", "performance reviews"],
"action": "block"
}
},
{
"type": "pii_protection",
"config": {
"fields": ["ssn", "salary", "address"],
"action": "mask"
}
}
]
},
{
"name": "copilot-studio-sales-policy",
"description": "Policy for Copilot Studio Sales agents",
"enabled": true,
"rules": [
{
"type": "rate_limit",
"config": {
"requests_per_minute": 60,
"action": "throttle"
}
}
]
}
]
}
Best Practices
1. Always Store Context ID
The context_id from pre-check must be passed to audit for proper correlation:
Variable: ContextId = body('PreCheckAxonFlow')?['context_id']
... make LLM call ...
Audit body: { "context_id": "@{variables('ContextId')}", ... }
2. Handle Blocked Requests Gracefully
If: body('PreCheckAxonFlow')?['approved'] equals false
Then:
Response: {
"message": "I'm unable to help with that request due to policy restrictions.",
"reason": "@{body('PreCheckAxonFlow')?['block_reason']}"
}
3. Always Audit, Even on Errors
Scope: TryLLMCall
Action: CallAzureOpenAI
Configure Run After:
AuditSuccess (if TryLLMCall succeeded)
AuditFailure (if TryLLMCall failed) - audit with error message
4. Agent Naming Convention
Use consistent naming for governance and audit clarity:
copilot-studio-{department}-{function}-{environment}
Examples:
- copilot-studio-hr-onboarding-prod
- copilot-studio-sales-research-dev
- copilot-studio-support-tier1-prod
Monitoring with Azure
Azure Monitor Integration
Send AxonFlow events to Azure Monitor via Power Automate:
After each governed call:
Action: Send Data to Azure Log Analytics
Body: {
"context_id": "@{body('PreCheckAxonFlow')?['context_id']}",
"client_id": "copilot-studio-...",
"approved": "@{body('PreCheckAxonFlow')?['approved']}",
"latency_ms": "...",
"timestamp": "@{utcNow()}"
}
Power BI Dashboard Query
-- KQL query for Azure Log Analytics
CustomLogs_CL
| where Category == "AxonFlowGovernance"
| where ClientId_s startswith "copilot-studio"
| summarize
TotalRequests = count(),
BlockedRequests = countif(Approved_b == false),
AvgLatencyMs = avg(LatencyMs_d)
by bin(TimeGenerated, 1h), Department_s
| order by TimeGenerated desc
Troubleshooting
Common Issues
Issue: Pre-check returns 401 Unauthorized
- Verify
X-Client-Secretheader is correct - Check
X-License-Keyif using enterprise features - Ensure client_id is registered in AxonFlow
Issue: Audit calls failing
- Verify context_id is from a valid pre-check (not expired)
- Check that AxonFlow agent is healthy (
/healthendpoint)
Issue: All requests being blocked
- Review policy configuration in AxonFlow
- Check if rate limits are exceeded
- Verify context fields match policy conditions
Issue: Power Automate flow timing out
- Increase timeout in HTTP actions (default 100s)
- Check AxonFlow gateway health endpoint
- Verify network connectivity from Power Platform