Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,27 @@ After upgrading, use VS Code's **Problems panel** (or `get_errors` tool) to conf
- `body: null` may not be allowed (use `body: ""` instead)
- New required properties may be added
- Property types may become stricter

## Common Mistakes to Avoid

### PRESET Metadata
- **PRESET should be "No"** for most samples
- Only set `"PRESET": "Yes"` if the sample is **reusable for other purposes** (e.g., a generic configuration that developers can apply to their own APIs)
- Having a `devproxyrc.json` config file does NOT automatically make it a preset

### Startup Commands
- `.devproxy/devproxyrc.json` is a **default path** that Dev Proxy looks for automatically
- When config is in `.devproxy/devproxyrc.json`, the startup command should just be `devproxy` (no `--config-file` needed)
- Only use `--config-file` when the config file is in a non-default location or has a non-default name

### Updating Dates
- When updating sample dates, **always update both files**:
- `assets/sample.json`: Update `updateDateTime` field
- `README.md`: Update the version history table with the new date
- Dates must stay in sync between these two files
- **Pre-release updates** (sample not yet merged to main):
- Update both `creationDateTime` and `updateDateTime` in `sample.json`
- Update the v1.0 date in the README version history table
- **Post-release updates** (sample already in main):
- Only update `updateDateTime` in `sample.json`
- Add a new version entry (e.g., 1.1) to the README version history table
48 changes: 48 additions & 0 deletions samples/api-key-protected-mock/.devproxy/devproxyrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json",
"plugins": [
{
"name": "AuthPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "auth"
},
{
"name": "MockResponsePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "mockResponsePlugin"
}
],
"urlsToWatch": [
"https://api.contoso.com/*"
],
"auth": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/authplugin.schema.json",
"type": "apiKey",
"apiKey": {
"parameters": [
{
"in": "header",
"name": "x-api-key"
},
{
"in": "query",
"name": "code"
},
{
"in": "cookie",
"name": "api_key"
}
],
"allowedKeys": [
"secret-key-123",
"dev-key-456"
]
}
},
"mockResponsePlugin": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
"mocksFile": "mocks.json"
}
}
148 changes: 148 additions & 0 deletions samples/api-key-protected-mock/.devproxy/mocks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.mocksfile.schema.json",
"mocks": [
{
"request": {
"url": "https://api.contoso.com/items",
"method": "GET"
},
"response": {
"statusCode": 200,
"headers": [
{
"name": "content-type",
"value": "application/json"
},
{
"name": "x-powered-by",
"value": "Dev Proxy"
},
{
"name": "x-mocked-by",
"value": "Dev Proxy MockResponsePlugin"
}
],
"body": [
{
"id": 1,
"name": "Item 1",
"description": "First item in the collection"
},
{
"id": 2,
"name": "Item 2",
"description": "Second item in the collection"
},
{
"id": 3,
"name": "Item 3",
"description": "Third item in the collection"
}
]
}
},
{
"request": {
"url": "https://api.contoso.com/items/*",
"method": "GET"
},
"response": {
"statusCode": 200,
"headers": [
{
"name": "content-type",
"value": "application/json"
},
{
"name": "x-powered-by",
"value": "Dev Proxy"
},
{
"name": "x-mocked-by",
"value": "Dev Proxy MockResponsePlugin"
}
],
"body": {
"id": 1,
"name": "Item 1",
"description": "First item in the collection"
}
}
},
{
"request": {
"url": "https://api.contoso.com/items",
"method": "POST"
},
"response": {
"statusCode": 201,
"headers": [
{
"name": "content-type",
"value": "application/json"
},
{
"name": "x-powered-by",
"value": "Dev Proxy"
},
{
"name": "x-mocked-by",
"value": "Dev Proxy MockResponsePlugin"
}
],
"body": {
"id": 4,
"name": "New Item",
"description": "Newly created item"
}
}
},
{
"request": {
"url": "https://api.contoso.com/items/*",
"method": "PUT"
},
"response": {
"statusCode": 200,
"headers": [
{
"name": "content-type",
"value": "application/json"
},
{
"name": "x-powered-by",
"value": "Dev Proxy"
},
{
"name": "x-mocked-by",
"value": "Dev Proxy MockResponsePlugin"
}
],
"body": {
"id": 1,
"name": "Updated Item",
"description": "Updated item description"
}
}
},
{
"request": {
"url": "https://api.contoso.com/items/*",
"method": "DELETE"
},
"response": {
"statusCode": 204,
"headers": [
{
"name": "x-powered-by",
"value": "Dev Proxy"
},
{
"name": "x-mocked-by",
"value": "Dev Proxy MockResponsePlugin"
}
]
}
}
]
}
121 changes: 121 additions & 0 deletions samples/api-key-protected-mock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Simulating API key authentication

