Skip to content

Commit 463302f

Browse files
committed
add proxy into the guide
1 parent 82a03c9 commit 463302f

File tree

2 files changed

+331
-422
lines changed

2 files changed

+331
-422
lines changed

docs/toolhive/guides-cli/auth.mdx

Lines changed: 331 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,337 @@ curl -H "Authorization: Bearer <your-jwt-token>" \
9898
<toolhive-server-url>
9999
```
100100

101+
## Set up proxy authentication
102+
103+
ToolHive provides a standalone `thv proxy` command that creates transparent HTTP
104+
proxies with advanced authentication capabilities. This is different from using
105+
`thv run` with authentication—the proxy command creates a standalone proxy
106+
process without managing workloads or containers.
107+
108+
### When to use proxy authentication
109+
110+
Use the `thv proxy` command when you need:
111+
112+
- **Outgoing authentication**: Authenticate to remote MCP servers using
113+
OAuth/OIDC, with the proxy handling token management and refresh
114+
- **Incoming authentication**: Protect a proxy endpoint with OIDC validation,
115+
requiring clients to provide valid JWT tokens
116+
- **Bidirectional authentication**: Secure both incoming requests to the proxy
117+
and outgoing requests to remote servers
118+
- **Dynamic client registration**: Automatically register OAuth clients using
119+
RFC 7591, eliminating the need for pre-configuration
120+
- **Standalone proxy**: Run a proxy without creating a managed workload
121+
122+
### Basic proxy with outgoing authentication
123+
124+
To create a proxy that authenticates to a remote MCP server:
125+
126+
```bash
127+
thv proxy my-server \
128+
--target-uri https://api.example.com \
129+
--remote-auth \
130+
--remote-auth-issuer https://auth.example.com \
131+
--remote-auth-client-id my-client-id \
132+
--remote-auth-client-secret-file /path/to/secret
133+
```
134+
135+
The proxy will:
136+
137+
1. Handle the OAuth/OIDC flow with the remote server
138+
2. Manage token storage and automatic refresh
139+
3. Forward authenticated requests transparently
140+
141+
Your clients connect to the local proxy without needing to handle
142+
authentication.
143+
144+
### Proxy with incoming authentication
145+
146+
To protect the proxy endpoint itself with OIDC validation:
147+
148+
```bash
149+
thv proxy my-server \
150+
--target-uri http://localhost:8080 \
151+
--oidc-issuer https://auth.example.com \
152+
--oidc-audience my-audience \
153+
--oidc-client-id my-client-id
154+
```
155+
156+
Clients must include a valid JWT token when connecting to the proxy.
157+
158+
### Bidirectional proxy authentication
159+
160+
Combine both incoming and outgoing authentication for end-to-end security:
161+
162+
```bash
163+
thv proxy my-server \
164+
--target-uri https://api.example.com \
165+
--remote-auth \
166+
--remote-auth-issuer https://remote-auth.example.com \
167+
--remote-auth-client-id remote-client-id \
168+
--remote-auth-client-secret-file /path/to/remote-secret \
169+
--oidc-issuer https://local-auth.example.com \
170+
--oidc-audience my-audience \
171+
--oidc-client-id local-client-id
172+
```
173+
174+
### Authentication modes
175+
176+
The `thv proxy` command supports four authentication scenarios:
177+
178+
1. **No authentication**: Simple transparent forwarding
179+
2. **Outgoing authentication**: Authenticate to remote MCP servers using
180+
OAuth/OIDC
181+
3. **Incoming authentication**: Protect the proxy endpoint with OIDC validation
182+
4. **Bidirectional**: Both incoming and outgoing authentication
183+
184+
### OAuth2 authentication (non-OIDC)
185+
186+
For non-OIDC OAuth2 servers, specify the authorization and token endpoints
187+
explicitly:
188+
189+
```bash
190+
thv proxy my-server \
191+
--target-uri https://api.example.com \
192+
--remote-auth \
193+
--remote-auth-authorize-url https://auth.example.com/oauth/authorize \
194+
--remote-auth-token-url https://auth.example.com/oauth/token \
195+
--remote-auth-client-id my-client-id \
196+
--remote-auth-client-secret-file /path/to/secret
197+
```
198+
199+
### Auto-detect authentication
200+
201+
The proxy can automatically detect if a remote server requires authentication by
202+
examining WWW-Authenticate headers:
203+
204+
```bash
205+
thv proxy my-server \
206+
--target-uri https://protected-api.com \
207+
--remote-auth-client-id my-client-id
208+
```
209+
210+
When authentication is detected, the proxy automatically initiates the
211+
appropriate OAuth flow.
212+
213+
### Dynamic client registration
214+
215+
When no client credentials are provided, the proxy can automatically register an
216+
OAuth client using RFC 7591 dynamic client registration:
217+
218+
```bash
219+
thv proxy my-server \
220+
--target-uri https://protected-api.com \
221+
--remote-auth \
222+
--remote-auth-issuer https://auth.example.com
223+
```
224+
225+
This feature:
226+
227+
- Eliminates the need to pre-configure OAuth clients
228+
- Automatically discovers the registration endpoint via OIDC
229+
- Supports PKCE flow for enhanced security
230+
231+
:::info
232+
233+
Dynamic client registration requires the remote authorization server to support
234+
RFC 7591. Not all OAuth providers support this feature.
235+
236+
:::
237+
238+
### Token introspection
239+
240+
For advanced scenarios, you can use token introspection for incoming
241+
authentication:
242+
243+
```bash
244+
thv proxy my-server \
245+
--target-uri http://localhost:8080 \
246+
--oidc-issuer https://auth.example.com \
247+
--oidc-audience my-audience \
248+
--oidc-client-id my-client-id \
249+
--oidc-client-secret my-client-secret \
250+
--oidc-introspection-url https://auth.example.com/oauth/introspect
251+
```
252+
253+
### Advanced proxy configuration
254+
255+
#### Custom OAuth scopes
256+
257+
Specify the OAuth scopes required by the remote server:
258+
259+
```bash
260+
thv proxy my-server \
261+
--target-uri https://api.example.com \
262+
--remote-auth \
263+
--remote-auth-issuer https://auth.example.com \
264+
--remote-auth-client-id my-client-id \
265+
--remote-auth-client-secret-file /path/to/secret \
266+
--remote-auth-scopes openid,profile,email,custom-scope
267+
```
268+
269+
:::note
270+
271+
If `--remote-auth-scopes` is not specified, OIDC authentication defaults to
272+
`openid,profile,email`.
273+
274+
:::
275+
276+
#### Authentication timeout
277+
278+
Adjust the timeout for slow networks or interactive authentication flows:
279+
280+
```bash
281+
thv proxy my-server \
282+
--target-uri https://api.example.com \
283+
--remote-auth \
284+
--remote-auth-issuer https://auth.example.com \
285+
--remote-auth-client-id my-client-id \
286+
--remote-auth-client-secret-file /path/to/secret \
287+
--remote-auth-timeout 2m
288+
```
289+
290+
#### Headless authentication
291+
292+
For non-interactive environments (CI/CD, servers), skip browser-based OAuth
293+
flows:
294+
295+
```bash
296+
thv proxy my-server \
297+
--target-uri https://api.example.com \
298+
--remote-auth \
299+
--remote-auth-issuer https://auth.example.com \
300+
--remote-auth-client-id my-client-id \
301+
--remote-auth-client-secret-file /path/to/secret \
302+
--remote-auth-skip-browser
303+
```
304+
305+
This requires client credentials flow or pre-authorized tokens.
306+
307+
#### Custom proxy host and port
308+
309+
By default, the proxy listens on `127.0.0.1` with a random port. To specify
310+
custom values:
311+
312+
```bash
313+
thv proxy my-server \
314+
--target-uri http://localhost:8080 \
315+
--host 0.0.0.0 \
316+
--port 8000
317+
```
318+
319+
#### Custom OAuth callback port
320+
321+
The proxy uses a temporary HTTP server for OAuth callbacks during
322+
authentication. To specify a custom callback port:
323+
324+
```bash
325+
thv proxy my-server \
326+
--target-uri https://api.example.com \
327+
--remote-auth \
328+
--remote-auth-issuer https://auth.example.com \
329+
--remote-auth-client-id my-client-id \
330+
--remote-auth-client-secret-file /path/to/secret \
331+
--remote-auth-callback-port 9000
332+
```
333+
334+
The default callback port is `8666`.
335+
336+
### Credential management
337+
338+
#### Client secret sources
339+
340+
OAuth client secrets can be provided via three methods (in order of precedence):
341+
342+
1. `--remote-auth-client-secret` flag (not recommended for production)
343+
2. `--remote-auth-client-secret-file` flag (recommended)
344+
3. `TOOLHIVE_REMOTE_OAUTH_CLIENT_SECRET` environment variable
345+
346+
:::warning[Secure credential handling]
347+
348+
Always use `--remote-auth-client-secret-file` instead of
349+
`--remote-auth-client-secret` in production environments. The file-based
350+
approach prevents credentials from appearing in process lists or command
351+
history.
352+
353+
:::
354+
355+
#### Using environment variables
356+
357+
```bash
358+
export TOOLHIVE_REMOTE_OAUTH_CLIENT_SECRET="your-secret-here"
359+
thv proxy my-server \
360+
--target-uri https://api.example.com \
361+
--remote-auth \
362+
--remote-auth-issuer https://auth.example.com \
363+
--remote-auth-client-id my-client-id
364+
```
365+
366+
#### Using secret files
367+
368+
```bash
369+
echo "your-secret-here" > /secure/path/secret.txt
370+
chmod 600 /secure/path/secret.txt
371+
372+
thv proxy my-server \
373+
--target-uri https://api.example.com \
374+
--remote-auth \
375+
--remote-auth-issuer https://auth.example.com \
376+
--remote-auth-client-id my-client-id \
377+
--remote-auth-client-secret-file /secure/path/secret.txt
378+
```
379+
380+
### Common proxy use cases
381+
382+
#### Protecting a local MCP server
383+
384+
Run a local MCP server and protect it with OIDC authentication:
385+
386+
```bash
387+
# Start your MCP server on localhost:8080
388+
# Then create a protected proxy
389+
thv proxy protected-mcp \
390+
--target-uri http://localhost:8080 \
391+
--port 3000 \
392+
--oidc-issuer https://auth.example.com \
393+
--oidc-audience mcp-users \
394+
--oidc-client-id mcp-proxy
395+
```
396+
397+
Clients now connect to `http://localhost:3000` with valid JWT tokens.
398+
399+
#### Accessing a protected remote MCP server
400+
401+
Connect to a remote MCP server that requires OAuth authentication:
402+
403+
```bash
404+
thv proxy remote-mcp \
405+
--target-uri https://api.example.com/mcp \
406+
--port 3000 \
407+
--remote-auth \
408+
--remote-auth-issuer https://auth.example.com \
409+
--remote-auth-client-id your-client-id \
410+
--remote-auth-client-secret-file /path/to/secret
411+
```
412+
413+
Clients connect to `http://localhost:3000` without handling OAuth flows.
414+
415+
#### Creating a secure gateway
416+
417+
Set up a secure gateway with authentication on both sides:
418+
419+
```bash
420+
thv proxy secure-gateway \
421+
--target-uri https://api.example.com/mcp \
422+
--port 3000 \
423+
--remote-auth \
424+
--remote-auth-issuer https://remote.example.com \
425+
--remote-auth-client-id remote-id \
426+
--remote-auth-client-secret-file /path/to/remote-secret \
427+
--oidc-issuer https://local.example.com \
428+
--oidc-audience gateway-users \
429+
--oidc-client-id gateway-proxy
430+
```
431+
101432
## Set up authorization
102433

103434
ToolHive uses Amazon's Cedar policy language for fine-grained, secure-by-default
@@ -162,5 +493,3 @@ If you're having issues with the CLI:
162493
- For detailed Cedar policy syntax, see
163494
[Cedar policies](../concepts/cedar-policies.md) and the
164495
[Cedar documentation](https://docs.cedarpolicy.com/)
165-
- For standalone proxy with authentication, see
166-
[Proxy with authentication](./proxy-authentication.mdx)

0 commit comments

Comments
 (0)