microsoft
This skill emulates Microsoft Entra ID (Azure AD) OAuth 2.0 and OpenID Connect locally, supporting authorization code flow, PKCE, client credentials, and…
Identity proven by GitHub's verified organisation badge (vercel, vercel-labs)
- Agents
- Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, claude.ai and API
- License
- Apache-2.0 (permissive)
- Pin
- c77cb73pinned Oct 9, 2026
- Context cost
- about 2,900 tokenswhen the skill loads
- GitHub stars
- 1,880on vercel-labs/emulate
- Scripts
- None found
What it does
“Emulated Microsoft Entra ID (Azure AD) OAuth 2.0 / OpenID Connect for local development and testing. Use when the user needs to test Microsoft sign-in locally, emulate Entra ID OIDC discovery, handle Microsoft token exchange, configure Azure AD OAuth clients, work with Microsoft Graph /me, or test PKCE/client credentials flows without hitting real Microsoft APIs. Triggers include "Microsoft OAuth", "Entra ID", "Azure AD", "emulate Microsoft", "mock Microsoft login", "test Microsoft sign-in", "Microsoft OIDC", "local Microsoft auth", or any task requiring a local Microsoft OAuth/OIDC provider.”
Generated summary from the skill's own text
This skill emulates Microsoft Entra ID (Azure AD) OAuth 2.0 and OpenID Connect locally, supporting authorization code flow, PKCE, client credentials, and token refresh. It provides a complete Microsoft authentication provider for development and testing without hitting real Microsoft APIs, including OIDC discovery, ID token signing, Microsoft Graph endpoints, and user seeding.
When to use it
- Testing Microsoft OAuth sign-in flows locally during development
- Mocking Entra ID OIDC discovery for automated tests
- Validating authorization code and PKCE implementations
- Developing apps with Auth.js, Passport.js, or MSAL without production credentials
When not to
- Production environments or real user authentication
- Applications that require actual Microsoft account data or permissions
- When real Azure AD integration is already available
Install
These commands install from the publisher's repository and need no account.
skills CLI
npx skills add vercel-labs/emulate --skill microsoftInstalls from the repository's default branch, which may have changed since the commit we checked.
GitHub CLI 2.90 or later
gh skill install vercel-labs/emulate microsoft@c77cb73e7ab525c5260dd36c04c91a54a23e7e75Installs the commit we checked (c77cb73).
Copy by hand
Download the folder at c77cb73 and put it in .claude/skills/microsoft for Claude Code and in .agents/skills/microsoft for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
Claude Code plugin
/plugin install vercel@claude-plugins-officialThe publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.
Copy for your agent
A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.
Prompt
Install the agent skill "microsoft" by Vercel. Source, pinned to commit c77cb73e7ab525c5260dd36c04c91a54a23e7e75: https://github.com/vercel-labs/emulate/tree/c77cb73e7ab525c5260dd36c04c91a54a23e7e75/skills/microsoft 1. Download that folder at exactly this commit. Do not use the default branch. 2. Copy every file unchanged, keeping the folder structure, into .claude/skills/microsoft/ for Claude Code and .agents/skills/microsoft/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist. 3. Do not edit the files, and do not run any script in the folder unless I ask you to. 4. When you are done, list the files you copied and where you put them. Listing and checks: https://www.agentnative.dev/skills/vercel/microsoft
SKILL.md at the pin
---
name: microsoft
description: Emulated Microsoft Entra ID (Azure AD) OAuth 2.0 / OpenID Connect for local development and testing. Use when the user needs to test Microsoft sign-in locally, emulate Entra ID OIDC discovery, handle Microsoft token exchange, configure Azure AD OAuth clients, work with Microsoft Graph /me, or test PKCE/client credentials flows without hitting real Microsoft APIs. Triggers include "Microsoft OAuth", "Entra ID", "Azure AD", "emulate Microsoft", "mock Microsoft login", "test Microsoft sign-in", "Microsoft OIDC", "local Microsoft auth", or any task requiring a local Microsoft OAuth/OIDC provider.
allowed-tools: Bash(npx emulate:*), Bash(curl:*)
---
# Microsoft Entra ID Emulator
Microsoft Entra ID (Azure AD) v2.0 OAuth 2.0 and OpenID Connect emulation with authorization code flow, PKCE, client credentials, RS256 ID tokens, OIDC discovery, and a Microsoft Graph `/v1.0/me` endpoint.
## Start
Local listeners bind to `127.0.0.1` by default. For access from containers or other machines, pass `--host 0.0.0.0` to the CLI or `hostname: '0.0.0.0'` to `createEmulator`. Configure `--base-url` or `baseUrl` for advertised URLs reachable by those clients.
```bash
# Microsoft only
npx emulate --service microsoft
# Default port (when run alone)
# http://localhost:4000
```
Or programmatically:
```typescript
import { createEmulator } from 'emulate'
const microsoft = await createEmulator({ service: 'microsoft', port: 4005 })
// microsoft.url === 'http://localhost:4005'
```
## Pointing Your App at the Emulator
### Environment Variable
```bash
MICROSOFT_EMULATOR_URL=http://localhost:4005
```
### OAuth URL Mapping
| Real Microsoft URL | Emulator URL |
|--------------------|-------------|
| `https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration` | `$MICROSOFT_EMULATOR_URL/{tenant}/v2.0/.well-known/openid-configuration` |
| `https://login.microsoftonline.com/.well-known/openid-configuration` | `$MICROSOFT_EMULATOR_URL/.well-known/openid-configuration` |
| `https://login.microsoftonline.com/common/oauth2/v2.0/authorize` | `$MICROSOFT_EMULATOR_URL/oauth2/v2.0/authorize` |
| `https://login.microsoftonline.com/common/oauth2/v2.0/token` | `$MICROSOFT_EMULATOR_URL/oauth2/v2.0/token` |
| `https://login.microsoftonline.com/common/discovery/v2.0/keys` | `$MICROSOFT_EMULATOR_URL/discovery/v2.0/keys` |
| `https://graph.microsoft.com/oidc/userinfo` | `$MICROSOFT_EMULATOR_URL/oidc/userinfo` |
| `https://graph.microsoft.com/v1.0/me` | `$MICROSOFT_EMULATOR_URL/v1.0/me` |
### Auth.js / NextAuth.js
```typescript
import MicrosoftEntraId from '@auth/core/providers/microsoft-entra-id'
MicrosoftEntraId({
clientId: process.env.MICROSOFT_CLIENT_ID,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
authorization: {
url: `${process.env.MICROSOFT_EMULATOR_URL}/oauth2/v2.0/authorize`,
params: { scope: 'openid email profile User.Read' },
},
token: {
url: `${process.env.MICROSOFT_EMULATOR_URL}/oauth2/v2.0/token`,
},
userinfo: {
url: `${process.env.MICROSOFT_EMULATOR_URL}/oidc/userinfo`,
},
issuer: process.env.MICROSOFT_EMULATOR_URL,
})
```
### Passport.js
```typescript
import { OIDCStrategy } from 'passport-azure-ad'
const MICROSOFT_URL = process.env.MICROSOFT_EMULATOR_URL ?? 'https://login.microsoftonline.com'
new OIDCStrategy({
identityMetadata: `${MICROSOFT_URL}/.well-known/openid-configuration`,
clientID: process.env.MICROSOFT_CLIENT_ID,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
redirectUrl: 'http://localhost:3000/api/auth/callback/microsoft-entra-id',
responseType: 'code',
responseMode: 'query',
scope: ['openid', 'email', 'profile'],
}, verifyCallback)
```
### MSAL.js
```typescript
import { ConfidentialClientApplication } from '@azure/msal-node'
const msalConfig = {
auth: {
clientId: process.env.MICROSOFT_CLIENT_ID,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
authority: process.env.MICROSOFT_EMULATOR_URL,
knownAuthorities: [process.env.MICROSOFT_EMULATOR_URL],
},
}
const cca = new ConfidentialClientApplication(msalConfig)
```
## Seed Config
```yaml
microsoft:
users:
- email: testuser@outlook.com
name: Test User
given_name: Test
family_name: User
tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad
oauth_clients:
- client_id: example-client-id
client_secret: example-client-secret
name: My Microsoft App
redirect_uris:
- http://localhost:3000/api/auth/callback/microsoft-entra-id
tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad
```
When no OAuth clients are configured, the emulator accepts any `client_id`. With clients configured, strict validation is enforced for `client_id`, `client_secret`, and `redirect_uri`.
## API Endpoints
### OIDC Discovery
```bash
# Default tenant
curl http://localhost:4005/.well-known/openid-configuration
# Tenant-scoped (common, organizations, consumers, or specific tenant ID)
curl http://localhost:4005/common/v2.0/.well-known/openid-configuration
```
Returns the standard OIDC discovery document:
```json
{
"issuer": "http://localhost:4005/{tenant}/v2.0",
"authorization_endpoint": "http://localhost:4005/oauth2/v2.0/authorize",
"token_endpoint": "http://localhost:4005/oauth2/v2.0/token",
"userinfo_endpoint": "http://localhost:4005/oidc/userinfo",
"end_session_endpoint": "http://localhost:4005/oauth2/v2.0/logout",
"jwks_uri": "http://localhost:4005/discovery/v2.0/keys",
"response_types_supported": ["code"],
"subject_types_supported": ["pairwise"],
"id_token_signing_alg_values_supported": ["RS256"],
"scopes_supported": ["openid", "email", "profile", "User.Read", "offline_access"],
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"]
}
```
### JWKS
```bash
curl http://localhost:4005/discovery/v2.0/keys
```
Returns an RSA public key (`kid`: `emulate-microsoft-1`) for verifying `id_token` signatures.
### Authorization
```bash
# Browser flow: redirects to a user picker page
curl -v "http://localhost:4005/oauth2/v2.0/authorize?\
client_id=example-client-id&\
redirect_uri=http://localhost:3000/api/auth/callback/microsoft-entra-id&\
scope=openid+email+profile&\
response_type=code&\
state=random-state&\
nonce=random-nonce"
```
Query parameters:
| Param | Description |
|-------|-------------|
| `client_id` | OAuth client ID |
| `redirect_uri` | Callback URL |
| `scope` | Space-separated scopes (`openid email profile User.Read`) |
| `state` | Opaque state for CSRF protection |
| `nonce` | Nonce for ID token (optional) |
| `response_mode` | `query` (default) or `form_post` |
| `code_challenge` | PKCE challenge (optional) |
| `code_challenge_method` | `plain` or `S256` (optional) |
### Token Exchange
```bash
curl -X POST http://localhost:4005/oauth2/v2.0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=<authorization_code>&\
client_id=example-client-id&\
client_secret=example-client-secret&\
redirect_uri=http://localhost:3000/api/auth/callback/microsoft-entra-id&\
grant_type=authorization_code"
```
Returns:
```json
{
"access_token": "microsoft_...",
"refresh_token": "r_microsoft_...",
"id_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid email profile"
}
```
The `id_token` is an RS256 JWT containing `sub`, `oid`, `tid` (tenant ID), `email`, `name`, `preferred_username`, `ver` ("2.0"), and optional `nonce`.
For PKCE, include `code_verifier` in the token request.
Supports `Authorization: Basic` header with base64-encoded `client_id:client_secret` as an alternative to body parameters.
### Client Credentials
```bash
curl -X POST http://localhost:4005/oauth2/v2.0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=example-client-id&\
client_secret=example-client-secret&\
grant_type=client_credentials&\
scope=https://graph.microsoft.com/.default"
```
Returns an `access_token` only (no `refresh_token` or `id_token`).
### Refresh Token
```bash
curl -X POST http://localhost:4005/oauth2/v2.0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "refresh_token=r_microsoft_...&\
client_id=example-client-id&\
client_secret=example-client-secret&\
grant_type=refresh_token"
```
Returns a new `access_token`, rotated `refresh_token`, and new `id_token`. The presenting `client_id` and `client_secret` must belong to the client that received the refresh token. Legacy refresh records without a stored client binding remain supported.
### User Info
```bash
curl http://localhost:4005/oidc/userinfo \
-H "Authorization: Bearer microsoft_..."
```
Returns:
```json
{
"sub": "<oid>",
"email": "testuser@outlook.com",
"name": "Test User",
"given_name": "Test",
"family_name": "User",
"preferred_username": "testuser@outlook.com"
}
```
### Microsoft Graph /me
```bash
curl http://localhost:4005/v1.0/me \
-H "Authorization: Bearer microsoft_..."
```
Returns an OData-style response:
```json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"displayName": "Test User",
"mail": "testuser@outlook.com",
"userPrincipalName": "testuser@outlook.com",
"id": "<oid>"
}
```
### Logout
```bash
curl "http://localhost:4005/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000"
```
Redirects to the `post_logout_redirect_uri` if provided and valid.
### Token Revocation
```bash
curl -X POST http://localhost:4005/oauth2/v2.0/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=microsoft_..."
```
Returns `200 OK`. The token is removed from the emulator's token map.
## Common Patterns
### Full Authorization Code Flow
```bash
MICROSOFT_URL="http://localhost:4005"
CLIENT_ID="example-client-id"
CLIENT_SECRET="example-client-secret"
REDIRECT_URI="http://localhost:3000/api/auth/callback/microsoft-entra-id"
# 1. Open in browser (user picks a seeded account)
# $MICROSOFT_URL/oauth2/v2.0/authorize?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid+email+profile&response_type=code&state=abc
# 2. After user selection, emulator redirects to:
# $REDIRECT_URI?code=<code>&state=abc
# 3. Exchange code for tokens
curl -X POST $MICROSOFT_URL/oauth2/v2.0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=<code>&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code"
# 4. Fetch user info with the access_token
curl $MICROSOFT_URL/oidc/userinfo \
-H "Authorization: Bearer <access_token>"
```
### PKCE Flow
```bash
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43)
CODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | base64 | tr -d '=' | tr '+/' '-_')
# 1. Authorize with challenge
# $MICROSOFT_URL/oauth2/v2.0/authorize?...&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256
# 2. Token exchange with verifier
curl -X POST $MICROSOFT_URL/oauth2/v2.0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=<code>&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code&code_verifier=$CODE_VERIFIER"
```
### OIDC Discovery-Based Setup
Libraries that support OIDC discovery can auto-configure from the discovery document:
```typescript
import { Issuer } from 'openid-client'
const microsoftIssuer = await Issuer.discover(
process.env.MICROSOFT_EMULATOR_URL ?? 'https://login.microsoftonline.com/common/v2.0'
)
const client = new microsoftIssuer.Client({
client_id: process.env.MICROSOFT_CLIENT_ID,
client_secret: process.env.MICROSOFT_CLIENT_SECRET,
redirect_uris: ['http://localhost:3000/api/auth/callback/microsoft-entra-id'],
})
```
## Custom emulators alongside built-ins
Use `npx emulate init --custom inventory` to scaffold a third-party API emulator and test. Register it in `emulate.config.ts` with `defineConfig` from `emulate`, alongside built-in entries such as `{ emulator: "microsoft" }`. Run `npx emulate start --watch` to reload imports and inspect custom state at the printed `/_emulate` URL. Successful reloads reset the run to seed. Existing flat seed configs still work; `--config` selects an explicit file. For authoring and testing third-party API emulators, see https://emulate.dev/docs/custom-emulators.
From vercel-labs/emulate at c77cb73, shown as plain text under its license: Apache-2.0 (permissive). The license text is in LICENSE.
View SKILL.md on GitHub at c77cb73Files
- SKILL.md12 KB · 7d1882c31e3c
1 file, 12 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.
Skill folder on GitHub at c77cb73More from Vercel
next-bundle-optimizer
Audits Next.js applications to identify and reduce browser bundle size and initial-load work by analyzing routes, dependencies and client outputs.
Claude Code, Codex, Cursor +4 · about 2.3K tokens · pinned 6 days ago
next-cache-components-optimizer
Optimize Next.js routes to display meaningful UI instantly on initial load or client navigation by encoding the optimization goal as a failing…
Claude Code, Codex, Cursor +4 · about 5.6K tokens · pinned 6 days ago
next-partial-prefetching-adoption
Enables Partial Prefetching in Next.js 16.3+ apps and guides adoption through auditing Link prefetch behavior, preserving UI in tests or manually, and…
Claude Code, Codex, Cursor +4 · about 6.7K tokens · pinned 6 days ago
next-partial-prefetching-optimizer
This skill optimizes Next.js client-side navigation under Partial Prefetching by defining what UI loads before and after a click.
Claude Code, Codex, Cursor +4 · about 2.8K tokens · pinned 6 days ago
apple
This skill emulates Apple's OAuth and OIDC services for local development and testing.
Claude Code, Codex, Cursor +4 · about 1.9K tokens · pinned 6 days ago
aws
This skill emulates AWS cloud services locally, providing S3 bucket and object operations, SQS message queues, IAM user and role management, and STS assume…
Claude Code, Codex, Cursor +4 · about 2.8K tokens · pinned 6 days ago
Related in Backend and APIs
nvflare-orient
Routes NVFLARE requests to appropriate downstream skills based on user intent and preliminary source inspection findings.
by NVIDIAOfficial publisher
Claude Code, Codex, Cursor +4 · about 600 tokens · pinned 6 days ago
cloudflare-email-service
This skill enables agents to send transactional emails and route incoming emails using Cloudflare's Email Service platform.
by CloudflareOfficial publisher
Claude Code, Codex, Cursor +4 · about 1.6K tokens · pinned 6 days ago
durable-objects
Build and debug Cloudflare Durable Objects applications for stateful coordination and persistent storage on the edge.
by CloudflareOfficial publisher
Claude Code, Codex, Cursor +4 · about 1.5K tokens · pinned 6 days ago
workers-best-practices
This skill guides code review and development of Cloudflare Workers by applying best practices for production readiness.
by CloudflareOfficial publisher
Claude Code, Codex, Cursor +4 · about 1.3K tokens · pinned 6 days ago
supabase
This skill enables the agent to work with Supabase products including Database, Auth, Edge Functions, Realtime, Storage, and Vectors.
by SupabaseOfficial publisher
Claude Code, Codex, Cursor +4 · about 3.3K tokens · pinned 6 days ago
custom-apis
Build custom HTTP API emulators to simulate third-party providers in local development and tests.
by VercelOfficial publisher
Claude Code, Codex, Cursor +4 · about 1.4K tokens · pinned 6 days ago
Open roles at Vercel
5 of 11 open roles on the jobs board
- Software Engineer - Data Platform
Remote (United States) (Remote)
- Software Engineer, CDN
San Francisco, California, United States; New York City, New York, United States (Hybrid)
- Software Engineer, Trust & Safety
San Francisco, California, United States; New York City, New York, United States (Hybrid)
- Solutions Architect
San Francisco, New York City, Austin, United States (Hybrid)
- Software Engineer, Compute
London, UK (Hybrid)