Skip to content
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,8 @@ htmlcov/
*.egg-info/
dist/
build/

# Local diagnostics and code review artifacts (never commit)
diagnostics/
.codereviews/
nul
31 changes: 31 additions & 0 deletions Readme-Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ a365 config init -c path/to/config.json
a365 config init --global
```

**Configure custom blueprint permissions:**
```bash
# Add custom API permissions for your agent
a365 config permissions --resource-app-id 00000003-0000-0000-c000-000000000000 \
--scopes Presence.ReadWrite,Files.Read.All

# View configured permissions
a365 config permissions

# Clear all custom permissions
a365 config permissions --reset
```

**Minimum required configuration:**
```json
{
Expand Down Expand Up @@ -122,9 +135,27 @@ a365 setup infrastructure
a365 setup blueprint
a365 setup permissions mcp
a365 setup permissions bot
a365 setup permissions custom # Configure custom blueprint permissions (if configured)
a365 setup permissions copilotstudio # Configure Copilot Studio permissions
```

**Custom Blueprint Permissions:**
If your agent needs additional API permissions beyond the standard set (e.g., Presence, Files, Chat, or custom APIs), configure them before running setup:

```bash
# Add custom permissions to config
a365 config permissions --resource-app-id 00000003-0000-0000-c000-000000000000 \
--scopes Presence.ReadWrite,Files.Read.All

# Then run setup (custom permissions applied automatically)
a365 setup all

# Or apply custom permissions separately
a365 setup permissions custom
```

See [Custom Permissions Guide](docs/commands/setup-permissions-custom.md) for detailed examples.

### Publish & Deploy
```bash
a365 publish # Publish manifest to MOS
Expand Down
119 changes: 116 additions & 3 deletions docs/ai-workflows/integration-test-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,35 @@ a365 config init --global
# Record: Global config created (Yes/No)
```

**Section 2 Status**: ✅ Pass | ❌ Fail
#### Test 2.5: Configure Custom Blueprint Permissions
```bash
# Add Microsoft Graph extended permissions
a365 config permissions \
--resource-app-id 00000003-0000-0000-c000-000000000000 \
--scopes Presence.ReadWrite,Files.Read.All

# Expected: NO PROMPTS - permission added directly to a365.config.json
# Resource name will be auto-resolved during 'a365 setup permissions custom'
# Verify customBlueprintPermissions array exists in config file
# Record: Custom permission added (Yes/No)

# View configured permissions
a365 config permissions

# Expected: Lists all configured custom permissions (may show appId only until setup runs)
# Record: Permissions displayed correctly (Yes/No)

# Add second custom resource
a365 config permissions \
--resource-app-id 12345678-1234-1234-1234-123456789012 \
--scopes CustomScope.Read,CustomScope.Write

# Expected: NO PROMPTS - second permission added directly
# Resource names will be auto-resolved during setup
# Record: Second permission added (Yes/No)
```

**Section 2 Status**: ✅ Pass | ❌ Fail
**Notes**:

---
Expand Down Expand Up @@ -284,7 +312,84 @@ a365 setup permissions bot
# Record: Bot permissions set (Yes/No)
```

**Section 4 Status**: ✅ Pass | ❌ Fail
#### Test 4.5: Blueprint Permissions - Custom Resources (with Auto-Lookup)
```bash
# Configure custom permissions (requires Test 2.5 completed)
a365 setup permissions custom

# Expected:
# - AUTO-LOOKUP: CLI queries Azure to resolve resource display names
# - Output shows: "Resource name not provided, attempting auto-lookup for {appId}..."
# - Output shows: "Auto-resolved resource name: Microsoft Graph" (or similar)
# - OAuth2 grants created for each custom resource
# - Inheritable permissions configured
# - Permissions visible in Azure Portal under API permissions
# - Success messages for each configured resource
# - Note: ResourceName is resolved in-memory for logging only; it is NOT persisted to any config file

# IMPORTANT: Verify auto-lookup messages appear in output
# If resource not found in Azure, should show fallback: "Custom-{first 8 chars}"

# Record: Custom permissions configured (Yes/No)
# Record: Number of custom resources configured
# Record: Auto-lookup succeeded (Yes/No)
```

#### Test 4.6: Verify Custom Permissions in Azure Portal
```bash
# Query blueprint application to verify custom permissions
az ad app show --id <blueprint-app-id> --query "requiredResourceAccess[].{ResourceAppId:resourceAppId, Scopes:resourceAccess[].id}"

# Expected: Shows custom resource permissions configured
# - Microsoft Graph (00000003-0000-0000-c000-000000000000) with extended scopes
# - Custom API resource (if configured)

# Alternatively, verify in Azure Portal:
# Navigate to: Entra ID → Applications → [Blueprint App] → API permissions
# Verify custom permissions are listed with "Granted" status

# Record: Custom permissions visible in portal (Yes/No)
```

#### Test 4.7: Verify Inheritable Permissions via Graph API
```powershell
# Get blueprint object ID from config
$blueprintObjectId = (Get-Content a365.generated.config.json | ConvertFrom-Json).agentBlueprintObjectId

# Get access token
$token = az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv

# Query inheritable permissions (this is what the CLI verifies internally)
$headers = @{ Authorization = "Bearer $token" }
$uri = "https://graph.microsoft.com/beta/applications/microsoft.graph.agentIdentityBlueprint/$blueprintObjectId/inheritablePermissions"
$response = Invoke-RestMethod -Uri $uri -Headers $headers
$response | ConvertTo-Json -Depth 10

# Expected response format:
# {
# "value": [
# {
# "resourceAppId": "00000003-0000-0000-c000-000000000000",
# "resourceName": "Microsoft Graph",
# "scopes": ["Presence.ReadWrite", "Files.Read.All"]
# }
# ]
# }

# Verify:
# - Each custom resource appears in the "value" array
# - resourceAppId matches configured permissions
# - resourceName is populated (auto-resolved during setup)
# - All requested scopes are present

# Note: This is the SAME endpoint the CLI uses to verify permissions were set correctly
# If this query succeeds, inheritable permissions are working properly

# Record: Inheritable permissions verified via Graph API (Yes/No)
# Record: Number of resources found in response
```

**Section 4 Status**: ✅ Pass | ❌ Fail
**Notes**:

---
Expand All @@ -306,10 +411,18 @@ a365 setup all
# Expected:
# - Infrastructure created
# - Blueprint created
# - Permissions configured
# - MCP permissions configured
# - Bot API permissions configured
# - Custom blueprint permissions configured (if present in config)
# - Messaging endpoint registered
# - All steps completed successfully

# Verify custom permissions were configured (if Test 2.5 was completed):
# - Check output for "Configuring custom blueprint permissions..."
# - Verify each custom resource shows "configured successfully"

# Record: Setup all completed (Yes/No)
# Record: Custom permissions included (Yes/No/N/A)
# Record: Time taken (approximate)
```

Expand Down
31 changes: 28 additions & 3 deletions docs/commands/config-init.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,31 @@ Azure location [westus]:

**Smart Defaults**: Uses location from existing config or Azure account

### Step 9: Configuration Summary
### Step 9: Custom Blueprint Permissions (Optional)

Optionally configure custom resource permissions for your agent:

```
=== Optional: Custom Blueprint Permissions ===
If your agent needs access to additional external resources
(e.g. Teams presence, OneDrive files, custom APIs) beyond
standard permissions, you can configure them here.
Most agents do not require this.

Configure custom blueprint permissions? (y/N): y

Resource App ID (GUID) - press Enter when done: 00000003-0000-0000-c000-000000000000
Scopes (comma-separated, e.g. Presence.ReadWrite,Files.Read.All): Presence.ReadWrite,Files.Read.All
Permission added.

Resource App ID (GUID) - press Enter when done:
```

Press **Enter** with no input to finish and proceed.

> **Tip**: You can also add or update permissions after initial setup using `a365 config permissions`.

### Step 10: Configuration Summary

Review all settings before saving:

Expand All @@ -212,11 +236,12 @@ App Service Plan : a365agent-app-plan
Location : westus
Subscription : My Subscription (e09e22f2-9193-4f54-a335-01f59575eefd)
Tenant : adfa4542-3e1e-46f5-9c70-3df0b15b3f6c
Custom Permissions : 1 configured

Do you want to customize any derived names? (y/N):
```

### Step 10: Name Customization (Optional)
### Step 11: Name Customization (Optional)

Optionally customize generated names:

Expand All @@ -230,7 +255,7 @@ Agent User Principal Name [agent.myagent.11140916@yourdomain.onmicrosoft.com]:
Agent User Display Name [myagent Agent User]:
```

### Step 11: Confirmation
### Step 12: Confirmation

Final confirmation to save:

Expand Down
Loading
Loading