Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions deployments/charts/service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,17 @@ destination, but it cannot validate external DNS.
| `services.mcp.scopes` | OAuth scopes advertised in direct-provider mode; ignored when `oidcProxy.enabled` is true. | `[]` |
| `services.mcp.allowedOrigins` | Exact browser origins permitted on `/mcp`; native clients normally omit `Origin`. | `[]` |
| `services.mcp.requestTimeoutSeconds` | Total timeout for each MCP-initiated Gateway request, from 1 through 60 seconds. | `10` |
| `services.mcp.replicas` | Number of MCP replicas. Must remain `1` with `oidcProxy.enabled` because FastMCP 3.4.7 refresh serialization is process-local. | `1` |
| `services.mcp.replicas` | Number of MCP replicas. The OIDC proxy keeps its state in Redis, so it scales out. | `1` |
| `services.mcp.extraEnv` | Additional non-managed environment variables. It cannot override MCP host, port, Gateway origin, or request timeout. | `[]` |
| `services.mcp.extraVolumeMounts` | Additional MCP container volume mounts, including Vault-injected credential files. | `[]` |
| `services.mcp.extraVolumes` | Additional MCP pod volumes. | `[]` |
| `services.mcp.oidcProxy.enabled` | Enable FastMCP's built-in OIDC proxy inside the existing MCP process. It advertises CIMD and retains DCR as a compatibility fallback. | `false` |
| `services.mcp.oidcProxy.scope` | Full delegated scope URI advertised to MCP clients and requested upstream, normally `<resourceUrl>/access_as_user`. | `""` |
| `services.mcp.oidcProxy.trustedHttpsRedirectOrigins` | Exact HTTPS origins allowed for pre-registered web-client redirects; native clients use loopback redirects. | `[]` |
| `services.mcp.oidcProxy.oidc.configUrl` | Upstream OIDC discovery URL. | `""` |
| `services.mcp.oidcProxy.oidc.clientId` | Administrator-managed confidential OIDC application client ID. | `""` |
| `services.mcp.oidcProxy.oidc.clientSecretFile` | Mounted file containing the upstream OIDC client secret. | `/etc/osmo/mcp-auth/client-secret` |
| `services.mcp.oidcProxy.oidc.accessTokenIssuer` | Exact issuer required on upstream API access tokens. | `""` |
| `services.mcp.oidcProxy.oidc.accessTokenAudience` | Exact OSMO MCP resource audience required on upstream API access tokens; must equal `resourceUrl`. | `""` |
| `services.mcp.oidcProxy.oidc.accessTokenJwksUrl` | HTTPS JWKS URL used to verify upstream API access tokens. | `""` |
| `services.mcp.oidcProxy.oidc.accessTokenRequiredScope` | Short scope value required in the upstream access token's `scp` claim. | `access_as_user` |
| `services.mcp.oidcProxy.redis` | Redis connection used by FastMCP for registrations, authorization state, and encrypted upstream tokens; blank host/port inherit `services.redis`. | See `values.yaml` |
| `services.mcp.oidcProxy.redis.dbNumber` | Logical Redis database for proxy state. Host, port and TLS come from `services.redis`. | `1` |
| `services.mcp.oidcProxy.accessTokenTtlSeconds` | Lifetime of proxy access tokens, from 60 through 3600 seconds. | `600` |
| `services.mcp.oidcProxy.refreshTokenTtlSeconds` | Lifetime of proxy refresh tokens, from 300 through 604800 seconds. | `28800` |
| `services.mcp.oidcProxy.upstreamTimeoutSeconds` | Timeout for upstream OIDC requests, from 1 through 60 seconds. | `10` |
Expand All @@ -142,7 +138,7 @@ destination, but it cannot validate external DNS.
The in-process proxy follows OSMO's OIDC profile: a full delegated scope URI is requested
from the upstream provider while its short suffix is enforced in the verified
API access token. Register the single stable upstream redirect URI
`<resourceUrl origin>/auth/callback`. MCP clients still configure only `resourceUrl`.
`<resourceUrl origin>/mcp/auth/callback`. MCP clients still configure only `resourceUrl`.
CIMD-capable clients identify themselves with a hosted metadata document;
older clients can use FastMCP's `/register` DCR endpoint. Both paths use
authorization-code flow with PKCE and end in the same OSMO Gateway and semantic
Expand Down
8 changes: 0 additions & 8 deletions deployments/charts/service/ci/mcp-oidc-proxy-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,13 @@ services:
- http://localhost:6274
oidcProxy:
enabled: true
scope: https://osmo.example.com/mcp/access_as_user
trustedHttpsRedirectOrigins:
- https://trusted-client.example.com
oidc:
configUrl: https://login.example.com/example-tenant/v2.0/.well-known/openid-configuration
clientId: example-mcp-proxy-client
accessTokenIssuer: https://sts.example.com/example-tenant/
accessTokenAudience: https://osmo.example.com/mcp
accessTokenJwksUrl: https://login.example.com/example-tenant/discovery/v2.0/keys
accessTokenRequiredScope: access_as_user
redis:
serviceName: proxy-redis.example.internal
port: 6380
dbNumber: 14
tlsEnabled: true
passwordFile: /etc/osmo/mcp-auth/redis-password
keyPrefix: test:mcp-auth
existingSecret:
Expand Down
43 changes: 9 additions & 34 deletions deployments/charts/service/ci/validate-mcp-chart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,14 @@ assert_env_value "$MCP_MANIFEST" OSMO_MCP_AUTH_ENABLED false
assert_route_omits "$RENDERED_MANIFEST" osmo-mcp 'typed_per_filter_config:'

