Patterns for Microsoft Graph, Microsoft Entra ID, and enterprise feature integration in VS Code extensions
Scanned 9/3/2026
Install to Claude Code
npx -y skills add fabioc-aloha/Alex_Skill_Mall --skill enterprise-integration --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Enterprise Integration?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/fabioc-aloha-enterprise-integration)More formats (shields.io, HTML) on the badges page.
---
name: enterprise-integration
description: "Patterns for Microsoft Graph, Microsoft Entra ID, and enterprise feature integration in VS Code extensions"
lastReviewed: 2026-04-30
---
# Enterprise Integration Skill
Expert in building enterprise features with Microsoft Graph API, Microsoft Entra ID authentication, and enterprise-mode feature gating for VS Code extensions.
## ⚠️ Staleness Warning
Microsoft Graph and Microsoft Entra ID APIs evolve frequently. Authentication flows and permission models change.
See `EXTERNAL-API-REGISTRY.md` for source URLs and recheck cadence.
**Refresh triggers:**
- Microsoft Graph API version updates
- MSAL library major releases
- Microsoft Entra ID rebranded to Microsoft Entra ID
- New Graph scopes or permissions
**Last validated:** February 2026 (MSAL 2.x, Graph v1.0)
**Check current state:** [Microsoft Graph docs](https://learn.microsoft.com/en-us/graph/api/overview), [MSAL.js docs](https://github.com/AzureAD/microsoft-authentication-library-for-js)
---
## Microsoft Graph Integration Pattern
### Authentication Flow
```typescript
// Progressive scope acquisition - request minimal scopes initially
const INITIAL_SCOPES = ['User.Read'];
const GRAPH_SCOPES = [
'User.Read',
'Calendars.Read',
'Mail.Read',
'Presence.Read',
'People.Read'
];
// Get token with automatic scope upgrade
async function getGraphToken(): Promise<string | null> {
const session = await vscode.authentication.getSession(
'microsoft',
GRAPH_SCOPES,
{ createIfNone: false }
);
return session?.accessToken ?? null;
}
// Check availability without triggering auth prompt
function isGraphAvailable(): boolean {
return !!cachedToken && isEnterpriseMode();
}
```
### API Client Pattern
```typescript
const GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0';
async function graphFetch<T>(path: string): Promise<T | null> {
const token = await getGraphToken();
if (!token) return null;
const response = await fetch(`${GRAPH_ENDPOINT}${path}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
console.error(`Graph API error: ${response.status}`);
return null;
}
return response.json();
}
```
### Feature-Specific Endpoints
| Feature | Endpoint | Scope Required |
|---------|----------|----------------|
| Calendar | `/me/calendar/events` | `Calendars.Read` |
| Mail | `/me/messages` | `Mail.Read` |
| Presence | `/me/presence` | `Presence.Read` |
| People | `/me/people` | `People.Read` |
| User Profile | `/me` | `User.Read` |
---
## Enterprise Feature Gating
### Setting-Based Gating
```typescript
// Check enterprise mode is enabled
function isEnterpriseMode(): boolean {
const config = vscode.workspace.getConfiguration('alex.enterprise');
return config.get<boolean>('enabled', false);
}
// Check specific feature is enabled
function isCalendarEnabled(): boolean {
if (!isEnterpriseMode()) return false;
const config = vscode.workspace.getConfiguration('alex.enterprise.graph');
return config.get<boolean>('calendarEnabled', true);
}
```
### Conditional UI Elements
```typescript
// In WebviewView provider
private getHtmlContent(): string {
const showEnterprise = isEnterpriseMode();
const graphConnected = isGraphAvailable();
return `
${showEnterprise ? `
<section class="enterprise">
<h3>Enterprise</h3>
${graphConnected
? this.getGraphButtons()
: this.getSignInButton()}
</section>
` : ''}
`;
}
```
### Command Conditional Display
```json
{
"commands": [
{
"name": "calendar",
"description": "View upcoming calendar events",
"when": "config.alex.enterprise.enabled"
}
]
}
```
---
## Settings Organization Pattern
Enterprise settings should be hierarchically organized:
```json
{
"alex.enterprise.enabled": {
"type": "boolean",
"default": false,
"description": "Master toggle for enterprise features"
},
"alex.enterprise.graph.enabled": {
"type": "boolean",
"default": true,
"description": "Enable Microsoft Graph integration"
},
"alex.enterprise.graph.calendarEnabled": {
"type": "boolean",
"default": true,
"description": "Feature-specific toggle"
},
"alex.enterprise.graph.calendarDaysAhead": {
"type": "number",
"default": 7,
"minimum": 1,
"maximum": 30,
"description": "Feature-specific configuration"
}
}
```
**Hierarchy**: `extension.area.feature.setting`
---
## Chat Command Handler Pattern
```typescript
interface IAlexChatResult extends vscode.ChatResult {
metadata?: {
command?: string;
// Command-specific metadata
eventCount?: number;
messageCount?: number;
error?: boolean;
};
}
async function handleCalendarCommand(
request: vscode.ChatRequest,
stream: vscode.ChatResponseStream,
token: vscode.CancellationToken
): Promise<IAlexChatResult> {
// Check prerequisites
if (!isEnterpriseMode()) {
stream.markdown('Enterprise mode is not enabled.');
return { metadata: { command: 'calendar', error: true } };
}
if (!isGraphAvailable()) {
stream.markdown('Please sign in to Microsoft Graph first.');
return { metadata: { command: 'calendar', error: true } };
}
// Execute feature logic
const events = await getCalendarEvents();
stream.markdown(formatCalendarEvents(events));
return {
metadata: {
command: 'calendar',
eventCount: events.length
}
};
}
```
---
## Example Usage
- "How do I add Microsoft Graph authentication?"
- "Show me the enterprise feature gating pattern"
- "What scopes do I need for calendar access?"
- "How do I organize enterprise settings?"
## Related Skills
- `VS Code Extension Patterns` - General extension patterns
- `API Design` - API client patterns
- `Security Review` - Auth security considerations
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!