Skip to content

[FEATURE][HELM]: Allow passing extra env variables via secret #1917

@mekedron

Description

@mekedron

Type of Feature

  • Enhancement to existing functionality
  • New feature or capability
  • New MCP-compliant server
  • New component or integration
  • Developer tooling or test improvement
  • Packaging, automation and deployment (ex: pypi, docker, quay.io, kubernetes, terraform)
  • Other (please describe below)

🧭 Epic

Title: External Secrets Integration for GitOps-Compatible Deployments

Goal: Enable users to inject secrets from external secret management solutions (ExternalSecrets Operator, Sealed Secrets, Vault, AWS Secrets Manager, etc.) into the MCP Gateway deployment without committing sensitive values to Git repositories.

Why now:

  • GitOps adoption is rapidly growing, with ArgoCD being one of the most popular CD tools
  • Current Helm chart requires secrets to be defined in values.yaml under mcpContextForge.secret, which must be committed to Git
  • Committing secrets to repositories violates security best practices and compliance requirements (SOC2, HIPAA, PCI-DSS)
  • Organizations using ArgoCD, Flux, or similar GitOps tools cannot securely deploy MCP Gateway without manual intervention or workarounds

📖 User Stories

US-1: DevOps Engineer - Reference External Secrets

As a: DevOps engineer using ArgoCD for GitOps deployments

I want: To reference Kubernetes Secrets created by ExternalSecrets Operator (or similar tools) in my MCP Gateway deployment

So that: I can maintain a secure GitOps workflow without committing sensitive credentials (JWT secrets, database passwords, API keys) to my Git repository

Acceptance Criteria:

Scenario: Deploy MCP Gateway with ExternalSecrets
  Given I have an ExternalSecret that syncs secrets from AWS Secrets Manager
  And the ExternalSecret creates a Kubernetes Secret named "mcp-gateway-external-secret"
  When I configure extraEnvVarsSecret in my Helm values to reference this secret
  Then the MCP Gateway pods should have environment variables from the external secret
  And the external secret values should override any defaults from the chart

Scenario: GitOps repository contains no plaintext secrets
  Given I have a GitOps repository with MCP Gateway Helm values
  When I configure the deployment to use extraEnvVarsSecret
  Then no sensitive values (passwords, keys, tokens) are stored in the repository
  And ArgoCD can deploy the application without manual secret injection

Scenario: External secret takes precedence over chart defaults
  Given the chart defines default values for JWT_SECRET_KEY in mcpContextForge.secret
  And I have an external secret with a production JWT_SECRET_KEY
  When I reference the external secret via extraEnvVarsSecret
  Then the production JWT_SECRET_KEY from the external secret is used
  And the default value is overridden
US-2: Platform Administrator - Environment-Specific Secrets

As a: Platform administrator managing multiple MCP Gateway environments

I want: To use different secret sources for different environments (dev, staging, production) without modifying the base Helm chart

So that: I can maintain environment-specific secrets in secure vaults while using the same GitOps workflow across all environments

Acceptance Criteria:

Scenario: Environment-specific secrets via ArgoCD ApplicationSet
  Given I have three environments: dev, staging, and production
  And each environment has its own ExternalSecret pointing to different vault paths
  When I deploy MCP Gateway using ArgoCD ApplicationSet
  Then each environment uses its own secrets from the corresponding vault
  And no cross-environment secret leakage occurs

Scenario: Optional external secrets for gradual migration
  Given I am migrating from inline secrets to ExternalSecrets
  When I configure extraEnvVarsSecret with optional: true
  Then the deployment succeeds even if the external secret doesn't exist yet
  And I can gradually migrate secrets without downtime

🏗 Architecture

Design Sketch

flowchart TD
    subgraph "Git Repository (Safe to Commit)"
        A[values.yaml<br/> extraEnvVarsSecret: secretRef]
        B[ArgoCD Application]
    end

    subgraph "Kubernetes Cluster"
        C[ArgoCD]
        D[ExternalSecrets Operator]
        E[AWS Secrets Manager<br/>Vault / Azure KV]
        F[Kubernetes Secret<br/>mcp-gateway-external-secret]
        G[MCP Gateway Deployment]
        H[MCP Gateway Pod]
    end

    A --> B
    B --> C
    C -->|Deploys| G
    E -->|Syncs| D
    D -->|Creates| F
    G -->|References via envFrom| F
    F -->|Injects env vars| H

    style A fill:#90EE90
    style B fill:#90EE90
    style E fill:#FFB6C1
    style F fill:#87CEEB
Loading

Current Flow (Insecure)

flowchart LR
    A[Developer] -->|Commits secrets| B[Git Repo]
    B -->|Contains plaintext| C[values.yaml]
    C -->|Deploys| D[MCP Gateway]

    style B fill:#FFB6C1
    style C fill:#FFB6C1