for expected in \
'name: OSMO_MCP_AUTH_ISSUER_URL' \
'name: OSMO_MCP_AUTH_RESOURCE_URL' \
'name: OSMO_MCP_AUTH_SCOPE' \
'name: OSMO_MCP_AUTH_REDIS_URL' \
'name: OSMO_MCP_AUTH_REDIS_CONNECT_TIMEOUT_SECONDS' \
'name: OSMO_MCP_AUTH_REDIS_OPERATION_TIMEOUT_SECONDS' \
'name: OSMO_MCP_AUTH_OIDC_CONFIG_URL' \
'name: OSMO_MCP_AUTH_OIDC_CLIENT_ID' \
'name: OSMO_MCP_AUTH_OIDC_CLIENT_SECRET_FILE' \
'name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_ISSUER' \
'name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_AUDIENCE' \
'name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_JWKS_URL' \
'name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_REQUIRED_SCOPE' \
'name: OSMO_MCP_AUTH_UPSTREAM_TIMEOUT_SECONDS' \
'secretName: mcp-oidc-proxy-secrets'; do
Expand Down Expand Up @@ -208,10 +204,14 @@ assert_route_contains "$PROXY_RENDERED_MANIFEST" mcp-health-not-public \
assert_route_contains "$PROXY_RENDERED_MANIFEST" mcp-health-not-public \
'envoy.filters.http.ext_authz:'
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_ENABLED true
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_ISSUER_URL https://osmo.example.com
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_RESOURCE_URL https://osmo.example.com/mcp
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_SCOPE https://osmo.example.com/mcp/access_as_user
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_REDIS_URL rediss://proxy-redis.example.internal:6380/14
assert_env_value "$PROXY_MCP_MANIFEST" OSMO_MCP_AUTH_REDIS_URL rediss://redis:6379/14

# The proxy keeps all state in Redis, so scaling out must render.
if ! helm template test-release "$CHART_DIR" -f "$PROXY_VALUES_FILE" \
--set 'services.mcp.replicas=2' >/dev/null 2>&1; then
fail "MCP OIDC proxy with two replicas failed to render"
fi

# FastMCP advertises its endpoints under /mcp; the gateway publishes that
# prefix and rewrites it off before forwarding to the root paths the MCP SDK
Expand Down Expand Up @@ -260,16 +260,6 @@ expect_render_failure "$PROXY_VALUES_FILE" \
'services.mcp.oidcProxy.enabled requires services.mcp.enabled=true' \
--set 'services.mcp.enabled=false'