## Summary

This sample demonstrates how to simulate API key authentication for mock APIs using Dev Proxy. The AuthPlugin validates API keys in header, query parameter, or cookie, while the MockResponsePlugin provides the API responses. This is useful for testing API key authentication flows without a real backend, such as Azure Functions, API Gateway integrations, and other services that use API keys for authentication.

![Dev Proxy simulating API key authentication](assets/screenshot.png)

## Compatibility

![Dev Proxy v2.0.0](https://aka.ms/devproxy/badge/v2.0.0)

## Contributors

* [Waldek Mastykarz](https://github.com/waldekmastykarz)

## Version history

Version|Date|Comments
-------|----|--------
1.0|January 18, 2026|Initial release

## Minimal path to awesome

* Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/proxy-samples/tree/main/samples/api-key-protected-mock) then unzip it)
* Start Dev Proxy: `devproxy`
* Test the API key authentication by making requests:

**With valid API key in header (should return 200):**
```bash
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: secret-key-123"
```

**With valid API key in query parameter (should return 200):**
```bash
curl -ikx http://127.0.0.1:8000 "https://api.contoso.com/items?code=dev-key-456"
```

**With valid API key in cookie (should return 200):**
```bash
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "Cookie: api_key=secret-key-123"
```

**Without API key (should return 401 Unauthorized):**
```bash
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items
```

**With invalid API key (should return 401 Unauthorized):**
```bash
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: invalid-key"
```

## Features

This sample configures API key authentication that accepts keys in multiple locations:

**Supported API Key Locations:**
* `header` - Pass the API key in the `x-api-key` header
* `query` - Pass the API key as the `code` query parameter
* `cookie` - Pass the API key in the `api_key` cookie

**Allowed API Keys:**
* `secret-key-123` - Primary API key for testing
* `dev-key-456` - Secondary API key for development

**Mock API Endpoints:**
* `GET /items` - List all items
* `GET /items/{id}` - Get a specific item
* `POST /items` - Create a new item
* `PUT /items/{id}` - Update an item
* `DELETE /items/{id}` - Delete an item

Using this sample you can use Dev Proxy to:

* Test API key authentication flows without a real backend
* Simulate Azure Functions or API Gateway authentication
* Validate client applications properly include API keys in requests
* Verify applications handle 401 Unauthorized responses correctly
* Test different API key transmission methods (header, query, cookie)

## Configuration

The sample uses the following configuration to enable API key authentication:

```json
{
"auth": {
"type": "apiKey",
"apiKey": {
"parameters": [
{ "in": "header", "name": "x-api-key" },
{ "in": "query", "name": "code" },
{ "in": "cookie", "name": "api_key" }
],
"allowedKeys": ["secret-key-123", "dev-key-456"]
}
}
}
```

You can customize the configuration by:
* Adding or removing parameter locations (header, query, cookie)
* Changing parameter names to match your API's requirements
* Adding or removing allowed API keys

## Help

We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.

You can try looking at [issues related to this sample](https://github.com/pnp/proxy-samples/issues?q=label%3A%22sample%3A%20api-key-protected-mock%22) to see if anybody else is having the same issues.

If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/proxy-samples/issues/new).

Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/proxy-samples/issues/new).

## Disclaimer

**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**

![](https://m365-visitor-stats.azurewebsites.net/SamplesGallery/pnp-devproxy-api-key-protected-mock)
Loading