diff --git a/common/api/generated/types.gen.ts b/common/api/generated/types.gen.ts index c3d254c80..fec617aaf 100644 --- a/common/api/generated/types.gen.ts +++ b/common/api/generated/types.gen.ts @@ -376,6 +376,14 @@ export type AuthserverOAuth2UpstreamRunConfig = { * TokenEndpoint is the URL for the OAuth token endpoint. */ token_endpoint?: string + /** + * TokenEndpointAuthMethod selects how the client authenticates at the OAuth token + * endpoint. When empty and a client secret is configured, client_secret_basic is + * used, matching the RFC 7591 default for confidential clients. Set this to + * client_secret_post only for providers that require credentials in the request body. + * Public clients without a secret use the "none" method. + */ + token_endpoint_auth_method?: string token_response_mapping?: AuthserverTokenResponseMappingRunConfig userinfo?: AuthserverUserInfoRunConfig } @@ -419,6 +427,7 @@ export type AuthserverOidcUpstreamRunConfig = { * Mutually exclusive with ClientSecretEnvVar. Optional for public clients using PKCE. */ client_secret_file?: string + dcr_config?: AuthserverDcrUpstreamConfig /** * InsecureAllowHTTP permits a plain-HTTP issuer URL and HTTP discovery * endpoints for this upstream. Only for in-cluster development environments @@ -1681,6 +1690,14 @@ export type GithubComStacklokToolhivePkgRunnerRunConfig = { * Note: "sse" is deprecated; use "streamable-http" instead. */ proxy_mode?: 'sse' | 'streamable-http' + /** + * ProxyReadTimeout bounds reading the entire request (headers + body) on the + * proxy HTTP server, expressed as a Go duration string (e.g. "30s", "1m"). + * Empty uses the proxy default (30s). Negative durations and values that fail + * time.ParseDuration are rejected at runtime. Applies to all HTTP transports. + * String (not time.Duration) keeps the wire format unit-explicit. + */ + proxy_read_timeout?: string /** * Publish lists ports to publish to the host in format "hostPort:containerPort" */ @@ -2768,6 +2785,11 @@ export type PkgApiV1CreateRequest = { * Port for the HTTP proxy to listen on */ proxy_port?: number + /** + * Maximum time to read a complete MCP proxy request, expressed as a Go duration string. + * Empty or zero uses the default timeout of 30 seconds. + */ + proxy_read_timeout?: string /** * Registry is the optional registry name to resolve the server from (e.g. "default"). */ @@ -3233,8 +3255,12 @@ export type PkgApiV1PushSkillRequest = { */ identity_token?: string /** - * Key is the path to a cosign private key used to sign the pushed - * artifact + * Key is the path to a cosign private key, resolved on the server's + * filesystem. Accepted only when the request carries the secret capability + * from the owner-protected local server discovery file; other requests are + * refused with 403, since honoring one would let an untrusted caller have + * the server sign with any key it can read. Use IdentityToken when calling + * a remote or manually configured server. */ key?: string /** @@ -3580,6 +3606,11 @@ export type PkgApiV1UpdateRequest = { * Port for the HTTP proxy to listen on */ proxy_port?: number + /** + * Maximum time to read a complete MCP proxy request, expressed as a Go duration string. + * Empty or zero uses the default timeout of 30 seconds. + */ + proxy_read_timeout?: string runtime_config?: TemplatesRuntimeConfig /** * Secret parameters to inject @@ -6820,6 +6851,12 @@ export type PostApiV1BetaSkillsPushData = { [key: string]: unknown } | PkgApiV1PushSkillRequest + headers?: { + /** + * Local discovery capability (required with request.key) + */ + 'X-Toolhive-Key-Signing-Capability'?: string + } path?: never query?: never url: '/api/v1beta/skills/push' @@ -6830,6 +6867,10 @@ export type PostApiV1BetaSkillsPushErrors = { * Bad Request */ 400: string + /** + * Forbidden (key signing requires the local discovery capability) + */ + 403: string /** * Not Found */ diff --git a/common/api/openapi.json b/common/api/openapi.json index d298efede..8f027e81e 100644 --- a/common/api/openapi.json +++ b/common/api/openapi.json @@ -330,6 +330,10 @@ "description": "TokenEndpoint is the URL for the OAuth token endpoint.", "type": "string" }, + "token_endpoint_auth_method": { + "description": "TokenEndpointAuthMethod selects how the client authenticates at the OAuth token\nendpoint. When empty and a client secret is configured, client_secret_basic is\nused, matching the RFC 7591 default for confidential clients. Set this to\nclient_secret_post only for providers that require credentials in the request body.\nPublic clients without a secret use the \"none\" method.", + "type": "string" + }, "token_response_mapping": { "$ref": "#/components/schemas/authserver.TokenResponseMappingRunConfig" }, @@ -369,6 +373,9 @@ "description": "ClientSecretFile is the path to a file containing the OAuth 2.0 client secret.\nMutually exclusive with ClientSecretEnvVar. Optional for public clients using PKCE.", "type": "string" }, + "dcr_config": { + "$ref": "#/components/schemas/authserver.DCRUpstreamConfig" + }, "insecure_allow_http": { "description": "InsecureAllowHTTP permits a plain-HTTP issuer URL and HTTP discovery\nendpoints for this upstream. Only for in-cluster development environments\n(e.g. Dex served over HTTP in a kind cluster) where TLS is not available.\nNever set this in production.", "type": "boolean" @@ -1765,6 +1772,11 @@ "enum": ["sse", "streamable-http"], "type": "string" }, + "proxy_read_timeout": { + "description": "ProxyReadTimeout bounds reading the entire request (headers + body) on the\nproxy HTTP server, expressed as a Go duration string (e.g. \"30s\", \"1m\").\nEmpty uses the proxy default (30s). Negative durations and values that fail\ntime.ParseDuration are rejected at runtime. Applies to all HTTP transports.\nString (not time.Duration) keeps the wire format unit-explicit.", + "example": "30s", + "type": "string" + }, "publish": { "description": "Publish lists ports to publish to the host in format \"hostPort:containerPort\"", "items": { @@ -3258,6 +3270,11 @@ "description": "Port for the HTTP proxy to listen on", "type": "integer" }, + "proxy_read_timeout": { + "description": "Maximum time to read a complete MCP proxy request, expressed as a Go duration string.\nEmpty or zero uses the default timeout of 30 seconds.", + "example": "30s", + "type": "string" + }, "registry": { "description": "Registry is the optional registry name to resolve the server from (e.g. \"default\").", "type": "string" @@ -3782,7 +3799,7 @@ "type": "string" }, "key": { - "description": "Key is the path to a cosign private key used to sign the pushed\nartifact", + "description": "Key is the path to a cosign private key, resolved on the server's\nfilesystem. Accepted only when the request carries the secret capability\nfrom the owner-protected local server discovery file; other requests are\nrefused with 403, since honoring one would let an untrusted caller have\nthe server sign with any key it can read. Use IdentityToken when calling\na remote or manually configured server.", "type": "string" }, "no_sign": { @@ -4168,6 +4185,11 @@ "description": "Port for the HTTP proxy to listen on", "type": "integer" }, + "proxy_read_timeout": { + "description": "Maximum time to read a complete MCP proxy request, expressed as a Go duration string.\nEmpty or zero uses the default timeout of 30 seconds.", + "example": "30s", + "type": "string" + }, "runtime_config": { "$ref": "#/components/schemas/templates.RuntimeConfig" }, @@ -8389,6 +8411,16 @@ "/api/v1beta/skills/push": { "post": { "description": "Push a built skill artifact to a remote registry", + "parameters": [ + { + "description": "Local discovery capability (required with request.key)", + "in": "header", + "name": "X-Toolhive-Key-Signing-Capability", + "schema": { + "type": "string" + } + } + ], "requestBody": { "content": { "application/json": { @@ -8430,6 +8462,16 @@ }, "description": "Bad Request" }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + }, + "description": "Forbidden (key signing requires the local discovery capability)" + }, "404": { "content": { "application/json": { diff --git a/utils/constants.ts b/utils/constants.ts index 9dae87e8b..ee6f34d1a 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -3,4 +3,4 @@ * This is managed by Renovate and updated automatically when new versions are released. * renovate: datasource=github-releases depName=stacklok/toolhive versioning=semver */ -export const TOOLHIVE_VERSION = process.env.THV_VERSION ?? 'v0.47.0' +export const TOOLHIVE_VERSION = process.env.THV_VERSION ?? 'v0.48.0'