expect_render_failure "$PROXY_VALUES_FILE" \
'OIDC proxy with multiple replicas' \
'services.mcp.replicas must be 1 when services.mcp.oidcProxy.enabled=true' \
--set 'services.mcp.replicas=2'

expect_render_failure "$PROXY_VALUES_FILE" \
'invalid OIDC proxy Redis port' \
'services.mcp.oidcProxy.redis.port must be between 1 and 65535' \
--set 'services.mcp.oidcProxy.redis.port=0'

expect_render_failure "$PROXY_VALUES_FILE" \
'OIDC proxy Redis database below range' \
'services.mcp.oidcProxy.redis.dbNumber must be between 0 and 15' \
Expand Down Expand Up @@ -315,16 +305,6 @@ expect_render_failure "$PROXY_VALUES_FILE" \
'services.mcp.oidcProxy.upstreamTimeoutSeconds must be between 1 and 60' \
--set 'services.mcp.oidcProxy.upstreamTimeoutSeconds=61'

expect_render_failure "$PROXY_VALUES_FILE" \
'OIDC access-token audience mismatch' \
'services.mcp.oidcProxy.oidc.accessTokenAudience must equal services.mcp.resourceUrl' \
--set 'services.mcp.oidcProxy.oidc.accessTokenAudience=https://other.example.com/mcp'

expect_render_failure "$PROXY_VALUES_FILE" \
'OIDC full scope mismatch' \
'services.mcp.oidcProxy.scope must equal services.mcp.resourceUrl followed by oidc.accessTokenRequiredScope' \
--set 'services.mcp.oidcProxy.scope=https://other.example.com/access_as_user'

expect_render_failure "$PROXY_VALUES_FILE" \
'relative OIDC client-secret path' \
'services.mcp.oidcProxy.oidc.clientSecretFile must be an absolute path' \
Expand All @@ -345,14 +325,9 @@ expect_render_failure "$PROXY_VALUES_FILE" \
'services.mcp.oidcProxy.redis.passwordFile must be <existingSecret.mountPath>/redis-password' \
--set 'services.mcp.oidcProxy.redis.passwordFile=/other/redis-password'

expect_render_failure "$PROXY_VALUES_FILE" \
'untrusted redirect origin with a path' \
'trustedHttpsRedirectOrigins entries must be exact HTTPS origins' \
--set 'services.mcp.oidcProxy.trustedHttpsRedirectOrigins[0]=https://trusted.example.com/callback'

expect_render_failure "$PROXY_VALUES_FILE" \
'managed OIDC proxy issuer override' \
'services.mcp.extraEnv must not override managed variable OSMO_MCP_AUTH_ISSUER_URL' \
--set-json 'services.mcp.extraEnv=[{"name":"OSMO_MCP_AUTH_ISSUER_URL","value":"https://evil.example.com"}]'
'services.mcp.extraEnv must not override managed variable OSMO_MCP_AUTH_OIDC_CLIENT_ID' \
--set-json 'services.mcp.extraEnv=[{"name":"OSMO_MCP_AUTH_OIDC_CLIENT_ID","value":"evil-client"}]'

