OLS-2575 Add denied_resources TOML config for openshift-mcp-server sidecar#1418
Conversation
Configure the shipped openshift-mcp-server sidecar to deny access to Kubernetes Secret and RBAC resources at the server level, so sensitive data never reaches the LLM. This replaces the aggressive substring matching in lightspeed-service that blocked legitimate operations (e.g., deployments referencing /var/run/secrets/ or secretRef). The operator now: - Generates a TOML config ConfigMap with denied_resources for v1/Secret and rbac.authorization.k8s.io/v1 - Mounts the config into the sidecar container - Passes --config flag to the sidecar (preserving --read-only and --port) - Manages the ConfigMap lifecycle (create/update/delete based on introspection enabled/disabled) This applies only to the shipped openshift-mcp-server sidecar. User-configured MCP servers (spec.mcpServers) are the user's responsibility to secure. Made-with: Cursor
42ee842 to
191e79a
Compare
| if cmExists { | ||
| r.GetLogger().Info("deleting MCP server config configmap", "configmap", OpenShiftMCPServerConfigCmName) | ||
| if err := r.Delete(ctx, foundCm); err != nil { | ||
| return fmt.Errorf("%s: %w", ErrGetMCPServerConfigMap, err) |
There was a problem hiding this comment.
ErrGetMCPServerConfigMap is a wrong error - you are deleting.
Maybe introduce a new constant
ErrDeleteMCPServerConfigMap = "failed to delete MCP server config configmap"
| @@ -108,14 +112,20 @@ func addOpenShiftMCPServerSidecar(r reconciler.Reconciler, cr *olsv1alpha1.OLSCo | |||
| AllowPrivilegeEscalation: &[]bool{false}[0], | |||
| ReadOnlyRootFilesystem: &[]bool{true}[0], | |||
| }, | |||
There was a problem hiding this comment.
This does not match the changes introduced by app server
There was a problem hiding this comment.
For this, maybe move a function from the app server to utils and use it in app server, lcore, postgres and console. Can be done in a separate PR
- Use correct ErrDeleteMCPServerConfigMap constant for delete failures (was incorrectly using ErrGetMCPServerConfigMap) - Properly distinguish NotFound vs other errors from Get, following the established codebase pattern (errors.IsNotFound check) - Remove unused CleanupOpenShiftMCPServerConfigMap (dead code — the ConfigMap has an owner reference and is cleaned up by the finalizer's generic owner-based deletion) Made-with: Cursor
Extract the restricted Pod Security profile SecurityContext helper from appserver into utils so all components use the same full restricted profile (AllowPrivilegeEscalation, ReadOnlyRootFilesystem, RunAsNonRoot, SeccompProfile, Capabilities). Previously lcore, postgres, and console only set two of five fields. This aligns all operator-managed containers to the same security posture. Made-with: Cursor
|
/lgtm |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: blublinsky The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
@onmete: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Description
Configure the shipped
openshift-mcp-serversidecar to deny access to Kubernetes Secret and RBAC resources at the server level, so sensitive data never reaches the LLM.The operator now:
ConfigMapwithdenied_resourcesentries forv1/Secretandrbac.authorization.k8s.io/v1/etc/mcp-server/config.toml--configflag to the openshift-mcp-server command (preserving--read-onlyand--port)introspectionEnabled)This applies only to the shipped openshift-mcp-server sidecar. User-configured MCP servers (
spec.mcpServers) are the user's responsibility to secure.When a denied resource is accessed, the MCP server returns an error
resource not allowed: <GVK>— the data never reaches the LLM.Type of change
Related Tickets & Documents
Checklist before requesting a review
Testing
internal/controller/utils/mcp_server_config_test.go— tests TOML content, ConfigMap generation, volume/mount helpers, config pathinternal/controller/appserver/assets_test.go— verifies--configflag in sidecar command, config volume and mount on deploymentinternal/controller/lcore/deployment_test.go— verifies--configflag, config volume/mount presence when introspection enabled, absence when disabledmake test)introspectionEnabled: trueand verify:openshift-mcp-server-configConfigMap exists with correct TOML content--config /etc/mcp-server/config.tomlin its commandresource not allowederrorintrospectionEnabled: falsedeletes the ConfigMap and removes the sidecarMade with Cursor