@@ -253,14 +253,25 @@ process.
253253
254254# ## Run a server with secrets
255255
256- For MCP servers that require authentication tokens or other secrets, you can use
257- secrets from multiple secrets managers :
256+ When your MCP servers require authentication tokens or other secrets, ToolHive
257+ supports multiple secrets management methods to fit your existing
258+ infrastructure. Choose the method that best suits your needs :
258259
259260<Tabs groupId='secret-manager' queryString='secret-manager'>
260- <TabItem value='kubernetes-native' label='Kubernetes' default>
261+ <TabItem value='kubernetes-native' label='Kubernetes secrets ' default>
261262
262- This example shows how to use an existing Kubernetes secret to pass a GitHub
263- personal access token to the `github` MCP server.
263+ ToolHive can reference existing Kubernetes secrets to inject sensitive data into
264+ your MCP server pods as environment variables. This example demonstrates how to
265+ pass a GitHub personal access token to the `github` MCP server.
266+
267+ First, create the secret. The secret must exist in the same namespace as your
268+ MCP server and the key must match what you specify in the `MCPServer` resource.
269+
270+ ` ` ` bash
271+ kubectl -n production create secret generic github-token --from-literal=token=<YOUR_TOKEN>
272+ ` ` `
273+
274+ Next, define the `MCPServer` resource to reference the secret :
264275
265276` ` ` yaml {13-16} title="my-mcpserver-with-secrets.yaml"
266277apiVersion: toolhive.stacklok.dev/v1alpha1
@@ -281,15 +292,7 @@ spec:
281292 targetEnvName: GITHUB_PERSONAL_ACCESS_TOKEN
282293` ` `
283294
284- First, create the secret. Note that the secret must be created in the same
285- namespace as the MCP server and the key must match the one specified in the
286- ` MCPServer` resource.
287-
288- ` ` ` bash
289- kubectl -n production create secret generic github-token --from-literal=token=<YOUR_TOKEN>
290- ` ` `
291-
292- Apply the MCPServer resource :
295+ Finally, apply the MCPServer resource :
293296
294297` ` ` bash
295298kubectl apply -f my-mcpserver-with-secrets.yaml
@@ -298,18 +301,27 @@ kubectl apply -f my-mcpserver-with-secrets.yaml
298301</TabItem>
299302<TabItem value='eso' label='External Secrets Operator'>
300303
301- This example shows how to use an existing Kubernetes secret created by the
302- [External Secrets Operator](https://external-secrets.io/) to pass a GitHub
303- personal access token to the `github` MCP server.
304+ [External Secrets Operator](https://external-secrets.io/) is a Kubernetes
305+ operator that integrates external secret management systems and syncs secrets
306+ into Kubernetes as native resources. This example demonstrates how to use
307+ ESO-managed secrets with your MCP server.
304308
305- :::info[Important]
309+ :::note
306310
307- Given the External Secrets Operator creates standard Kubernetes secrets based on
308- external secrets, the MCP server definition will look the same as the Kubernetes
309- example .
311+ When you use the External Secrets Operator, your MCP server definition will look
312+ the same as the Kubernetes-native example. This is because the External Secrets
313+ Operator creates standard Kubernetes secrets from external sources .
310314
311315:: :
312316
317+ First, create a secret using the
318+ [ExternalSecret resource](https://external-secrets.io/latest/api/externalsecret/).
319+ The exact configuration depends on your external secret management system. The
320+ secret must exist in the same namespace as your MCP server and the key must
321+ match what you specify in the `MCPServer` resource.
322+
323+ Next, define the `MCPServer` resource to reference the secret :
324+
313325` ` ` yaml {13-16} title="my-mcpserver-with-secrets-eso.yaml"
314326apiVersion: toolhive.stacklok.dev/v1alpha1
315327kind: MCPServer
@@ -329,83 +341,35 @@ spec:
329341 targetEnvName: GITHUB_PERSONAL_ACCESS_TOKEN
330342` ` `
331343
332- First, create the secret by using
333- [External Secrets Operator](https://external-secrets.io/latest/api/externalsecret).
334- Note that the secret must be created in the same namespace as the MCP server and
335- the key must match the one specified in the `MCPServer` resource.
336-
337- Apply the MCPServer resource :
344+ Finally, apply the MCPServer resource :
338345
339346` ` ` bash
340347kubectl apply -f my-mcpserver-with-secrets-eso.yaml
341348` ` `
342349
343350</TabItem>
344- <TabItem value='vault' label='Vault Secret Injection'>
345-
346- This example shows how to use [Vault](https://developer.hashicorp.com/vault) to
347- inject secrets into the ToolHive containers for consumption.
348-
349- Injecting secrets using Vault is done with its agent sidecar container, but
350- before you can start injecting secrets into the container there are some steps
351- to do before hand. This includes setting up Vault to be able to authenticate and
352- pull the necessary secrets. We will not detail here how to do this as there are
353- some very helpful
354- [Vault guides](https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-sidecar)
355- on setting this up, but before we can inject secrets into the ToolHive
356- containers we need to have the following :
357-
358- - Vault available
359- - Vault configured for Kubernetes authentication
360- - Vault policy created to be able to read the desired secrets
361- - Vault role created that is bound to the ToolHive ProxyRunner Service Account
362- in order to enable authentication
363-
364- ` ` ` yaml {23-33} title="my-mcpserver-with-vault-secrets-injection.yaml"
365- apiVersion: toolhive.stacklok.dev/v1alpha1
366- kind: MCPServer
367- metadata:
368- name: github-vault-generic
369- namespace: toolhive-system
370- spec:
371- image: ghcr.io/github/github-mcp-server:latest
372- transport: stdio
373- port: 9095
374- permissionProfile:
375- type: builtin
376- name: network
377- resources:
378- limits:
379- cpu: '100m'
380- memory: '128Mi'
381- requests:
382- cpu: '50m'
383- memory: '64Mi'
384- resourceOverrides:
385- proxyDeployment:
386- podTemplateMetadataOverrides:
387- annotations:
388- # Enable Vault Agent injection
389- vault.hashicorp.com/agent-inject: 'true'
390- vault.hashicorp.com/role: '<ROLE_NAME_CREATE_IN_VAULT>'
391-
392- # Inject GitHub configuration secret
393- vault.hashicorp.com/agent-inject-secret-github-config: 'workload-secrets/data/github-mcp/config'
394- vault.hashicorp.com/agent-inject-template-github-config: |
395- {{- with secret "workload-secrets/data/github-mcp/config" -}}
396- GITHUB_PERSONAL_ACCESS_TOKEN={{ .Data.data.token }}
397- {{- end -}}
398- ` ` `
399-
400- Apply the MCPServer resource :
401-
402- ` ` ` bash
403- kubectl apply -f my-mcpserver-with-vault-secrets-injection.yaml
404- ` ` `
405-
406- The Vault agent sidecar will now inject secrets from the
407- ` workload-secrets/data/github-mcp/config` inside of Vault, into the ProxyRunner
408- container.
351+ <TabItem value='vault' label='HashiCorp Vault'>
352+
353+ HashiCorp Vault provides multiple integration methods for Kubernetes
354+ environments :
355+
356+ 1. [Vault Sidecar Agent Injector](https://developer.hashicorp.com/vault/docs/deploy/kubernetes/injector),
357+ which injects a sidecar container into your pod to fetch and renew secrets
358+ 2. [Vault Secrets Operator](https://developer.hashicorp.com/vault/docs/deploy/kubernetes/vso),
359+ which creates Kubernetes secrets from Vault secrets (similar to the External
360+ Secrets Operator)
361+ 3. [Vault CSI Provider](https://developer.hashicorp.com/vault/docs/deploy/kubernetes/csi),
362+ which mounts secrets directly into your pod as files
363+
364+ ToolHive supports the first two methods. When you use the Vault Secrets
365+ Operator, your MCP server definition will look the same as the Kubernetes-native
366+ example because the Vault Secrets Operator creates standard Kubernetes secrets
367+ from Vault.
368+
369+ The Vault Sidecar Agent Injector requires additional configuration in your
370+ ` MCPServer` resource to add the required annotations. For a complete example,
371+ see the
372+ [HashiCorp Vault integration tutorial](../tutorials/vault-integration.mdx).
409373
410374</TabItem>
411375</Tabs>
0 commit comments