echo 'MCP chart validation passed'
63 changes: 3 additions & 60 deletions deployments/charts/service/templates/mcp-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,66 +25,30 @@
{{- if not (regexMatch "^([1-9]|[1-5][0-9]|60)$" $requestTimeoutSeconds) }}
{{- fail "services.mcp.requestTimeoutSeconds must be between 1 and 60" }}
{{- end }}
{{- $scope := "" }}
{{- $oidcConfigUrl := "" }}
{{- $oidcClientId := "" }}
{{- $oidcClientSecretFile := "" }}
{{- $oidcAccessTokenIssuer := "" }}
{{- $oidcAccessTokenAudience := "" }}
{{- $oidcAccessTokenJwksUrl := "" }}
{{- $oidcAccessTokenRequiredScope := "" }}
{{- $redisKeyPrefix := "" }}
{{- $redisUrl := "" }}
{{- if $oidcProxyEnabled }}
{{- if ne (int $mcp.replicas) 1 }}
{{- fail "services.mcp.replicas must be 1 when services.mcp.oidcProxy.enabled=true" }}
{{- end }}
{{- if not (kindIs "slice" $oidcProxy.trustedHttpsRedirectOrigins) }}
{{- fail "services.mcp.oidcProxy.trustedHttpsRedirectOrigins must be a list" }}
{{- end }}
{{- range $origin := $oidcProxy.trustedHttpsRedirectOrigins }}
{{- if or (not (kindIs "string" $origin)) (not (regexMatch "^https://[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?(:[0-9]{1,5})?$" $origin)) }}
{{- fail "services.mcp.oidcProxy.trustedHttpsRedirectOrigins entries must be exact HTTPS origins" }}
{{- end }}
{{- $originPortSuffix := regexFind ":[0-9]+$" $origin }}
{{- if $originPortSuffix }}
{{- $originPort := trimPrefix ":" $originPortSuffix | int }}
{{- if or (lt $originPort 1) (gt $originPort 65535) }}
{{- fail "services.mcp.oidcProxy.trustedHttpsRedirectOrigins ports must be between 1 and 65535" }}
{{- end }}
{{- end }}
{{- end }}
{{- $scope = required "services.mcp.oidcProxy.scope is required when the OIDC proxy is enabled" $oidcProxy.scope }}
{{- $oidcConfigUrl = required "services.mcp.oidcProxy.oidc.configUrl is required when the OIDC proxy is enabled" $oidcProxy.oidc.configUrl }}
{{- $oidcClientId = required "services.mcp.oidcProxy.oidc.clientId is required when the OIDC proxy is enabled" $oidcProxy.oidc.clientId }}
{{- $oidcClientSecretFile = required "services.mcp.oidcProxy.oidc.clientSecretFile is required when the OIDC proxy is enabled" $oidcProxy.oidc.clientSecretFile }}
{{- $oidcAccessTokenIssuer = required "services.mcp.oidcProxy.oidc.accessTokenIssuer is required when the OIDC proxy is enabled" $oidcProxy.oidc.accessTokenIssuer }}
{{- $oidcAccessTokenAudience = required "services.mcp.oidcProxy.oidc.accessTokenAudience is required when the OIDC proxy is enabled" $oidcProxy.oidc.accessTokenAudience }}
{{- $oidcAccessTokenJwksUrl = required "services.mcp.oidcProxy.oidc.accessTokenJwksUrl is required when the OIDC proxy is enabled" $oidcProxy.oidc.accessTokenJwksUrl }}
{{- $oidcAccessTokenRequiredScope = required "services.mcp.oidcProxy.oidc.accessTokenRequiredScope is required when the OIDC proxy is enabled" $oidcProxy.oidc.accessTokenRequiredScope }}
{{- if not (regexMatch "^[A-Za-z0-9:._~-]{1,128}$" $oidcAccessTokenRequiredScope) }}
{{- fail "services.mcp.oidcProxy.oidc.accessTokenRequiredScope must be one non-empty scope" }}
{{- end }}
{{- if or (gt (len $oidcAccessTokenAudience) 2048) (not (regexMatch "^[^[:space:][:cntrl:]]+$" $oidcAccessTokenAudience)) }}
{{- fail "services.mcp.oidcProxy.oidc.accessTokenAudience must be one non-empty value without whitespace or control characters" }}
{{- end }}
{{- if ne $oidcAccessTokenAudience $mcpResourceUrl }}
{{- fail "services.mcp.oidcProxy.oidc.accessTokenAudience must equal services.mcp.resourceUrl" }}
{{- end }}
{{- if ne $scope (printf "%s/%s" $mcpResourceUrl $oidcAccessTokenRequiredScope) }}
{{- fail "services.mcp.oidcProxy.scope must equal services.mcp.resourceUrl followed by oidc.accessTokenRequiredScope" }}
{{- end }}
{{- $oidcHttpsUrlPattern := "^https://[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?(:[0-9]{1,5})?(/[A-Za-z0-9._~%!$&'()*+,;=:@/-]*)?$" }}
{{- if not (regexMatch $oidcHttpsUrlPattern $oidcConfigUrl) }}
{{- fail "services.mcp.oidcProxy.oidc.configUrl must be an absolute HTTPS URL without query or fragment" }}
{{- end }}
{{- if not (regexMatch $oidcHttpsUrlPattern $oidcAccessTokenIssuer) }}
{{- fail "services.mcp.oidcProxy.oidc.accessTokenIssuer must be an absolute HTTPS issuer without query or fragment" }}
{{- end }}
{{- if not (regexMatch $oidcHttpsUrlPattern $oidcAccessTokenJwksUrl) }}
{{- fail "services.mcp.oidcProxy.oidc.accessTokenJwksUrl must be an absolute HTTPS URL without query or fragment" }}
{{- end }}
{{- range $name, $url := dict "configUrl" $oidcConfigUrl "accessTokenIssuer" $oidcAccessTokenIssuer "accessTokenJwksUrl" $oidcAccessTokenJwksUrl }}
{{- range $name, $url := dict "configUrl" $oidcConfigUrl "accessTokenIssuer" $oidcAccessTokenIssuer }}
{{- $portMatch := regexFind ":[0-9]+(/|$)" $url }}
{{- if $portMatch }}
{{- $urlPort := trimSuffix "/" (trimPrefix ":" $portMatch) | int }}
Expand All @@ -96,14 +60,8 @@
{{- if not (hasPrefix "/" $oidcClientSecretFile) }}
{{- fail "services.mcp.oidcProxy.oidc.clientSecretFile must be an absolute path" }}
{{- end }}
{{- $redisHost := $oidcProxy.redis.serviceName | default .Values.services.redis.serviceName | required "services.mcp.oidcProxy.redis.serviceName or services.redis.serviceName is required" }}
{{- $redisHost := .Values.services.redis.serviceName | required "services.redis.serviceName is required when the MCP OIDC proxy is enabled" }}
Comment thread
jiaenren marked this conversation as resolved.
{{- $redisPort := .Values.services.redis.port }}
{{- if not (kindIs "invalid" $oidcProxy.redis.port) }}
{{- $redisPort = $oidcProxy.redis.port }}
{{- end }}
{{- if or (lt (int $redisPort) 1) (gt (int $redisPort) 65535) }}
{{- fail "services.mcp.oidcProxy.redis.port must be between 1 and 65535" }}
{{- end }}
{{- if or (lt (int $oidcProxy.redis.dbNumber) 0) (gt (int $oidcProxy.redis.dbNumber) 15) }}
{{- fail "services.mcp.oidcProxy.redis.dbNumber must be between 0 and 15" }}
{{- end }}
Expand Down Expand Up @@ -146,7 +104,7 @@
{{- fail "services.mcp.oidcProxy.existingSecret.redisPasswordKey is required when redis.passwordFile is configured" }}
{{- end }}
{{- end }}
{{- $redisScheme := ternary "rediss" "redis" $oidcProxy.redis.tlsEnabled }}
{{- $redisScheme := ternary "rediss" "redis" .Values.services.redis.tlsEnabled }}
{{- $redisUrl = printf "%s://%s:%v/%v" $redisScheme $redisHost $redisPort $oidcProxy.redis.dbNumber }}
{{- end }}
{{- if not (kindIs "slice" $mcp.allowedOrigins) }}
Expand All @@ -164,10 +122,7 @@
"OSMO_MCP_REQUEST_TIMEOUT_SECONDS"
"OSMO_MCP_ALLOWED_ORIGINS"
"OSMO_MCP_AUTH_ENABLED"
"OSMO_MCP_AUTH_ISSUER_URL"
"OSMO_MCP_AUTH_RESOURCE_URL"
"OSMO_MCP_AUTH_SCOPE"
"OSMO_MCP_AUTH_TRUSTED_HTTPS_REDIRECT_ORIGINS"
"OSMO_MCP_AUTH_REDIS_URL"
"OSMO_MCP_AUTH_REDIS_PASSWORD_FILE"
"OSMO_MCP_AUTH_REDIS_KEY_PREFIX"
Expand All @@ -177,8 +132,6 @@
"OSMO_MCP_AUTH_OIDC_CLIENT_ID"
"OSMO_MCP_AUTH_OIDC_CLIENT_SECRET_FILE"
"OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_ISSUER"
"OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_AUDIENCE"
"OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_JWKS_URL"
"OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_REQUIRED_SCOPE"
"OSMO_MCP_AUTH_ACCESS_TOKEN_TTL_SECONDS"
"OSMO_MCP_AUTH_REFRESH_TOKEN_TTL_SECONDS"
Expand Down Expand Up @@ -258,14 +211,8 @@ spec:
- name: OSMO_MCP_AUTH_ENABLED
value: {{ $oidcProxyEnabled | quote }}
{{- if $oidcProxyEnabled }}
- name: OSMO_MCP_AUTH_ISSUER_URL
value: {{ $gatewayUrl | quote }}
- name: OSMO_MCP_AUTH_RESOURCE_URL
value: {{ $mcpResourceUrl | quote }}
- name: OSMO_MCP_AUTH_SCOPE
value: {{ $scope | quote }}
- name: OSMO_MCP_AUTH_TRUSTED_HTTPS_REDIRECT_ORIGINS
value: {{ join "," $oidcProxy.trustedHttpsRedirectOrigins | quote }}
- name: OSMO_MCP_AUTH_REDIS_URL
value: {{ $redisUrl | quote }}
{{- if $oidcProxy.redis.passwordFile }}
Expand All @@ -286,10 +233,6 @@ spec:
value: {{ $oidcClientSecretFile | quote }}
- name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_ISSUER
value: {{ $oidcAccessTokenIssuer | quote }}
- name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_AUDIENCE
value: {{ $oidcAccessTokenAudience | quote }}
- name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_JWKS_URL
value: {{ $oidcAccessTokenJwksUrl | quote }}
- name: OSMO_MCP_AUTH_OIDC_ACCESS_TOKEN_REQUIRED_SCOPE
value: {{ $oidcAccessTokenRequiredScope | quote }}
- name: OSMO_MCP_AUTH_ACCESS_TOKEN_TTL_SECONDS
Expand Down
27 changes: 7 additions & 20 deletions deployments/charts/service/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ services:
##
enabled: false