Loading

Proposed Flow (Secure)

flowchart LR
    A[Developer] -->|Commits reference only| B[Git Repo]
    B -->|No secrets| C[values.yaml]
    D[Secrets Manager] -->|ExternalSecrets| E[K8s Secret]
    C -->|References| E
    E -->|Injects| F[MCP Gateway]

    style B fill:#90EE90
    style C fill:#90EE90
    style D fill:#87CEEB
Loading

📋 Implementation Tasks

Phase 1: Helm Chart Values

  • Add extraEnvVarsSecret field to mcpContextForge in values.yaml
  • Add documentation comments explaining the feature
  • Add JSON schema validation in values.schema.json

Phase 2: Deployment Template

  • Modify deployment-mcpgateway.yaml to include extraEnvVarsSecret in envFrom
  • Ensure extra secrets load AFTER default envFrom (for override precedence)
  • Support both secretRef and configMapRef entries

Phase 3: Testing

  • Test with ExternalSecrets Operator
  • Test with HashiCorp Vault Secrets Operator
  • Test with Sealed Secrets
  • Test ArgoCD deployment workflow
  • Verify override precedence works correctly

Phase 4: Documentation

  • Update Helm chart README with examples
  • Add ArgoCD integration guide
  • Document migration path from inline secrets

⚙️ Configuration Examples

values.yaml Addition

mcpContextForge:
  # CUSTOM ENV-FROM OVERRIDES
  # Use this to inject additional secrets or configmaps (e.g., from
  # ExternalSecrets) that should be loaded AFTER the default envFrom.
  extraEnvVarsSecret: []
  # Example:
  #   extraEnvVarsSecret:
  #     - secretRef:
  #         name: my-external-secret
  #     - configMapRef:
  #         name: my-custom-config

deployment-mcpgateway.yaml Modification

envFrom:
  - secretRef:
      name: {{ include "mcp-stack.fullname" . }}-gateway-secret
  - configMapRef:
      name: {{ include "mcp-stack.fullname" . }}-gateway-config
  {{- with .Values.mcpContextForge.extraEnvVarsSecret }}
  {{- toYaml . | nindent 12 }}
  {{- end }}

Example: ExternalSecrets Operator with AWS Secrets Manager

# externalsecret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: mcp-gateway-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: mcp-gateway-external-secret
  data:
    - secretKey: JWT_SECRET_KEY
      remoteRef:
        key: prod/mcp-gateway
        property: jwt_secret
# values.yaml (safe to commit to Git)
mcpContextForge:
  extraEnvVarsSecret:
    - secretRef:
        name: mcp-gateway-external-secret

✅ Success Criteria

  • extraEnvVarsSecret field added to values.yaml with documentation
  • deployment-mcpgateway.yaml renders extra envFrom entries correctly
  • External secrets override default chart secrets
  • ArgoCD can deploy without plaintext secrets in Git
  • ExternalSecrets Operator integration works
  • HashiCorp Vault integration works
  • JSON schema validates the new field
  • Helm chart README updated with examples

🏁 Definition of Done

  • values.yaml updated with extraEnvVarsSecret field
  • values.schema.json updated with validation
  • deployment-mcpgateway.yaml template modified
  • Unit tests for template rendering pass
  • Integration tested with ExternalSecrets Operator
  • Integration tested with ArgoCD
  • Helm chart README updated
  • Helm chart version bumped
  • Code passes helm lint
  • PR reviewed and approved

🔗 MCP Standards Check

  • Change adheres to current MCP specifications
  • No breaking changes to existing MCP-compliant integrations
  • Feature is additive and backward-compatible

This is a Helm chart enhancement only. It does not modify any MCP protocol behavior, API endpoints, or core gateway functionality.


🔄 Alternatives Considered

Alternative Why Rejected
Helm post-render hooks Requires additional tooling, not natively supported by ArgoCD
ArgoCD Vault Plugin Requires specific plugin installation, not universal
Kustomize overlays Adds complexity, requires separate Kustomize layer
Manual secret creation Breaks GitOps principles, requires out-of-band operations
SealedSecrets only Vendor lock-in to Bitnami SealedSecrets
existingSecret field Would require significant refactoring

📓 Additional Context

Security Benefits

  • Enables compliance with SOC2, HIPAA, PCI-DSS
  • Supports secret rotation without Git commits
  • Integrates with enterprise secret management

GitOps Ecosystem Compatibility

  • ArgoCD: Full compatibility with Application and ApplicationSet
  • Flux CD: Works with HelmRelease resources
  • Rancher Fleet: Compatible with GitRepo bundles

Metadata

Metadata

Assignees

Labels

COULDP3: Nice-to-have features with minimal impact if left out; included if time permitsdatabaseenhancementNew feature or requesthelmHelm chart

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions