Skip to content

Commit bec3eb5

Browse files
Add sample: api-key-protected-mock - Simulate API key authentication (#42)
* Add api-key-protected-mock sample for API key authentication simulation Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Fix author attribution and add placeholder screenshot Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Address PR feedback: remove default properties, update dates, fix PRESET value, simplify devproxy command Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Add x-mocked-by header to mocks and update dates to 2026-01-10 Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Move Dev Proxy config files to .devproxy folder Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Remove unnecessary cd .devproxy step - Dev Proxy auto-loads from .devproxy Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Updates --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> Co-authored-by: waldekmastykarz <waldek@mastykarz.nl>
1 parent f2fc217 commit bec3eb5

File tree

6 files changed

+413
-0
lines changed

6 files changed

+413
-0
lines changed

.github/copilot-instructions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,27 @@ After upgrading, use VS Code's **Problems panel** (or `get_errors` tool) to conf
206206
- `body: null` may not be allowed (use `body: ""` instead)
207207
- New required properties may be added
208208
- Property types may become stricter
209+
210+
## Common Mistakes to Avoid
211+
212+
### PRESET Metadata
213+
- **PRESET should be "No"** for most samples
214+
- 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)
215+
- Having a `devproxyrc.json` config file does NOT automatically make it a preset
216+
217+
### Startup Commands
218+
- `.devproxy/devproxyrc.json` is a **default path** that Dev Proxy looks for automatically
219+
- When config is in `.devproxy/devproxyrc.json`, the startup command should just be `devproxy` (no `--config-file` needed)
220+
- Only use `--config-file` when the config file is in a non-default location or has a non-default name
221+
222+
### Updating Dates
223+
- When updating sample dates, **always update both files**:
224+
- `assets/sample.json`: Update `updateDateTime` field
225+
- `README.md`: Update the version history table with the new date
226+
- Dates must stay in sync between these two files
227+
- **Pre-release updates** (sample not yet merged to main):
228+
- Update both `creationDateTime` and `updateDateTime` in `sample.json`
229+
- Update the v1.0 date in the README version history table
230+
- **Post-release updates** (sample already in main):
231+
- Only update `updateDateTime` in `sample.json`
232+
- Add a new version entry (e.g., 1.1) to the README version history table
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json",
3+
"plugins": [
4+
{
5+
"name": "AuthPlugin",
6+
"enabled": true,
7+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
8+
"configSection": "auth"
9+
},
10+
{
11+
"name": "MockResponsePlugin",
12+
"enabled": true,
13+
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
14+
"configSection": "mockResponsePlugin"
15+
}
16+
],
17+
"urlsToWatch": [
18+
"https://api.contoso.com/*"
19+
],
20+
"auth": {
21+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/authplugin.schema.json",
22+
"type": "apiKey",
23+
"apiKey": {
24+
"parameters": [
25+
{
26+
"in": "header",
27+
"name": "x-api-key"
28+
},
29+
{
30+
"in": "query",
31+
"name": "code"
32+
},
33+
{
34+
"in": "cookie",
35+
"name": "api_key"
36+
}
37+
],
38+
"allowedKeys": [
39+
"secret-key-123",
40+
"dev-key-456"
41+
]
42+
}
43+
},
44+
"mockResponsePlugin": {
45+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json",
46+
"mocksFile": "mocks.json"
47+
}
48+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.mocksfile.schema.json",
3+
"mocks": [
4+
{
5+
"request": {
6+
"url": "https://api.contoso.com/items",
7+
"method": "GET"
8+
},
9+
"response": {
10+
"statusCode": 200,
11+
"headers": [
12+
{
13+
"name": "content-type",
14+
"value": "application/json"
15+
},
16+
{
17+
"name": "x-powered-by",
18+
"value": "Dev Proxy"
19+
},
20+
{
21+
"name": "x-mocked-by",
22+
"value": "Dev Proxy MockResponsePlugin"
23+
}
24+
],
25+
"body": [
26+
{
27+
"id": 1,
28+
"name": "Item 1",
29+
"description": "First item in the collection"
30+
},
31+
{
32+
"id": 2,
33+
"name": "Item 2",
34+
"description": "Second item in the collection"
35+
},
36+
{
37+
"id": 3,
38+
"name": "Item 3",
39+
"description": "Third item in the collection"
40+
}
41+
]
42+
}
43+
},
44+
{
45+
"request": {
46+
"url": "https://api.contoso.com/items/*",
47+
"method": "GET"
48+
},
49+
"response": {
50+
"statusCode": 200,
51+
"headers": [
52+
{
53+
"name": "content-type",
54+
"value": "application/json"
55+
},
56+
{
57+
"name": "x-powered-by",
58+
"value": "Dev Proxy"
59+
},
60+
{
61+
"name": "x-mocked-by",
62+
"value": "Dev Proxy MockResponsePlugin"
63+
}
64+
],
65+
"body": {
66+
"id": 1,
67+
"name": "Item 1",
68+
"description": "First item in the collection"
69+
}
70+
}
71+
},
72+
{
73+
"request": {
74+
"url": "https://api.contoso.com/items",
75+
"method": "POST"
76+
},
77+
"response": {
78+
"statusCode": 201,
79+
"headers": [
80+
{
81+
"name": "content-type",
82+
"value": "application/json"
83+
},
84+
{
85+
"name": "x-powered-by",
86+
"value": "Dev Proxy"
87+
},
88+
{
89+
"name": "x-mocked-by",
90+
"value": "Dev Proxy MockResponsePlugin"
91+
}
92+
],
93+
"body": {
94+
"id": 4,
95+
"name": "New Item",
96+
"description": "Newly created item"
97+
}
98+
}
99+
},
100+
{
101+
"request": {
102+
"url": "https://api.contoso.com/items/*",
103+
"method": "PUT"
104+
},
105+
"response": {
106+
"statusCode": 200,
107+
"headers": [
108+
{
109+
"name": "content-type",
110+
"value": "application/json"
111+
},
112+
{
113+
"name": "x-powered-by",
114+
"value": "Dev Proxy"
115+
},
116+
{
117+
"name": "x-mocked-by",
118+
"value": "Dev Proxy MockResponsePlugin"
119+
}
120+
],
121+
"body": {
122+
"id": 1,
123+
"name": "Updated Item",
124+
"description": "Updated item description"
125+
}
126+
}
127+
},
128+
{
129+
"request": {
130+
"url": "https://api.contoso.com/items/*",
131+
"method": "DELETE"
132+
},
133+
"response": {
134+
"statusCode": 204,
135+
"headers": [
136+
{
137+
"name": "x-powered-by",
138+
"value": "Dev Proxy"
139+
},
140+
{
141+
"name": "x-mocked-by",
142+
"value": "Dev Proxy MockResponsePlugin"
143+
}
144+
]
145+
}
146+
}
147+
]
148+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Simulating API key authentication
2+
3+
## Summary
4+
5+
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.
6+
7+
![Dev Proxy simulating API key authentication](assets/screenshot.png)
8+
9+
## Compatibility
10+
11+
![Dev Proxy v2.0.0](https://aka.ms/devproxy/badge/v2.0.0)
12+
13+
## Contributors
14+
15+
* [Waldek Mastykarz](https://github.com/waldekmastykarz)
16+
17+
## Version history
18+
19+
Version|Date|Comments
20+
-------|----|--------
21+
1.0|January 18, 2026|Initial release
22+
23+
## Minimal path to awesome
24+
25+
* 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)
26+
* Start Dev Proxy: `devproxy`
27+
* Test the API key authentication by making requests:
28+
29+
**With valid API key in header (should return 200):**
30+
```bash
31+
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: secret-key-123"
32+
```
33+
34+
**With valid API key in query parameter (should return 200):**
35+
```bash
36+
curl -ikx http://127.0.0.1:8000 "https://api.contoso.com/items?code=dev-key-456"
37+
```
38+
39+
**With valid API key in cookie (should return 200):**
40+
```bash
41+
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "Cookie: api_key=secret-key-123"
42+
```
43+
44+
**Without API key (should return 401 Unauthorized):**
45+
```bash
46+
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items
47+
```
48+
49+
**With invalid API key (should return 401 Unauthorized):**
50+
```bash
51+
curl -ikx http://127.0.0.1:8000 https://api.contoso.com/items -H "x-api-key: invalid-key"
52+
```
53+
54+
## Features
55+
56+
This sample configures API key authentication that accepts keys in multiple locations:
57+
58+
**Supported API Key Locations:**
59+
* `header` - Pass the API key in the `x-api-key` header
60+
* `query` - Pass the API key as the `code` query parameter
61+
* `cookie` - Pass the API key in the `api_key` cookie
62+
63+
**Allowed API Keys:**
64+
* `secret-key-123` - Primary API key for testing
65+
* `dev-key-456` - Secondary API key for development
66+
67+
**Mock API Endpoints:**
68+
* `GET /items` - List all items
69+
* `GET /items/{id}` - Get a specific item
70+
* `POST /items` - Create a new item
71+
* `PUT /items/{id}` - Update an item
72+
* `DELETE /items/{id}` - Delete an item
73+
74+
Using this sample you can use Dev Proxy to:
75+
76+
* Test API key authentication flows without a real backend
77+
* Simulate Azure Functions or API Gateway authentication
78+
* Validate client applications properly include API keys in requests
79+
* Verify applications handle 401 Unauthorized responses correctly
80+
* Test different API key transmission methods (header, query, cookie)
81+
82+
## Configuration
83+
84+
The sample uses the following configuration to enable API key authentication:
85+
86+
```json
87+
{
88+
"auth": {
89+
"type": "apiKey",
90+
"apiKey": {
91+
"parameters": [
92+
{ "in": "header", "name": "x-api-key" },
93+
{ "in": "query", "name": "code" },
94+
{ "in": "cookie", "name": "api_key" }
95+
],
96+
"allowedKeys": ["secret-key-123", "dev-key-456"]
97+
}
98+
}
99+
}
100+
```
101+
102+
You can customize the configuration by:
103+
* Adding or removing parameter locations (header, query, cookie)
104+
* Changing parameter names to match your API's requirements
105+
* Adding or removing allowed API keys
106+
107+
## Help
108+
109+
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.
110+
111+
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.
112+
113+
If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/proxy-samples/issues/new).
114+
115+
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/proxy-samples/issues/new).
116+
117+
## Disclaimer
118+
119+
**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.**
120+
121+
![](https://m365-visitor-stats.azurewebsites.net/SamplesGallery/pnp-devproxy-api-key-protected-mock)

0 commit comments

Comments
 (0)