## Number of MCP replicas. Keep this at 1 while oidcProxy is enabled;
## FastMCP 3.4.7 serializes refreshes within one process.
## Number of MCP replicas. The OIDC proxy keeps all of its state in Redis,
## so more than one replica is supported.
Comment thread
jiaenren marked this conversation as resolved.
##
replicas: 1

Expand Down Expand Up @@ -204,36 +204,23 @@ services:
oidcProxy:
enabled: false

## Full delegated scope URI advertised to MCP clients and requested from
## the upstream provider, normally <resourceUrl>/access_as_user.
##
scope: ""

## Public HTTPS redirect origins allowed for pre-registered web clients.
## Native clients use dynamically allocated loopback redirects.
##
trustedHttpsRedirectOrigins: []

## Upstream OpenID Connect provider. Register the fixed redirect URL
## <resourceUrl origin>/auth/callback on this confidential application.
## <resourceUrl origin>/mcp/auth/callback on this confidential application.
##
oidc:
configUrl: ""
clientId: ""
clientSecretFile: /etc/osmo/mcp-auth/client-secret
accessTokenIssuer: ""
accessTokenAudience: ""
accessTokenJwksUrl: ""
accessTokenRequiredScope: access_as_user

## Redis stores proxy registrations, authorization state, and encrypted
## upstream tokens. Empty serviceName/port inherit services.redis.
## upstream tokens. Host, port and TLS come from services.redis; only the
## logical database is chosen here, so proxy state stays isolated from
## OSMO's other Redis users.
##
redis:
serviceName: ""
port: null
dbNumber: 0
tlsEnabled: true
dbNumber: 1
passwordFile: ""
keyPrefix: osmo:mcp-fastmcp
connectTimeoutSeconds: 3
Expand Down
Loading
Loading