From be9ea3223134e68cd046e971fbe7a1f7633af1b4 Mon Sep 17 00:00:00 2001 From: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> Date: Fri, 10 Oct 2025 17:28:12 +0100 Subject: [PATCH 1/4] adds start for auth docs Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --- .../_partials/_auth-troubleshooting.md | 29 ++ .../toolhive/_partials/_basic-cedar-config.md | 28 ++ .../toolhive/_partials/_oidc-prerequisites.md | 22 + docs/toolhive/concepts/auth-framework.md | 258 +++++++++++ .../concepts/authentication-authorization.md | 366 ++++++++++++++++ docs/toolhive/concepts/cedar-policies.md | 411 ++++++++++++++++++ docs/toolhive/guides-cli/auth.mdx | 165 +++++++ docs/toolhive/guides-k8s/auth-k8s.mdx | 384 ++++++++++++++++ 8 files changed, 1663 insertions(+) create mode 100644 docs/toolhive/_partials/_auth-troubleshooting.md create mode 100644 docs/toolhive/_partials/_basic-cedar-config.md create mode 100644 docs/toolhive/_partials/_oidc-prerequisites.md create mode 100644 docs/toolhive/concepts/auth-framework.md create mode 100644 docs/toolhive/concepts/authentication-authorization.md create mode 100644 docs/toolhive/concepts/cedar-policies.md create mode 100644 docs/toolhive/guides-cli/auth.mdx create mode 100644 docs/toolhive/guides-k8s/auth-k8s.mdx diff --git a/docs/toolhive/_partials/_auth-troubleshooting.md b/docs/toolhive/_partials/_auth-troubleshooting.md new file mode 100644 index 00000000..9a01f5bc --- /dev/null +++ b/docs/toolhive/_partials/_auth-troubleshooting.md @@ -0,0 +1,29 @@ +### Authentication issues + +If clients can't authenticate: + +1. Check that the JWT token is valid and not expired +2. Verify that the audience and issuer match your configuration +3. Ensure the JWKS URL is accessible +4. Check the server logs for specific authentication errors: + + ```bash + thv logs + ``` + +### Authorization issues + +If authenticated clients are denied access: + +1. Make sure your Cedar policies explicitly permit the specific action + (remember, default deny) +2. Check that the principal, action, and resource match what's in your policies + (including case and formatting) +3. Examine any conditions in your policies to ensure they're satisfied (for + example, required JWT claims or tool arguments) +4. Remember that Cedar uses a default deny policy—if no policy explicitly + permits an action, it will be denied + +**Troubleshooting tip:** If access is denied, check that your policies +explicitly permit the action. Cedar uses a default deny model—if no policy +matches, the request is denied. diff --git a/docs/toolhive/_partials/_basic-cedar-config.md b/docs/toolhive/_partials/_basic-cedar-config.md new file mode 100644 index 00000000..8ab50c53 --- /dev/null +++ b/docs/toolhive/_partials/_basic-cedar-config.md @@ -0,0 +1,28 @@ +Create a JSON or YAML file with Cedar policies. Here's an example in JSON +format: + +```json +{ + "version": "1.0", + "type": "cedarv1", + "cedar": { + "policies": [ + // Allow everyone to use the weather tool + "permit(principal, action == Action::\"call_tool\", resource == Tool::\"weather\");", + // Restrict admin_tool to a specific user + "permit(principal == Client::\"alice123\", action == Action::\"call_tool\", resource == Tool::\"admin_tool\");", + // Role-based access: only users with the 'premium' role can call any tool + "permit(principal, action == Action::\"call_tool\", resource) when { principal.claim_roles.contains(\"premium\") };", + // Attribute-based: allow calculator tool only for add/subtract operations + "permit(principal, action == Action::\"call_tool\", resource == Tool::\"calculator\") when { resource.arg_operation == \"add\" || resource.arg_operation == \"subtract\" };" + ], + "entities_json": "[]" + } +} +``` + +You can also define custom resource attributes in `entities_json` for per-tool +ownership or sensitivity labels. + +> For more policy examples and advanced usage, see +> [Cedar policies](../concepts/cedar-policies.md). diff --git a/docs/toolhive/_partials/_oidc-prerequisites.md b/docs/toolhive/_partials/_oidc-prerequisites.md new file mode 100644 index 00000000..a4c57f2d --- /dev/null +++ b/docs/toolhive/_partials/_oidc-prerequisites.md @@ -0,0 +1,22 @@ +Before you begin, make sure you have: + +- ToolHive installed and working +- Basic familiarity with OAuth, OIDC, and JWT concepts +- An identity provider that supports OpenID Connect (OIDC), such as Google, + GitHub, Microsoft Entra ID (Azure AD), Okta, Auth0, or Kubernetes (for service + accounts) + +From your identity provider, you'll need: + +- Client ID +- Audience value +- Issuer URL +- JWKS URL (for key verification) + +> ToolHive uses OIDC to connect to your existing identity provider, so you can +> authenticate with your own credentials (for example, Google login) or with +> service account tokens (for example, in Kubernetes). ToolHive never sees your +> password, only signed tokens from your identity provider. + +For background on authentication, authorization, and Cedar policy examples, see +[Authentication and authorization framework](../concepts/auth-framework.md). diff --git a/docs/toolhive/concepts/auth-framework.md b/docs/toolhive/concepts/auth-framework.md new file mode 100644 index 00000000..6f60e7a1 --- /dev/null +++ b/docs/toolhive/concepts/auth-framework.md @@ -0,0 +1,258 @@ +--- +title: Authentication and authorization framework +description: + Understanding ToolHive's authentication and authorization framework concepts. +sidebar_position: 50 +--- + +This document explains the concepts behind ToolHive's authentication and +authorization framework, which secures MCP servers by verifying client identity +and controlling access to resources. You'll learn how these systems work +together, why they're designed this way, and the benefits of this approach. + +## Understanding authentication vs. authorization + +When you secure MCP servers, you need to understand the strong separation +between two critical security concepts: + +- **Authentication (authN):** Verifying the identity of clients connecting to + your MCP server ("Who are you?") +- **Authorization (authZ):** Determining what actions authenticated clients are + allowed to perform ("What can you do?") + +You should always perform authentication first, using a trusted identity +provider, and then apply authorization rules to determine what the authenticated +identity can do. ToolHive helps you follow this best practice by acting as a +gateway in front of your MCP servers. This approach lets you use proven identity +systems for authentication, while keeping your authorization policies clear, +flexible, and auditable. You don't need to add custom authentication or +authorization logic to every server—ToolHive handles it for you, consistently +and securely. + +## ToolHive vs. MCP specification + +The official Model Context Protocol (MCP) specification recommends OAuth +2.1-based authorization for HTTP transports, which can require each MCP server +to implement OAuth endpoints and manage tokens. ToolHive takes a different +approach: it centralizes authentication and authorization in its proxy layer, +using OIDC for authentication and Cedar for fine-grained authorization. This +means you don't need to implement OAuth flows or scope management in every +server—just configure ToolHive with your IdP and write clear policies. This +approach is more flexible, secure, and easier to manage for you and your team. + +## Authentication framework + +ToolHive uses OpenID Connect (OIDC), an identity layer built on top of OAuth +2.0, for authentication. OIDC is a widely adopted, interoperable protocol that +lets you connect ToolHive to any OIDC-compliant identity provider (IdP), such as +Google, GitHub, Microsoft Entra ID (Azure AD), Okta, Auth0, or even Kubernetes +service accounts. ToolHive never handles your raw passwords or credentials; +instead, it relies on signed identity tokens (usually JWTs) issued by your +trusted provider. + +### Why use OIDC? + +OIDC provides several key advantages for securing MCP servers: + +- **Standard and interoperable:** You can connect ToolHive to any OIDC-compliant + IdP without custom code, supporting both human users and automated services. +- **Proven and secure:** Authentication is delegated to battle-tested identity + systems, which handle login UI, multi-factor authentication, and password + storage. +- **Decoupled identity management:** You can use your existing SSO/IdP + infrastructure, making onboarding and management seamless. +- **Flexible for users and services:** OIDC supports both interactive user login + (for example, Google sign-in) and service-to-service authentication (for + example, Kubernetes service account tokens). + +### Real-world authentication scenarios + +Understanding how OIDC works in practice helps you design better security for +your MCP servers: + +**User login via Google (OIDC):** You can run an MCP server that requires +authentication using your Google credentials. ToolHive delegates login to +Google, receives a signed ID token, and uses it to authenticate you. This means +users get a familiar login experience while you benefit from Google's security +infrastructure. + +**Service-to-service auth with Kubernetes:** If you run a microservice in a +Kubernetes cluster, it can present its service account token (an OIDC JWT) to +ToolHive. ToolHive validates the token using the cluster's OIDC issuer and JWKS +URL, enabling secure, automated authentication for your internal services. + +### JWT-based authentication + +ToolHive uses JSON Web Tokens (JWTs) for authentication. JWTs are compact, +self-contained tokens that securely transmit identity information. Each JWT has +three parts: + +1. **Header:** Metadata about the token +2. **Payload:** Claims about the entity (typically you or your service) +3. **Signature:** Ensures the token hasn't been altered + +### Authentication flow + +The authentication process follows these steps: + +1. **Token acquisition:** You obtain a JWT from your identity provider. +2. **Token presentation:** You include the JWT in your requests to ToolHive. +3. **Token validation:** ToolHive validates the JWT's signature, expiration, and + claims. +4. **Identity extraction:** ToolHive extracts your identity information from the + validated JWT. + +```mermaid +flowchart TD + Client -->|OIDC Token| ToolHive + ToolHive -->|Validate Token| OIDC_Provider[OIDC Provider] + ToolHive -->|Evaluate Cedar Policy| Cedar_Authorizer[Cedar Authorizer] + Cedar_Authorizer -->|Permit| MCP_Server + Cedar_Authorizer -->|Deny| Denied[403 Forbidden] +``` + +### Identity providers + +ToolHive can integrate with any provider that supports OIDC, including: + +- Google +- GitHub +- Microsoft Entra ID (Azure AD) +- Okta +- Auth0 +- Kubernetes (service account tokens) + +This flexibility lets you use your existing identity infrastructure for both +users and services, reducing operational overhead and improving security. + +## Authorization framework + +After authentication, ToolHive enforces authorization using Amazon's Cedar +policy language. ToolHive acts as a gateway in front of MCP servers, handling +all authorization checks before requests reach the server logic. This means MCP +servers do not need to implement their own OAuth or custom authorization +logic—ToolHive centralizes and standardizes access control. + +### Why Cedar for authorization? + +Cedar provides several advantages for MCP server authorization: + +- **Expressive and flexible:** Cedar supports both role-based (RBAC) and + attribute-based (ABAC) access control patterns, letting you create policies + that match your security requirements. +- **Formally verified:** Cedar's design has been formally verified for safety + and security properties, reducing the risk of policy bugs. +- **Human-readable:** Cedar policies use clear, declarative syntax that's easy + to read, write, and audit. +- **Policy enforcement point:** ToolHive blocks unauthorized requests before + they reach the MCP server, reducing risk and simplifying server code. +- **Secure-by-default:** Authorization is explicit—if a request is not + explicitly permitted, it is denied. Deny rules take precedence over permit + rules (deny overrides). + +### Authorization components + +ToolHive's authorization framework consists of: + +1. **Cedar authorizer:** Evaluates Cedar policies to determine if a request is + authorized +2. **Authorization middleware:** Extracts information from MCP requests and uses + the Cedar Authorizer +3. **Configuration:** A JSON or YAML file that specifies the Cedar policies and + entities + +### Authorization flow + +When a request arrives at an MCP server with authorization enabled: + +1. The JWT middleware authenticates the client and adds JWT claims to the + request context +2. The authorization middleware extracts information from the request + (principal, action, resource, and any arguments) +3. The Cedar authorizer evaluates policies to determine if the request is + authorized +4. If authorized, the request proceeds; otherwise, a 403 Forbidden response is + returned + +```mermaid +flowchart TD + Client -->|JWT| ToolHive + ToolHive -->|Validate JWT| JWT_Middleware + JWT_Middleware -->|Extract Claims| Authz_Middleware + Authz_Middleware -->|Evaluate Cedar Policies| Cedar_Authorizer + Cedar_Authorizer -->|Permit| MCP_Server + Cedar_Authorizer -->|Deny| Denied[403 Forbidden] +``` + +## Security and operational benefits + +ToolHive's authentication and authorization approach provides several key +benefits: + +- **Separation of concerns:** Authentication and authorization are handled + independently, following security best practices. +- **Integration with existing systems:** Use your existing identity + infrastructure (SSO, IdPs, Kubernetes, etc.). +- **Centralized, flexible policy model:** Define precise, auditable access rules + in a single place—no need to modify MCP server code. +- **Secure by default:** Requests are denied unless explicitly permitted by + policy, with deny precedence for maximum safety. +- **Auditable and versionable:** Policies are clear, declarative, and can be + tracked in version control for compliance and review. +- **Developer and operator friendly:** ToolHive acts as a smart proxy, so you + don't need to implement complex OAuth or custom auth logic in every server. + +## Client support for MCP server authentication + +While ToolHive provides a robust authentication and authorization framework for +MCP servers, it's important to understand the current state of client support +across the ecosystem. + +### Current limitations + +Most AI coding clients and MCP client implementations do not currently support +authentication when connecting to MCP servers. This means that many popular AI +development tools expect MCP servers to be accessible without authentication, +which limits the security options available for production deployments. + +### Expected evolution + +As the official MCP specification matures and security becomes a higher priority +for production MCP deployments, we expect to see authentication support +implemented across major AI coding clients. The MCP specification already +includes provisions for OAuth 2.1-based authorization, and client +implementations are likely to adopt these standards over time. + +### Current use cases + +Today, MCP server authentication is primarily valuable for: + +- **Custom AI applications and agent workflows:** If you're building your own AI + application or agent system, you can implement MCP client authentication to + work with ToolHive's secure MCP servers. +- **Kubernetes service account authentication:** For automated services running + in Kubernetes clusters, service account tokens provide a secure way to + authenticate with MCP servers without requiring interactive login flows. +- **Internal tooling and APIs:** Organizations building internal tools that + consume MCP servers can implement authentication to secure access to sensitive + resources and tools. + +### Planning for the future + +When designing your MCP server security strategy, consider that: + +- Authentication support in popular AI coding clients will likely improve over + time +- ToolHive's OIDC-based approach aligns with emerging standards and will be + compatible with future client implementations +- You can start with authenticated MCP servers for internal use cases and + gradually expand as client support improves + +This evolving landscape means that while authentication capabilities exist +today, their practical application depends on your specific use case and client +requirements. + +## Related information + +- For detailed policy writing guidance, see + [Cedar policies](./cedar-policies.mdcedar-policies.md) diff --git a/docs/toolhive/concepts/authentication-authorization.md b/docs/toolhive/concepts/authentication-authorization.md new file mode 100644 index 00000000..a03ad002 --- /dev/null +++ b/docs/toolhive/concepts/authentication-authorization.md @@ -0,0 +1,366 @@ +--- +title: Authentication and authorization +description: + Understanding ToolHive's authentication and authorization framework. +sidebar_position: 40 +--- + +This document explains the concepts behind ToolHive's authentication and +authorization framework, which secures MCP servers by verifying client identity +and controlling access to resources. + +> For step-by-step setup and troubleshooting, see +> [Securing MCP servers with authentication and authorization](../how-to/authentication-authorization.md). + +## Understanding authentication vs. authorization + +When you secure MCP servers, it's critical to understand the strong separation +between: + +- **Authentication (authN):** Verifying the identity of clients connecting to + your MCP server ("Who are you?") +- **Authorization (authZ):** Determining what actions authenticated clients are + allowed to perform ("What can you do?") + +You should always perform authentication first, using a trusted identity +provider, and then apply authorization rules to determine what the authenticated +identity can do. ToolHive helps you follow this best practice by acting as a +gateway in front of your MCP servers. This approach lets you use proven identity +systems for authentication, while keeping your authorization policies clear, +flexible, and auditable. You don't need to add custom authentication or +authorization logic to every server—ToolHive handles it for you, consistently +and securely. + +## Authentication framework + +You use OpenID Connect (OIDC)—an identity layer built on top of OAuth 2.0—for +authentication in ToolHive. OIDC is a widely adopted, interoperable protocol +that lets you connect ToolHive to any OIDC-compliant identity provider (IdP), +such as Google, GitHub, Microsoft Entra ID (Azure AD), Okta, Auth0, or even +Kubernetes service accounts. ToolHive never handles your raw passwords or +credentials; instead, it relies on signed identity tokens (usually JWTs) issued +by your trusted provider. + +**Why use OIDC?** + +- **Standard and interoperable:** You can connect ToolHive to any OIDC-compliant + IdP without custom code, supporting both human users and automated services. +- **Proven and secure:** Authentication is delegated to battle-tested identity + systems, which handle login UI, multi-factor authentication, and password + storage. +- **Decoupled identity management:** You can use your existing SSO/IdP + infrastructure, making onboarding and management seamless. +- **Flexible for users and services:** OIDC supports both interactive user login + (for example, Google sign-in) and service-to-service authentication (for + example, Kubernetes service account tokens). + +### Real-world scenarios + +- **User login via Google (OIDC):** You can run an MCP server that requires + authentication using your Google credentials. ToolHive delegates login to + Google, receives a signed ID token, and uses it to authenticate you. +- **Service-to-service auth with Kubernetes:** If you run a microservice in a + Kubernetes cluster, it can present its service account token (an OIDC JWT) to + ToolHive. ToolHive validates the token using the cluster's OIDC issuer and + JWKS URL, enabling secure, automated authentication for your internal + services. + +### JWT-based authentication + +ToolHive uses JSON Web Tokens (JWTs) for authentication. JWTs are compact, +self-contained tokens that securely transmit identity information. Each JWT has +three parts: + +1. **Header:** Metadata about the token +2. **Payload:** Claims about the entity (typically you or your service) +3. **Signature:** Ensures the token hasn't been altered + +### Authentication flow + +The authentication process follows these steps: + +1. **Token acquisition:** You obtain a JWT from your identity provider. +2. **Token presentation:** You include the JWT in your requests to ToolHive. +3. **Token validation:** ToolHive validates the JWT's signature, expiration, and + claims. +4. **Identity extraction:** ToolHive extracts your identity information from the + validated JWT. + +```mermaid +flowchart TD + Client -->|OIDC Token| ToolHive + ToolHive -->|Validate Token| OIDC_Provider[OIDC Provider] + ToolHive -->|Evaluate Cedar Policy| Cedar_Authorizer[Cedar Authorizer] + Cedar_Authorizer -->|Permit| MCP_Server + Cedar_Authorizer -->|Deny| Denied[403 Forbidden] +``` + +### Identity providers + +ToolHive can integrate with: + +- Google +- GitHub +- Microsoft Entra ID (Azure AD) +- Okta +- Auth0 +- Kubernetes (service account tokens) +- Any provider that supports OIDC + +This flexibility lets you use your existing identity infrastructure for both +users and services, reducing operational overhead and improving security. + +## Authorization framework + +After authentication, ToolHive enforces authorization using Amazon's Cedar +policy language. ToolHive acts as a gateway in front of MCP servers, handling +all authorization checks before requests reach the server logic. This means MCP +servers do not need to implement their own OAuth or custom authorization +logic—ToolHive centralizes and standardizes access control. + +**Key features of ToolHive's authorization:** + +- **Cedar policy language:** Cedar is a flexible, expressive, and formally + verified language for access control, supporting both role-based (RBAC) and + attribute-based (ABAC) rules. +- **Policy enforcement point:** ToolHive blocks unauthorized requests before + they reach the MCP server, reducing risk and simplifying server code. +- **Secure-by-default:** Authorization is explicit—if a request is not + explicitly permitted, it is denied. Deny rules take precedence over permit + rules (deny overrides). + +### Cedar policy language + +Cedar policies express authorization rules in a clear, declarative syntax: + +```text +permit|forbid(principal, action, resource) when { conditions }; +``` + +- `permit` or `forbid`: Whether to allow or deny the operation +- `principal`: The entity making the request (the client) +- `action`: The operation being performed +- `resource`: The object being accessed +- `conditions`: Optional conditions that must be satisfied + +### Authorization components + +ToolHive's authorization framework consists of: + +1. **Cedar authorizer:** Evaluates Cedar policies to determine if a request is + authorized +2. **Authorization middleware:** Extracts information from MCP requests and uses + the Cedar Authorizer +3. **Configuration:** A JSON or YAML file that specifies the Cedar policies and + entities + +### Authorization flow + +When a request arrives at an MCP server with authorization enabled: + +1. The JWT middleware authenticates the client and adds JWT claims to the + request context +2. The authorization middleware extracts information from the request + (principal, action, resource, and any arguments) +3. The Cedar authorizer evaluates policies to determine if the request is + authorized +4. If authorized, the request proceeds; otherwise, a 403 Forbidden response is + returned + +```mermaid +flowchart TD + Client -->|JWT| ToolHive + ToolHive -->|Validate JWT| JWT_Middleware + JWT_Middleware -->|Extract Claims| Authz_Middleware + Authz_Middleware -->|Evaluate Cedar Policies| Cedar_Authorizer + Cedar_Authorizer -->|Permit| MCP_Server + Cedar_Authorizer -->|Deny| Denied[403 Forbidden] +``` + +## MCP-specific entities + +In the context of MCP servers, Cedar policies use the following entities: + +### Principal + +The client making the request, identified by the `sub` claim in the JWT token: + +- Format: `Client::` +- Example: `Client::user123` + +### Action + +The operation being performed on an MCP feature: + +- Format: `Action::` +- Examples: + - `Action::"call_tool"`: Call a tool + - `Action::"get_prompt"`: Get a prompt + - `Action::"read_resource"`: Read a resource + - `Action::"list_tools"`: List available tools + +### Resource + +The object being accessed: + +- Format: `::` +- Examples: + - `Tool::"weather"`: The weather tool + - `Prompt::"greeting"`: The greeting prompt + - `Resource::"data"`: The data resource + +## Policy examples + +Cedar policies can express a wide range of authorization rules: + +### Basic access control + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather"); +``` + +This policy allows any authenticated client to call the weather tool. + +### Role-based access control (RBAC) + +```text +permit(principal, action == Action::"call_tool", resource) when { + principal.claim_roles.contains("admin") +}; +``` + +This policy allows clients with the "admin" role to call any tool. + +### Attribute-based access control (ABAC) + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"sensitive_data") when { + principal.claim_roles.contains("data_analyst") && + resource.arg_data_level <= principal.claim_clearance_level +}; +``` + +This policy allows data analysts to access sensitive data, but only if their +clearance level is sufficient. + +## JWT claims and tool arguments + +ToolHive makes JWT claims and tool arguments available in Cedar policies: + +### JWT claims + +Claims from the JWT are added with a `claim_` prefix: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + principal.claim_name == "John Doe" +}; +``` + +This policy allows only clients with the name "John Doe" to call the weather +tool. + +### Tool arguments + +Arguments from tool calls are added with an `arg_` prefix: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + resource.arg_location == "New York" || resource.arg_location == "London" +}; +``` + +This policy allows any client to call the weather tool, but only for the +locations "New York" and "London". + +## Policy evaluation and secure defaults + +ToolHive's policy evaluation follows a secure-by-default, least-privilege model: + +1. If any `forbid` policy matches, the request is denied (deny precedence) +2. If any `permit` policy matches, the request is authorized +3. If no policy matches, the request is denied (default deny) + +This means that `forbid` policies always override `permit` policies, and any +request not explicitly permitted is denied. This approach minimizes risk and +ensures that only authorized actions are allowed. + +## Security and operational benefits + +ToolHive's authentication and authorization approach provides several key +benefits: + +- **Separation of concerns:** Authentication and authorization are handled + independently, following best practices. +- **Integration with existing systems:** Use your existing identity + infrastructure (SSO, IdPs, Kubernetes, etc.). +- **Centralized, flexible policy model:** Define precise, auditable access rules + in a single place—no need to modify MCP server code. +- **Secure by default:** Requests are denied unless explicitly permitted by + policy, with deny precedence for maximum safety. +- **Auditable and versionable:** Policies are clear, declarative, and can be + tracked in version control for compliance and review. +- **Developer and operator friendly:** ToolHive acts as a smart proxy, so you + don't need to implement complex OAuth or custom auth logic in every server. + +## Example scenarios + +### Multi-tenant environments + +In multi-tenant environments, you can use policies to isolate tenants: + +```text +permit(principal, action, resource) when { + principal.claim_tenant_id == resource.tenant_id +}; +``` + +This ensures that clients can only access resources belonging to their tenant. + +### Data sensitivity levels + +For data with different sensitivity levels: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"data_access") when { + principal.claim_clearance_level >= resource.arg_data_sensitivity +}; +``` + +This ensures that clients can only access data within their clearance level. + +### Geographic restrictions + +For geographically restricted resources: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"geo_restricted") when { + principal.claim_location in ["US", "Canada", "Mexico"] +}; +``` + +This restricts access based on the client's location. + +## Related information + +- For practical steps to configure authentication and authorization, see + [Authentication and authorization](../how-to/authentication-authorization.md) +- For security best practices, see + [Security reference](../reference/security.md) +- For container security details, see + [Container security model](container-security-model.md) +- For detailed Cedar policy syntax, see + [Cedar documentation](https://docs.cedarpolicy.com/) + +--- + +### ToolHive vs. MCP Specification + +The official Model Context Protocol (MCP) specification recommends OAuth +2.1-based authorization for HTTP transports, which can require each MCP server +to implement OAuth endpoints and manage tokens. ToolHive takes a different +approach: it centralizes authentication and authorization in its proxy layer, +using OIDC for authentication and Cedar for fine-grained authorization. This +means you don't need to implement OAuth flows or scope management in every +server—just configure ToolHive with your IdP and write clear policies. This +approach is more flexible, secure, and easier to manage for you and your team. diff --git a/docs/toolhive/concepts/cedar-policies.md b/docs/toolhive/concepts/cedar-policies.md new file mode 100644 index 00000000..3c15ad43 --- /dev/null +++ b/docs/toolhive/concepts/cedar-policies.md @@ -0,0 +1,411 @@ +--- +title: Cedar policies +description: + Writing and configuring Cedar policies for MCP server authorization. +sidebar_position: 51 +--- + +This document provides detailed guidance on writing and configuring Cedar +policies for MCP server authorization. You'll learn how to create effective +policies, configure authorization settings, and troubleshoot common issues. + +:::info + +For the conceptual overview of authentication and authorization, see +[Authentication and authorization framework](./auth-framework.md). + +::: + +## Cedar policy language + +Cedar policies express authorization rules in a clear, declarative syntax: + +```text +permit|forbid(principal, action, resource) when { conditions }; +``` + +- `permit` or `forbid`: Whether to allow or deny the operation +- `principal`: The entity making the request (the client) +- `action`: The operation being performed +- `resource`: The object being accessed +- `conditions`: Optional conditions that must be satisfied + +## MCP-specific entities + +In the context of MCP servers, Cedar policies use the following entities: + +### Principal + +The client making the request, identified by the `sub` claim in the JWT token: + +- Format: `Client::` +- Example: `Client::user123` + +### Action + +The operation being performed on an MCP feature: + +- Format: `Action::` +- Examples: + - `Action::"call_tool"`: Call a tool + - `Action::"get_prompt"`: Get a prompt + - `Action::"read_resource"`: Read a resource + - `Action::"list_tools"`: List available tools + +### Resource + +The object being accessed: + +- Format: `::` +- Examples: + - `Tool::"weather"`: The weather tool + - `Prompt::"greeting"`: The greeting prompt + - `Resource::"data"`: The data resource + +## Configuration formats + +You can configure Cedar authorization using either JSON or YAML format: + +### JSON configuration + +```json +{ + "version": "1.0", + "type": "cedarv1", + "cedar": { + "policies": [ + "permit(principal, action == Action::\"call_tool\", resource == Tool::\"weather\");", + "permit(principal, action == Action::\"get_prompt\", resource == Prompt::\"greeting\");", + "permit(principal, action == Action::\"read_resource\", resource == Resource::\"data\");" + ], + "entities_json": "[]" + } +} +``` + +### YAML configuration + +```yaml +version: '1.0' +type: cedarv1 +cedar: + policies: + - 'permit(principal, action == Action::"call_tool", resource == + Tool::"weather");' + - 'permit(principal, action == Action::"get_prompt", resource == + Prompt::"greeting");' + - 'permit(principal, action == Action::"read_resource", resource == + Resource::"data");' + entities_json: '[]' +``` + +### Configuration fields + +- `version`: The version of the configuration format +- `type`: The type of authorization configuration (currently only `cedarv1` is + supported) +- `cedar`: The Cedar-specific configuration + - `policies`: An array of Cedar policy strings + - `entities_json`: A JSON string representing Cedar entities + +## Writing effective policies + +Understanding how to write Cedar policies is crucial for securing your MCP +servers effectively. This section provides practical guidance for creating +policies that match your security requirements. + +### Basic policy patterns + +Start with simple policies and build complexity as needed: + +#### Allow specific tool access + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather"); +``` + +This policy allows any authenticated client to call the weather tool. It's +useful when you want to provide broad access to specific functionality. + +#### Allow specific user access + +```text +permit(principal == Client::"user123", action == Action::"call_tool", resource); +``` + +This policy allows a specific user to call any tool. Use this pattern when you +need to grant broad permissions to trusted users. + +### Role-based access control (RBAC) + +RBAC policies use roles from JWT claims to determine access: + +```text +permit(principal, action == Action::"call_tool", resource) when { + principal.claim_roles.contains("admin") +}; +``` + +This policy allows clients with the "admin" role to call any tool. RBAC is +effective when you have well-defined roles in your organization. + +### Attribute-based access control (ABAC) + +ABAC policies use multiple attributes to make fine-grained decisions: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"sensitive_data") when { + principal.claim_roles.contains("data_analyst") && + resource.arg_data_level <= principal.claim_clearance_level +}; +``` + +This policy allows data analysts to access sensitive data, but only if their +clearance level is sufficient. ABAC provides the most flexibility for complex +security requirements. + +## Working with JWT claims + +JWT claims from your identity provider become available in policies with a +`claim_` prefix. You can use these claims in two ways: + +### On the principal entity + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + principal.claim_name == "John Doe" +}; +``` + +### In the context + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + context.claim_name == "John Doe" +}; +``` + +Both approaches work identically. Choose the one that makes your policies more +readable. + +## Working with tool arguments + +Tool arguments become available in policies with an `arg_` prefix. This lets you +create policies based on the specific parameters of requests: + +### On the resource entity + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + resource.arg_location == "New York" || resource.arg_location == "London" +}; +``` + +### In the context + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { + context.arg_location == "New York" || context.arg_location == "London" +}; +``` + +This policy allows weather tool calls only for specific locations, demonstrating +how you can control access based on request parameters. + +## List operations and filtering + +List operations (`tools/list`, `prompts/list`, `resources/list`) work +differently from other operations. They're always allowed, but the response is +automatically filtered based on what the user can actually access: + +- `tools/list` shows only tools the user can call (based on `call_tool` + policies) +- `prompts/list` shows only prompts the user can get (based on `get_prompt` + policies) +- `resources/list` shows only resources the user can read (based on + `read_resource` policies) + +You don't need to write explicit policies for list operations. Instead, focus on +the underlying access policies, and the lists will be filtered automatically. + +For example, if you have this policy: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"weather"); +``` + +Then `tools/list` will only show the "weather" tool for that user. + +## Policy evaluation and secure defaults + +Understanding how Cedar evaluates policies helps you write more effective and +secure authorization rules. + +### Evaluation order + +ToolHive's policy evaluation follows a secure-by-default, least-privilege model: + +1. **Deny precedence:** If any `forbid` policy matches, the request is denied +2. **Permit evaluation:** If any `permit` policy matches, the request is + authorized +3. **Default deny:** If no policy matches, the request is denied + +This means that `forbid` policies always override `permit` policies, and any +request not explicitly permitted is denied. This approach minimizes risk and +ensures that only authorized actions are allowed. + +### Designing secure policies + +When writing policies, follow these principles: + +**Start with least privilege:** Begin by denying everything, then add specific +permissions as needed. This approach is more secure than starting with broad +permissions and trying to restrict them. + +**Use explicit deny sparingly:** While `forbid` policies can be useful, they can +also make your policy set harder to understand. In most cases, the default deny +behavior is sufficient. + +**Test your policies:** Always test policies with real requests to ensure they +work as expected. Pay special attention to edge cases and error conditions. + +## Advanced policy examples + +### Combining JWT claims and tool arguments + +You can combine JWT claims and tool arguments in your policies to create more +sophisticated authorization rules: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"sensitive_data") when { + principal.claim_roles.contains("data_analyst") && + resource.arg_data_level <= principal.claim_clearance_level +}; +``` + +This policy allows clients with the "data_analyst" role to access the +sensitive_data tool, but only if their clearance level (from JWT claims) is +sufficient for the requested data level (from tool arguments). + +### Multi-tenant environments + +In multi-tenant environments, you can use policies to isolate tenants: + +```text +permit(principal, action, resource) when { + principal.claim_tenant_id == resource.tenant_id +}; +``` + +This ensures that clients can only access resources belonging to their tenant. + +### Data sensitivity levels + +For data with different sensitivity levels: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"data_access") when { + principal.claim_clearance_level >= resource.arg_data_sensitivity +}; +``` + +This ensures that clients can only access data within their clearance level. + +### Geographic restrictions + +For geographically restricted resources: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"geo_restricted") when { + principal.claim_location in ["US", "Canada", "Mexico"] +}; +``` + +This restricts access based on the client's location. + +### Time-based access + +For resources that should only be accessible during certain hours: + +```text +permit(principal, action == Action::"call_tool", resource == Tool::"business_hours") when { + context.current_hour >= 9 && context.current_hour <= 17 +}; +``` + +This restricts access to business hours only. + +## Entity attributes + +Cedar entities can have attributes that can be used in policy conditions. The +authorization middleware automatically adds JWT claims and tool arguments as +attributes to the principal entity. + +You can also define custom entities with attributes in the `entities_json` field +of the configuration file: + +```json +{ + "version": "1.0", + "type": "cedarv1", + "cedar": { + "policies": [ + "permit(principal, action == Action::\"call_tool\", resource) when { resource.owner == principal.claim_sub };" + ], + "entities_json": "[ + { + \"uid\": \"Tool::weather\", + \"attrs\": { + \"owner\": \"user123\" + } + } + ]" + } +} +``` + +This configuration defines a custom entity for the weather tool with an `owner` +attribute set to `user123`. The policy allows clients to call tools only if they +own them. + +## Troubleshooting policies + +When policies don't work as expected, follow this systematic approach: + +### Request is denied unexpectedly + +1. **Check policy syntax:** Ensure your policies are correctly formatted and use + valid Cedar syntax. +2. **Verify entity matching:** Confirm that the principal, action, and resource + in your policies match the actual values in the request. +3. **Test conditions:** Check that any conditions in your policies are satisfied + by the request context. +4. **Remember default deny:** If no policy explicitly permits the request, it + will be denied. + +### JWT claims are not available + +1. **Verify JWT middleware:** Ensure that JWT authentication is configured + correctly and running before authorization. +2. **Check token claims:** Verify that the JWT token contains the expected + claims. +3. **Use correct prefix:** Remember that JWT claims are available with a + `claim_` prefix. + +### Tool arguments are not available + +1. **Check request format:** Ensure that tool arguments are correctly specified + in the request. +2. **Use correct prefix:** Remember that tool arguments are available with an + `arg_` prefix. +3. **Verify argument names:** Confirm that the argument names in your policies + match those in the actual requests. + +## Related information + +- For the conceptual overview, see + [Authentication and authorization framework](./auth-framework.md) +- For detailed Cedar policy syntax, see + [Cedar documentation](https://docs.cedarpolicy.com/) + + diff --git a/docs/toolhive/guides-cli/auth.mdx b/docs/toolhive/guides-cli/auth.mdx new file mode 100644 index 00000000..2827a84b --- /dev/null +++ b/docs/toolhive/guides-cli/auth.mdx @@ -0,0 +1,165 @@ +--- +title: Authentication and authorization +description: + How to set up authentication and authorization for MCP servers using the + ToolHive CLI. +sidebar_position: 60 +--- + +import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; +import BasicCedarConfig from '../_partials/_basic-cedar-config.md'; +import AuthTroubleshooting from '../_partials/_auth-troubleshooting.md'; + +This guide shows you how to secure your MCP servers using OAuth-based +authentication and Cedar-based authorization policies with the ToolHive CLI. + +:::info + +Authentication and authorization are emerging capabilities in the MCP ecosystem. +The official MCP authorization specification is still evolving, and client +support for these features is limited. ToolHive is leading the way in +implementing these capabilities, but you may encounter some limitations with +certain clients. + +::: + +## Prerequisites + + + +## Set up authentication + +### Step 1: Gather OIDC configuration + +First, collect the necessary information from your identity provider: + +- Client ID +- Audience value +- Issuer URL +- JWKS URL (for key verification) + +### Step 2: Run an MCP server with authentication + +Use the following command to start an MCP server with authentication enabled: + +```bash +thv run \ + --oidc-audience \ + --oidc-client-id \ + --oidc-issuer \ + --oidc-jwks-url \ + +``` + +Replace the placeholders with your actual OIDC configuration. + +### Step 3: Test authentication + +Once your server is running with authentication enabled, clients must include a +valid JWT (JSON Web Token) in the `Authorization` header of each HTTP request. +The token should: + +- Be issued by your configured identity provider +- Include the correct audience claim +- Not be expired +- Have a valid signature + +:::note Client support limitations + +Client support for authentication is limited at this time. While some clients +support HTTP headers with SSE MCP client configurations, we do not recommend +passing JWT tokens in this way since it requires manual configuration and +exposes your token in plain text. + +We are working on a solution within ToolHive to securely handle authentication +for clients. Stay tuned for updates on this feature. + +::: + +:::note Obtaining JWT tokens + +How to obtain JWT tokens varies by identity provider and is outside the scope of +this guide. Consult your identity provider's documentation for specific +instructions on: + +- Interactive user authentication flows (OAuth 2.0 Authorization Code flow) +- Service-to-service authentication (Client Credentials flow) +- API token generation and management + +For Kubernetes service accounts, tokens are automatically mounted at +`/var/run/secrets/kubernetes.io/serviceaccount/token` in pods. + +::: + +To verify that authentication is working, you can use a tool like `curl` to make +a request to your MCP server: + +```bash +curl -H "Authorization: Bearer " \ + +``` + +## Set up authorization + +ToolHive uses Amazon's Cedar policy language for fine-grained, secure-by-default +authorization. Authorization is explicit: if a request is not explicitly +permitted by a policy, it is denied. Deny rules always take precedence over +permit rules. + +### Step 1: Create an authorization configuration file + + + +Save this file to a location accessible to ToolHive, such as +`/path/to/authz-config.json`. + +### Step 2: Run an MCP server with authorization + +Start your MCP server with the authorization configuration: + +```bash +thv run \ + --authz-config /path/to/authz-config.json \ + +``` + +You can combine this with the authentication parameters from the previous +section: + +```bash +thv run \ + --oidc-audience \ + --oidc-client-id \ + --oidc-issuer \ + --oidc-jwks-url \ + --authz-config /path/to/authz-config.json \ + +``` + +### Step 3: Test authorization + +Once your server is running with authorization enabled, clients will be subject +to the Cedar policies defined in your configuration file. When a client attempts +to perform an action, ToolHive will evaluate the request against the policies. +If the request is permitted, the action will proceed; otherwise, it will be +denied with a 403 Forbidden response. + +## Troubleshooting + + + +### CLI-specific issues + +If you're having issues with the CLI: + +1. Verify that the configuration file path is correct and accessible +2. Check that the server name matches an available MCP server +3. Ensure all required CLI flags are provided + +## Related information + +- For conceptual understanding, see + [Authentication and authorization framework](../concepts/auth-framework.md) +- For detailed Cedar policy syntax, see + [Cedar policies](../concepts/cedar-policies.md) and the + [Cedar documentation](https://docs.cedarpolicy.com/) diff --git a/docs/toolhive/guides-k8s/auth-k8s.mdx b/docs/toolhive/guides-k8s/auth-k8s.mdx new file mode 100644 index 00000000..0fe772bb --- /dev/null +++ b/docs/toolhive/guides-k8s/auth-k8s.mdx @@ -0,0 +1,384 @@ +--- +title: Authentication and authorization in Kubernetes +description: + How to set up authentication and authorization for MCP servers in Kubernetes + using the ToolHive Operator. +sidebar_position: 30 +--- + +import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; +import BasicCedarConfig from '../_partials/_basic-cedar-config.md'; +import AuthTroubleshooting from '../_partials/_auth-troubleshooting.md'; + +This guide shows you how to secure your MCP servers in Kubernetes using +authentication and authorization with the ToolHive Operator. + +:::info + +Authentication and authorization are emerging capabilities in the MCP ecosystem. +The official MCP authorization specification is still evolving, and client +support for these features is limited. ToolHive is leading the way in +implementing these capabilities, but you may encounter some limitations with +certain clients. + +::: + +## Prerequisites + +You'll need: + +- Kubernetes cluster with RBAC enabled +- ToolHive Operator installed (see + [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.md)) +- `kubectl` access to your cluster + +## Choose your authentication approach + +There are two main ways to authenticate with MCP servers running in Kubernetes: + +### Approach 1: External identity provider authentication + +Use this when you want to authenticate users or external services using +providers like Google, GitHub, Microsoft Entra ID, Okta, or Auth0. + +**Prerequisites for external IdP:** + + + +### Approach 2: Kubernetes service-to-service authentication + +Use this when you have client applications running in the same Kubernetes +cluster that need to call MCP servers. This approach uses Kubernetes service +account tokens for authentication. + +**Prerequisites for service-to-service:** + +- Client applications running in Kubernetes pods +- Understanding of Kubernetes service accounts and RBAC + +## Set up external identity provider authentication + +### Step 1: Create an MCPServer with external OIDC + +Create an `MCPServer` resource configured to accept tokens from your external +identity provider. The ToolHive proxy will handle authentication before +forwarding requests to the MCP server. + +```yaml title="mcp-server-external-auth.yaml" +apiVersion: toolhive.stacklok.dev/v1alpha1 +kind: MCPServer +metadata: + name: weather-server-external + namespace: toolhive-system +spec: + image: ghcr.io/stackloklabs/weather-mcp/server + transport: sse + port: 8080 + permissionProfile: + type: builtin + name: network + # Authentication configuration for external IdP + auth: + oidc: + audience: '' + clientId: '' + issuer: '' + jwksUrl: '' + resources: + limits: + cpu: '100m' + memory: '128Mi' + requests: + cpu: '50m' + memory: '64Mi' +``` + +Replace the OIDC placeholders with your actual identity provider configuration. + +### Step 2: Apply the MCPServer resource + +```bash +kubectl apply -f mcp-server-external-auth.yaml +``` + +### Step 3: Test external authentication + +Clients connecting to this MCP server must include a valid JWT token from your +configured identity provider in their requests. The ToolHive proxy will validate +the token before allowing access to the MCP server. + +:::note Obtaining JWT tokens + +How to obtain JWT tokens varies by identity provider and is outside the scope of +this guide. Consult your identity provider's documentation for specific +instructions on: + +- Interactive user authentication flows (OAuth 2.0 Authorization Code flow) +- Service-to-service authentication (Client Credentials flow) +- API token generation and management + +For Kubernetes service accounts, tokens are automatically mounted at +`/var/run/secrets/kubernetes.io/serviceaccount/token` in pods. + +::: + +## Set up Kubernetes service-to-service authentication + +This approach is ideal when you have client applications running in the same +Kubernetes cluster that need to call MCP servers. + +### Step 1: Create service account for client application + +Create a service account that your client application will use: + +```yaml title="client-service-account.yaml" +apiVersion: v1 +kind: ServiceAccount +metadata: + name: mcp-client + namespace: client-apps +``` + +```bash +kubectl apply -f client-service-account.yaml +``` + +### Step 2: Create MCPServer for service-to-service auth + +Create an `MCPServer` resource configured to accept Kubernetes service account +tokens: + +```yaml title="mcp-server-k8s-auth.yaml" +apiVersion: toolhive.stacklok.dev/v1alpha1 +kind: MCPServer +metadata: + name: weather-server-k8s + namespace: toolhive-system +spec: + image: ghcr.io/stackloklabs/weather-mcp/server + transport: sse + port: 8080 + permissionProfile: + type: builtin + name: network + # Authentication configuration for Kubernetes service accounts + auth: + oidc: + audience: 'toolhive' + clientId: 'mcp-client.client-apps.svc.cluster.local' + issuer: 'https://kubernetes.default.svc' + jwksUrl: 'https://kubernetes.default.svc/openid/v1/jwks' + resources: + limits: + cpu: '100m' + memory: '128Mi' + requests: + cpu: '50m' + memory: '64Mi' +``` + +This configuration only allows requests from pods using the `mcp-client` service +account in the `client-apps` namespace. + +```bash +kubectl apply -f mcp-server-k8s-auth.yaml +``` + +### Step 3: Deploy client application with service account + +Deploy your client application using the service account: + +```yaml title="client-app.yaml" +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mcp-client-app + namespace: client-apps +spec: + replicas: 1 + selector: + matchLabels: + app: mcp-client-app + template: + metadata: + labels: + app: mcp-client-app + spec: + serviceAccountName: mcp-client + containers: + - name: client + image: your-client-app:latest + env: + - name: MCP_SERVER_URL + value: 'http://weather-server-k8s.toolhive-system.svc.cluster.local:8080' +``` + +```bash +kubectl apply -f client-app.yaml +``` + +Your client application can now authenticate to the MCP server using its +Kubernetes service account token, which is automatically mounted at +`/var/run/secrets/kubernetes.io/serviceaccount/token`. + +## Set up authorization + +Both authentication approaches can use the same authorization configuration +using Cedar policies. + +### Step 1: Create authorization configuration + + + +### Step 2: Create a ConfigMap with policies + +Store your authorization configuration in a ConfigMap: + +```yaml title="authz-configmap.yaml" +apiVersion: v1 +kind: ConfigMap +metadata: + name: authz-config + namespace: toolhive-system +data: + authz-config.json: | + { + "version": "1.0", + "type": "cedarv1", + "cedar": { + "policies": [ + "permit(principal, action == Action::\"call_tool\", resource == Tool::\"weather\");", + "permit(principal == Client::\"alice123\", action == Action::\"call_tool\", resource == Tool::\"admin_tool\");", + "permit(principal, action == Action::\"call_tool\", resource) when { principal.claim_roles.contains(\"premium\") };" + ], + "entities_json": "[]" + } + } +``` + +```bash +kubectl apply -f authz-configmap.yaml +``` + +### Step 3: Update MCPServer to use authorization + +Add the authorization configuration to your `MCPServer` resources: + +```yaml title="mcp-server-with-authz.yaml" +apiVersion: toolhive.stacklok.dev/v1alpha1 +kind: MCPServer +metadata: + name: weather-server-with-authz + namespace: toolhive-system +spec: + image: ghcr.io/stackloklabs/weather-mcp/server + transport: sse + port: 8080 + permissionProfile: + type: builtin + name: network + # Authentication configuration + auth: + oidc: + audience: 'toolhive' + clientId: 'mcp-client.client-apps.svc.cluster.local' + issuer: 'https://kubernetes.default.svc' + jwksUrl: 'https://kubernetes.default.svc/openid/v1/jwks' + # Authorization configuration + authorization: + configMapName: authz-config + configMapKey: authz-config.json + resources: + limits: + cpu: '100m' + memory: '128Mi' + requests: + cpu: '50m' + memory: '64Mi' +``` + +```bash +kubectl apply -f mcp-server-with-authz.yaml +``` + +## Test your setup + +### Test external IdP authentication + +1. Deploy the external IdP configuration +2. Obtain a valid JWT token from your identity provider +3. Make a request to the MCP server including the token + +### Test service-to-service authentication + +1. Deploy both the MCP server and client application +2. Check that the client can successfully call the MCP server +3. Verify authentication in the ToolHive proxy logs: + +```bash +kubectl logs -n toolhive-system -l app.kubernetes.io/name=weather-server-k8s +``` + +### Test authorization + +1. Make requests that should be permitted by your policies +2. Make requests that should be denied +3. Check the proxy logs to see authorization decisions + +## Troubleshooting + + + +### Kubernetes-specific issues + +**MCPServer resource issues:** + +- Check the MCPServer status: `kubectl get mcpserver -n toolhive-system` +- Describe the resource for details: + `kubectl describe mcpserver weather-server-k8s -n toolhive-system` + +**Service account issues:** + +- Verify the service account exists: `kubectl get sa -n client-apps mcp-client` +- Check RBAC permissions if needed + +**ConfigMap mounting issues:** + +- Verify the ConfigMap exists: + `kubectl get configmap -n toolhive-system authz-config` +- Check the ConfigMap content: + `kubectl get configmap authz-config -n toolhive-system -o yaml` + +**OIDC configuration issues:** + +- For external IdP: Ensure the issuer URL is accessible from within the cluster +- For Kubernetes auth: Ensure the Kubernetes API server has OIDC enabled +- Check that the JWKS URL returns valid keys + +**Network connectivity:** + +- Verify pods can reach the Kubernetes API server +- Check cluster DNS resolution +- Test service-to-service connectivity: + `kubectl exec -n client-apps deployment/mcp-client-app -- curl http://weather-server-k8s.toolhive-system.svc.cluster.local:8080` + +**ToolHive Operator issues:** + +- Check operator logs: + `kubectl logs -n toolhive-system -l app.kubernetes.io/name=toolhive-operator` +- Verify the operator is running: `kubectl get pods -n toolhive-system` + +## Related information + +- For conceptual understanding, see + [Authentication and authorization framework](../concepts/auth-framework.md) +- For detailed Cedar policy syntax, see + [Cedar policies](../concepts/cedar-policies.md) +- For CLI deployment, see + [Secure MCP servers with authentication and authorization](../how-to/auth.mdx) +- For running MCP servers without authentication, see + [Run MCP servers in Kubernetes](./run-mcp-k8s.md) +- For ToolHive Operator installation, see + [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.md) +- For detailed Cedar policy syntax, see + [Cedar documentation](https://docs.cedarpolicy.com/) From 2e550a10a4f95aa33fd23d00b1dd4c131962dc7f Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Fri, 10 Oct 2025 22:01:21 -0400 Subject: [PATCH 2/4] Fix issues breaking the build Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> --- docs/toolhive/_partials/_basic-cedar-config.md | 8 ++++++-- docs/toolhive/_partials/_oidc-prerequisites.md | 8 ++++---- docs/toolhive/concepts/auth-framework.md | 2 +- .../concepts/authentication-authorization.md | 13 ++++--------- docs/toolhive/concepts/cedar-policies.md | 10 ++++------ docs/toolhive/guides-k8s/auth-k8s.mdx | 9 +++------ 6 files changed, 22 insertions(+), 28 deletions(-) diff --git a/docs/toolhive/_partials/_basic-cedar-config.md b/docs/toolhive/_partials/_basic-cedar-config.md index 8ab50c53..48afe9a9 100644 --- a/docs/toolhive/_partials/_basic-cedar-config.md +++ b/docs/toolhive/_partials/_basic-cedar-config.md @@ -24,5 +24,9 @@ format: You can also define custom resource attributes in `entities_json` for per-tool ownership or sensitivity labels. -> For more policy examples and advanced usage, see -> [Cedar policies](../concepts/cedar-policies.md). +:::tip + +For more policy examples and advanced usage, see +[Cedar policies](../concepts/cedar-policies.md). + +::: diff --git a/docs/toolhive/_partials/_oidc-prerequisites.md b/docs/toolhive/_partials/_oidc-prerequisites.md index a4c57f2d..3e6a2670 100644 --- a/docs/toolhive/_partials/_oidc-prerequisites.md +++ b/docs/toolhive/_partials/_oidc-prerequisites.md @@ -13,10 +13,10 @@ From your identity provider, you'll need: - Issuer URL - JWKS URL (for key verification) -> ToolHive uses OIDC to connect to your existing identity provider, so you can -> authenticate with your own credentials (for example, Google login) or with -> service account tokens (for example, in Kubernetes). ToolHive never sees your -> password, only signed tokens from your identity provider. +ToolHive uses OIDC to connect to your existing identity provider, so you can +authenticate with your own credentials (for example, Google login) or with +service account tokens (for example, in Kubernetes). ToolHive never sees your +password, only signed tokens from your identity provider. For background on authentication, authorization, and Cedar policy examples, see [Authentication and authorization framework](../concepts/auth-framework.md). diff --git a/docs/toolhive/concepts/auth-framework.md b/docs/toolhive/concepts/auth-framework.md index 6f60e7a1..48d94808 100644 --- a/docs/toolhive/concepts/auth-framework.md +++ b/docs/toolhive/concepts/auth-framework.md @@ -255,4 +255,4 @@ requirements. ## Related information - For detailed policy writing guidance, see - [Cedar policies](./cedar-policies.mdcedar-policies.md) + [Cedar policies](./cedar-policies.md) diff --git a/docs/toolhive/concepts/authentication-authorization.md b/docs/toolhive/concepts/authentication-authorization.md index a03ad002..f9a4ae0a 100644 --- a/docs/toolhive/concepts/authentication-authorization.md +++ b/docs/toolhive/concepts/authentication-authorization.md @@ -9,9 +9,6 @@ This document explains the concepts behind ToolHive's authentication and authorization framework, which secures MCP servers by verifying client identity and controlling access to resources. -> For step-by-step setup and troubleshooting, see -> [Securing MCP servers with authentication and authorization](../how-to/authentication-authorization.md). - ## Understanding authentication vs. authorization When you secure MCP servers, it's critical to understand the strong separation @@ -343,12 +340,10 @@ This restricts access based on the client's location. ## Related information -- For practical steps to configure authentication and authorization, see - [Authentication and authorization](../how-to/authentication-authorization.md) -- For security best practices, see - [Security reference](../reference/security.md) -- For container security details, see - [Container security model](container-security-model.md) +- For configuration and setup with the ToolHive CLI, see + [Authentication and authorization](../guides-cli/auth.mdx) +- For Kubernetes deployment, see + [Authentication and authorization in Kubernetes](../guides-k8s/auth-k8s.mdx) - For detailed Cedar policy syntax, see [Cedar documentation](https://docs.cedarpolicy.com/) diff --git a/docs/toolhive/concepts/cedar-policies.md b/docs/toolhive/concepts/cedar-policies.md index 3c15ad43..a26015dc 100644 --- a/docs/toolhive/concepts/cedar-policies.md +++ b/docs/toolhive/concepts/cedar-policies.md @@ -169,7 +169,7 @@ security requirements. JWT claims from your identity provider become available in policies with a `claim_` prefix. You can use these claims in two ways: -### On the principal entity +**On the principal entity:** ```text permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { @@ -177,7 +177,7 @@ permit(principal, action == Action::"call_tool", resource == Tool::"weather") wh }; ``` -### In the context +**In the context:** ```text permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { @@ -193,7 +193,7 @@ readable. Tool arguments become available in policies with an `arg_` prefix. This lets you create policies based on the specific parameters of requests: -### On the resource entity +**On the resource entity:** ```text permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { @@ -201,7 +201,7 @@ permit(principal, action == Action::"call_tool", resource == Tool::"weather") wh }; ``` -### In the context +**In the context:** ```text permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { @@ -407,5 +407,3 @@ When policies don't work as expected, follow this systematic approach: [Authentication and authorization framework](./auth-framework.md) - For detailed Cedar policy syntax, see [Cedar documentation](https://docs.cedarpolicy.com/) - - diff --git a/docs/toolhive/guides-k8s/auth-k8s.mdx b/docs/toolhive/guides-k8s/auth-k8s.mdx index 0fe772bb..88f6e485 100644 --- a/docs/toolhive/guides-k8s/auth-k8s.mdx +++ b/docs/toolhive/guides-k8s/auth-k8s.mdx @@ -373,12 +373,9 @@ kubectl logs -n toolhive-system -l app.kubernetes.io/name=weather-server-k8s - For conceptual understanding, see [Authentication and authorization framework](../concepts/auth-framework.md) - For detailed Cedar policy syntax, see - [Cedar policies](../concepts/cedar-policies.md) -- For CLI deployment, see - [Secure MCP servers with authentication and authorization](../how-to/auth.mdx) + [Cedar policies](../concepts/cedar-policies.md) and the + [Cedar documentation](https://docs.cedarpolicy.com/) - For running MCP servers without authentication, see - [Run MCP servers in Kubernetes](./run-mcp-k8s.md) + [Run MCP servers in Kubernetes](./run-mcp-k8s.mdx) - For ToolHive Operator installation, see [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.md) -- For detailed Cedar policy syntax, see - [Cedar documentation](https://docs.cedarpolicy.com/) From 3357e8d42dc41b62356c418e113c87a3a2a44d3f Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Fri, 10 Oct 2025 22:14:34 -0400 Subject: [PATCH 3/4] Add to sidebar, remove duplicate doc Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> --- docs/toolhive/concepts/auth-framework.md | 3 +- .../concepts/authentication-authorization.md | 361 ------------------ docs/toolhive/concepts/cedar-policies.md | 1 - docs/toolhive/guides-cli/auth.mdx | 1 - docs/toolhive/guides-k8s/auth-k8s.mdx | 3 +- sidebars.ts | 4 + 6 files changed, 6 insertions(+), 367 deletions(-) delete mode 100644 docs/toolhive/concepts/authentication-authorization.md diff --git a/docs/toolhive/concepts/auth-framework.md b/docs/toolhive/concepts/auth-framework.md index 48d94808..4e2e47bf 100644 --- a/docs/toolhive/concepts/auth-framework.md +++ b/docs/toolhive/concepts/auth-framework.md @@ -1,8 +1,7 @@ --- -title: Authentication and authorization framework +title: Authentication and authorization description: Understanding ToolHive's authentication and authorization framework concepts. -sidebar_position: 50 --- This document explains the concepts behind ToolHive's authentication and diff --git a/docs/toolhive/concepts/authentication-authorization.md b/docs/toolhive/concepts/authentication-authorization.md deleted file mode 100644 index f9a4ae0a..00000000 --- a/docs/toolhive/concepts/authentication-authorization.md +++ /dev/null @@ -1,361 +0,0 @@ ---- -title: Authentication and authorization -description: - Understanding ToolHive's authentication and authorization framework. -sidebar_position: 40 ---- - -This document explains the concepts behind ToolHive's authentication and -authorization framework, which secures MCP servers by verifying client identity -and controlling access to resources. - -## Understanding authentication vs. authorization - -When you secure MCP servers, it's critical to understand the strong separation -between: - -- **Authentication (authN):** Verifying the identity of clients connecting to - your MCP server ("Who are you?") -- **Authorization (authZ):** Determining what actions authenticated clients are - allowed to perform ("What can you do?") - -You should always perform authentication first, using a trusted identity -provider, and then apply authorization rules to determine what the authenticated -identity can do. ToolHive helps you follow this best practice by acting as a -gateway in front of your MCP servers. This approach lets you use proven identity -systems for authentication, while keeping your authorization policies clear, -flexible, and auditable. You don't need to add custom authentication or -authorization logic to every server—ToolHive handles it for you, consistently -and securely. - -## Authentication framework - -You use OpenID Connect (OIDC)—an identity layer built on top of OAuth 2.0—for -authentication in ToolHive. OIDC is a widely adopted, interoperable protocol -that lets you connect ToolHive to any OIDC-compliant identity provider (IdP), -such as Google, GitHub, Microsoft Entra ID (Azure AD), Okta, Auth0, or even -Kubernetes service accounts. ToolHive never handles your raw passwords or -credentials; instead, it relies on signed identity tokens (usually JWTs) issued -by your trusted provider. - -**Why use OIDC?** - -- **Standard and interoperable:** You can connect ToolHive to any OIDC-compliant - IdP without custom code, supporting both human users and automated services. -- **Proven and secure:** Authentication is delegated to battle-tested identity - systems, which handle login UI, multi-factor authentication, and password - storage. -- **Decoupled identity management:** You can use your existing SSO/IdP - infrastructure, making onboarding and management seamless. -- **Flexible for users and services:** OIDC supports both interactive user login - (for example, Google sign-in) and service-to-service authentication (for - example, Kubernetes service account tokens). - -### Real-world scenarios - -- **User login via Google (OIDC):** You can run an MCP server that requires - authentication using your Google credentials. ToolHive delegates login to - Google, receives a signed ID token, and uses it to authenticate you. -- **Service-to-service auth with Kubernetes:** If you run a microservice in a - Kubernetes cluster, it can present its service account token (an OIDC JWT) to - ToolHive. ToolHive validates the token using the cluster's OIDC issuer and - JWKS URL, enabling secure, automated authentication for your internal - services. - -### JWT-based authentication - -ToolHive uses JSON Web Tokens (JWTs) for authentication. JWTs are compact, -self-contained tokens that securely transmit identity information. Each JWT has -three parts: - -1. **Header:** Metadata about the token -2. **Payload:** Claims about the entity (typically you or your service) -3. **Signature:** Ensures the token hasn't been altered - -### Authentication flow - -The authentication process follows these steps: - -1. **Token acquisition:** You obtain a JWT from your identity provider. -2. **Token presentation:** You include the JWT in your requests to ToolHive. -3. **Token validation:** ToolHive validates the JWT's signature, expiration, and - claims. -4. **Identity extraction:** ToolHive extracts your identity information from the - validated JWT. - -```mermaid -flowchart TD - Client -->|OIDC Token| ToolHive - ToolHive -->|Validate Token| OIDC_Provider[OIDC Provider] - ToolHive -->|Evaluate Cedar Policy| Cedar_Authorizer[Cedar Authorizer] - Cedar_Authorizer -->|Permit| MCP_Server - Cedar_Authorizer -->|Deny| Denied[403 Forbidden] -``` - -### Identity providers - -ToolHive can integrate with: - -- Google -- GitHub -- Microsoft Entra ID (Azure AD) -- Okta -- Auth0 -- Kubernetes (service account tokens) -- Any provider that supports OIDC - -This flexibility lets you use your existing identity infrastructure for both -users and services, reducing operational overhead and improving security. - -## Authorization framework - -After authentication, ToolHive enforces authorization using Amazon's Cedar -policy language. ToolHive acts as a gateway in front of MCP servers, handling -all authorization checks before requests reach the server logic. This means MCP -servers do not need to implement their own OAuth or custom authorization -logic—ToolHive centralizes and standardizes access control. - -**Key features of ToolHive's authorization:** - -- **Cedar policy language:** Cedar is a flexible, expressive, and formally - verified language for access control, supporting both role-based (RBAC) and - attribute-based (ABAC) rules. -- **Policy enforcement point:** ToolHive blocks unauthorized requests before - they reach the MCP server, reducing risk and simplifying server code. -- **Secure-by-default:** Authorization is explicit—if a request is not - explicitly permitted, it is denied. Deny rules take precedence over permit - rules (deny overrides). - -### Cedar policy language - -Cedar policies express authorization rules in a clear, declarative syntax: - -```text -permit|forbid(principal, action, resource) when { conditions }; -``` - -- `permit` or `forbid`: Whether to allow or deny the operation -- `principal`: The entity making the request (the client) -- `action`: The operation being performed -- `resource`: The object being accessed -- `conditions`: Optional conditions that must be satisfied - -### Authorization components - -ToolHive's authorization framework consists of: - -1. **Cedar authorizer:** Evaluates Cedar policies to determine if a request is - authorized -2. **Authorization middleware:** Extracts information from MCP requests and uses - the Cedar Authorizer -3. **Configuration:** A JSON or YAML file that specifies the Cedar policies and - entities - -### Authorization flow - -When a request arrives at an MCP server with authorization enabled: - -1. The JWT middleware authenticates the client and adds JWT claims to the - request context -2. The authorization middleware extracts information from the request - (principal, action, resource, and any arguments) -3. The Cedar authorizer evaluates policies to determine if the request is - authorized -4. If authorized, the request proceeds; otherwise, a 403 Forbidden response is - returned - -```mermaid -flowchart TD - Client -->|JWT| ToolHive - ToolHive -->|Validate JWT| JWT_Middleware - JWT_Middleware -->|Extract Claims| Authz_Middleware - Authz_Middleware -->|Evaluate Cedar Policies| Cedar_Authorizer - Cedar_Authorizer -->|Permit| MCP_Server - Cedar_Authorizer -->|Deny| Denied[403 Forbidden] -``` - -## MCP-specific entities - -In the context of MCP servers, Cedar policies use the following entities: - -### Principal - -The client making the request, identified by the `sub` claim in the JWT token: - -- Format: `Client::` -- Example: `Client::user123` - -### Action - -The operation being performed on an MCP feature: - -- Format: `Action::` -- Examples: - - `Action::"call_tool"`: Call a tool - - `Action::"get_prompt"`: Get a prompt - - `Action::"read_resource"`: Read a resource - - `Action::"list_tools"`: List available tools - -### Resource - -The object being accessed: - -- Format: `::` -- Examples: - - `Tool::"weather"`: The weather tool - - `Prompt::"greeting"`: The greeting prompt - - `Resource::"data"`: The data resource - -## Policy examples - -Cedar policies can express a wide range of authorization rules: - -### Basic access control - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"weather"); -``` - -This policy allows any authenticated client to call the weather tool. - -### Role-based access control (RBAC) - -```text -permit(principal, action == Action::"call_tool", resource) when { - principal.claim_roles.contains("admin") -}; -``` - -This policy allows clients with the "admin" role to call any tool. - -### Attribute-based access control (ABAC) - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"sensitive_data") when { - principal.claim_roles.contains("data_analyst") && - resource.arg_data_level <= principal.claim_clearance_level -}; -``` - -This policy allows data analysts to access sensitive data, but only if their -clearance level is sufficient. - -## JWT claims and tool arguments - -ToolHive makes JWT claims and tool arguments available in Cedar policies: - -### JWT claims - -Claims from the JWT are added with a `claim_` prefix: - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { - principal.claim_name == "John Doe" -}; -``` - -This policy allows only clients with the name "John Doe" to call the weather -tool. - -### Tool arguments - -Arguments from tool calls are added with an `arg_` prefix: - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"weather") when { - resource.arg_location == "New York" || resource.arg_location == "London" -}; -``` - -This policy allows any client to call the weather tool, but only for the -locations "New York" and "London". - -## Policy evaluation and secure defaults - -ToolHive's policy evaluation follows a secure-by-default, least-privilege model: - -1. If any `forbid` policy matches, the request is denied (deny precedence) -2. If any `permit` policy matches, the request is authorized -3. If no policy matches, the request is denied (default deny) - -This means that `forbid` policies always override `permit` policies, and any -request not explicitly permitted is denied. This approach minimizes risk and -ensures that only authorized actions are allowed. - -## Security and operational benefits - -ToolHive's authentication and authorization approach provides several key -benefits: - -- **Separation of concerns:** Authentication and authorization are handled - independently, following best practices. -- **Integration with existing systems:** Use your existing identity - infrastructure (SSO, IdPs, Kubernetes, etc.). -- **Centralized, flexible policy model:** Define precise, auditable access rules - in a single place—no need to modify MCP server code. -- **Secure by default:** Requests are denied unless explicitly permitted by - policy, with deny precedence for maximum safety. -- **Auditable and versionable:** Policies are clear, declarative, and can be - tracked in version control for compliance and review. -- **Developer and operator friendly:** ToolHive acts as a smart proxy, so you - don't need to implement complex OAuth or custom auth logic in every server. - -## Example scenarios - -### Multi-tenant environments - -In multi-tenant environments, you can use policies to isolate tenants: - -```text -permit(principal, action, resource) when { - principal.claim_tenant_id == resource.tenant_id -}; -``` - -This ensures that clients can only access resources belonging to their tenant. - -### Data sensitivity levels - -For data with different sensitivity levels: - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"data_access") when { - principal.claim_clearance_level >= resource.arg_data_sensitivity -}; -``` - -This ensures that clients can only access data within their clearance level. - -### Geographic restrictions - -For geographically restricted resources: - -```text -permit(principal, action == Action::"call_tool", resource == Tool::"geo_restricted") when { - principal.claim_location in ["US", "Canada", "Mexico"] -}; -``` - -This restricts access based on the client's location. - -## Related information - -- For configuration and setup with the ToolHive CLI, see - [Authentication and authorization](../guides-cli/auth.mdx) -- For Kubernetes deployment, see - [Authentication and authorization in Kubernetes](../guides-k8s/auth-k8s.mdx) -- For detailed Cedar policy syntax, see - [Cedar documentation](https://docs.cedarpolicy.com/) - ---- - -### ToolHive vs. MCP Specification - -The official Model Context Protocol (MCP) specification recommends OAuth -2.1-based authorization for HTTP transports, which can require each MCP server -to implement OAuth endpoints and manage tokens. ToolHive takes a different -approach: it centralizes authentication and authorization in its proxy layer, -using OIDC for authentication and Cedar for fine-grained authorization. This -means you don't need to implement OAuth flows or scope management in every -server—just configure ToolHive with your IdP and write clear policies. This -approach is more flexible, secure, and easier to manage for you and your team. diff --git a/docs/toolhive/concepts/cedar-policies.md b/docs/toolhive/concepts/cedar-policies.md index a26015dc..1da7ee11 100644 --- a/docs/toolhive/concepts/cedar-policies.md +++ b/docs/toolhive/concepts/cedar-policies.md @@ -2,7 +2,6 @@ title: Cedar policies description: Writing and configuring Cedar policies for MCP server authorization. -sidebar_position: 51 --- This document provides detailed guidance on writing and configuring Cedar diff --git a/docs/toolhive/guides-cli/auth.mdx b/docs/toolhive/guides-cli/auth.mdx index 2827a84b..d2fa5a39 100644 --- a/docs/toolhive/guides-cli/auth.mdx +++ b/docs/toolhive/guides-cli/auth.mdx @@ -3,7 +3,6 @@ title: Authentication and authorization description: How to set up authentication and authorization for MCP servers using the ToolHive CLI. -sidebar_position: 60 --- import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; diff --git a/docs/toolhive/guides-k8s/auth-k8s.mdx b/docs/toolhive/guides-k8s/auth-k8s.mdx index 88f6e485..ac2921d2 100644 --- a/docs/toolhive/guides-k8s/auth-k8s.mdx +++ b/docs/toolhive/guides-k8s/auth-k8s.mdx @@ -1,9 +1,8 @@ --- -title: Authentication and authorization in Kubernetes +title: Authentication and authorization description: How to set up authentication and authorization for MCP servers in Kubernetes using the ToolHive Operator. -sidebar_position: 30 --- import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; diff --git a/sidebars.ts b/sidebars.ts index b0f2e50d..a6c916f0 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -90,6 +90,7 @@ const sidebars: SidebarsConfig = { ], }, 'toolhive/guides-cli/telemetry-and-metrics', + 'toolhive/guides-cli/auth', 'toolhive/guides-cli/advanced-cicd', { type: 'category', @@ -126,6 +127,7 @@ const sidebars: SidebarsConfig = { 'toolhive/guides-k8s/tool-config', 'toolhive/guides-k8s/telemetry-and-metrics', 'toolhive/guides-k8s/logging-infrastructure', + 'toolhive/guides-k8s/auth-k8s', 'toolhive/reference/crd-spec', ], }, @@ -144,6 +146,8 @@ const sidebars: SidebarsConfig = { 'toolhive/concepts/mcp-primer', 'toolhive/concepts/registry-criteria', 'toolhive/concepts/observability', + 'toolhive/concepts/auth-framework', + 'toolhive/concepts/cedar-policies', ], }, From 5a3d305907c3c42de1c0b086c9536fa364118ae3 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Fri, 17 Oct 2025 09:35:54 -0400 Subject: [PATCH 4/4] Rename files to mdx, fix up admonition syntax Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com> --- ...roubleshooting.md => _auth-troubleshooting.mdx} | 0 ...sic-cedar-config.md => _basic-cedar-config.mdx} | 2 +- ...dc-prerequisites.md => _oidc-prerequisites.mdx} | 2 +- .../{auth-framework.md => auth-framework.mdx} | 2 +- .../{cedar-policies.md => cedar-policies.mdx} | 4 ++-- docs/toolhive/guides-cli/auth.mdx | 14 +++++++------- docs/toolhive/guides-k8s/auth-k8s.mdx | 14 +++++++------- 7 files changed, 19 insertions(+), 19 deletions(-) rename docs/toolhive/_partials/{_auth-troubleshooting.md => _auth-troubleshooting.mdx} (100%) rename docs/toolhive/_partials/{_basic-cedar-config.md => _basic-cedar-config.mdx} (95%) rename docs/toolhive/_partials/{_oidc-prerequisites.md => _oidc-prerequisites.mdx} (98%) rename docs/toolhive/concepts/{auth-framework.md => auth-framework.mdx} (99%) rename docs/toolhive/concepts/{cedar-policies.md => cedar-policies.mdx} (99%) diff --git a/docs/toolhive/_partials/_auth-troubleshooting.md b/docs/toolhive/_partials/_auth-troubleshooting.mdx similarity index 100% rename from docs/toolhive/_partials/_auth-troubleshooting.md rename to docs/toolhive/_partials/_auth-troubleshooting.mdx diff --git a/docs/toolhive/_partials/_basic-cedar-config.md b/docs/toolhive/_partials/_basic-cedar-config.mdx similarity index 95% rename from docs/toolhive/_partials/_basic-cedar-config.md rename to docs/toolhive/_partials/_basic-cedar-config.mdx index 48afe9a9..b2abc4d8 100644 --- a/docs/toolhive/_partials/_basic-cedar-config.md +++ b/docs/toolhive/_partials/_basic-cedar-config.mdx @@ -27,6 +27,6 @@ ownership or sensitivity labels. :::tip For more policy examples and advanced usage, see -[Cedar policies](../concepts/cedar-policies.md). +[Cedar policies](../concepts/cedar-policies.mdx). ::: diff --git a/docs/toolhive/_partials/_oidc-prerequisites.md b/docs/toolhive/_partials/_oidc-prerequisites.mdx similarity index 98% rename from docs/toolhive/_partials/_oidc-prerequisites.md rename to docs/toolhive/_partials/_oidc-prerequisites.mdx index 3e6a2670..99e1cb66 100644 --- a/docs/toolhive/_partials/_oidc-prerequisites.md +++ b/docs/toolhive/_partials/_oidc-prerequisites.mdx @@ -19,4 +19,4 @@ service account tokens (for example, in Kubernetes). ToolHive never sees your password, only signed tokens from your identity provider. For background on authentication, authorization, and Cedar policy examples, see -[Authentication and authorization framework](../concepts/auth-framework.md). +[Authentication and authorization framework](../concepts/auth-framework.mdx). diff --git a/docs/toolhive/concepts/auth-framework.md b/docs/toolhive/concepts/auth-framework.mdx similarity index 99% rename from docs/toolhive/concepts/auth-framework.md rename to docs/toolhive/concepts/auth-framework.mdx index 4e2e47bf..ed71d5f7 100644 --- a/docs/toolhive/concepts/auth-framework.md +++ b/docs/toolhive/concepts/auth-framework.mdx @@ -254,4 +254,4 @@ requirements. ## Related information - For detailed policy writing guidance, see - [Cedar policies](./cedar-policies.md) + [Cedar policies](./cedar-policies.mdx) diff --git a/docs/toolhive/concepts/cedar-policies.md b/docs/toolhive/concepts/cedar-policies.mdx similarity index 99% rename from docs/toolhive/concepts/cedar-policies.md rename to docs/toolhive/concepts/cedar-policies.mdx index 1da7ee11..fca7eeb7 100644 --- a/docs/toolhive/concepts/cedar-policies.md +++ b/docs/toolhive/concepts/cedar-policies.mdx @@ -11,7 +11,7 @@ policies, configure authorization settings, and troubleshoot common issues. :::info For the conceptual overview of authentication and authorization, see -[Authentication and authorization framework](./auth-framework.md). +[Authentication and authorization framework](./auth-framework.mdx). ::: @@ -403,6 +403,6 @@ When policies don't work as expected, follow this systematic approach: ## Related information - For the conceptual overview, see - [Authentication and authorization framework](./auth-framework.md) + [Authentication and authorization framework](./auth-framework.mdx) - For detailed Cedar policy syntax, see [Cedar documentation](https://docs.cedarpolicy.com/) diff --git a/docs/toolhive/guides-cli/auth.mdx b/docs/toolhive/guides-cli/auth.mdx index d2fa5a39..1c6a0e19 100644 --- a/docs/toolhive/guides-cli/auth.mdx +++ b/docs/toolhive/guides-cli/auth.mdx @@ -5,9 +5,9 @@ description: ToolHive CLI. --- -import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; -import BasicCedarConfig from '../_partials/_basic-cedar-config.md'; -import AuthTroubleshooting from '../_partials/_auth-troubleshooting.md'; +import OidcPrerequisites from '../_partials/_oidc-prerequisites.mdx'; +import BasicCedarConfig from '../_partials/_basic-cedar-config.mdx'; +import AuthTroubleshooting from '../_partials/_auth-troubleshooting.mdx'; This guide shows you how to secure your MCP servers using OAuth-based authentication and Cedar-based authorization policies with the ToolHive CLI. @@ -63,7 +63,7 @@ The token should: - Not be expired - Have a valid signature -:::note Client support limitations +:::note[Client support limitations] Client support for authentication is limited at this time. While some clients support HTTP headers with SSE MCP client configurations, we do not recommend @@ -75,7 +75,7 @@ for clients. Stay tuned for updates on this feature. ::: -:::note Obtaining JWT tokens +:::note[Obtaining JWT tokens] How to obtain JWT tokens varies by identity provider and is outside the scope of this guide. Consult your identity provider's documentation for specific @@ -158,7 +158,7 @@ If you're having issues with the CLI: ## Related information - For conceptual understanding, see - [Authentication and authorization framework](../concepts/auth-framework.md) + [Authentication and authorization framework](../concepts/auth-framework.mdx) - For detailed Cedar policy syntax, see - [Cedar policies](../concepts/cedar-policies.md) and the + [Cedar policies](../concepts/cedar-policies.mdx) and the [Cedar documentation](https://docs.cedarpolicy.com/) diff --git a/docs/toolhive/guides-k8s/auth-k8s.mdx b/docs/toolhive/guides-k8s/auth-k8s.mdx index ac2921d2..f916b585 100644 --- a/docs/toolhive/guides-k8s/auth-k8s.mdx +++ b/docs/toolhive/guides-k8s/auth-k8s.mdx @@ -5,9 +5,9 @@ description: using the ToolHive Operator. --- -import OidcPrerequisites from '../_partials/_oidc-prerequisites.md'; -import BasicCedarConfig from '../_partials/_basic-cedar-config.md'; -import AuthTroubleshooting from '../_partials/_auth-troubleshooting.md'; +import OidcPrerequisites from '../_partials/_oidc-prerequisites.mdx'; +import BasicCedarConfig from '../_partials/_basic-cedar-config.mdx'; +import AuthTroubleshooting from '../_partials/_auth-troubleshooting.mdx'; This guide shows you how to secure your MCP servers in Kubernetes using authentication and authorization with the ToolHive Operator. @@ -28,7 +28,7 @@ You'll need: - Kubernetes cluster with RBAC enabled - ToolHive Operator installed (see - [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.md)) + [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.mdx)) - `kubectl` access to your cluster ## Choose your authentication approach @@ -370,11 +370,11 @@ kubectl logs -n toolhive-system -l app.kubernetes.io/name=weather-server-k8s ## Related information - For conceptual understanding, see - [Authentication and authorization framework](../concepts/auth-framework.md) + [Authentication and authorization framework](../concepts/auth-framework.mdx) - For detailed Cedar policy syntax, see - [Cedar policies](../concepts/cedar-policies.md) and the + [Cedar policies](../concepts/cedar-policies.mdx) and the [Cedar documentation](https://docs.cedarpolicy.com/) - For running MCP servers without authentication, see [Run MCP servers in Kubernetes](./run-mcp-k8s.mdx) - For ToolHive Operator installation, see - [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.md) + [Deploy the ToolHive Operator with Helm](./deploy-operator-helm.mdx)