From 527cf18da623d9fdf6cd2715d0f151ee87ed3f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Delion?= Date: Thu, 13 Nov 2025 17:30:04 +0100 Subject: [PATCH 1/2] fix(deployment): Fix naming and some conditions --- .github/workflows/ci.yml | 11 +- .github/workflows/release.yml | 10 +- helm/mcp-server/CONTRIBUTING.md | 351 ----------------- helm/mcp-server/Chart.yaml | 5 +- helm/mcp-server/DOCKER.md | 342 ---------------- helm/mcp-server/INSTALL.md | 293 -------------- helm/mcp-server/README.md | 367 ------------------ .../examples/values-production.yaml | 2 +- helm/mcp-server/examples/values-secops.yaml | 37 -- helm/mcp-server/templates/NOTES.txt | 2 +- helm/mcp-server/templates/deployment.yaml | 4 +- helm/mcp-server/tests/deployment_test.yaml | 2 +- helm/mcp-server/tests/hpa_test.yaml | 2 +- helm/mcp-server/tests/ingress_test.yaml | 2 +- helm/mcp-server/tests/service_test.yaml | 2 +- .../mcp-server/tests/serviceaccount_test.yaml | 2 +- helm/mcp-server/values.yaml | 2 +- 17 files changed, 21 insertions(+), 1415 deletions(-) delete mode 100644 helm/mcp-server/CONTRIBUTING.md delete mode 100644 helm/mcp-server/DOCKER.md delete mode 100644 helm/mcp-server/INSTALL.md delete mode 100644 helm/mcp-server/README.md delete mode 100644 helm/mcp-server/examples/values-secops.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a65a54..8b94c1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,12 +81,6 @@ jobs: helm template mcp-server ./helm/mcp-server \ --values ./helm/mcp-server/examples/values-production.yaml - - name: Validate secops values - run: | - echo "Validating helm/mcp-server/examples/values-secops.yaml..." - helm template mcp-server ./helm/mcp-server \ - --values ./helm/mcp-server/examples/values-secops.yaml - - name: Lint Helm Chart run: | echo "Linting Helm chart..." @@ -104,11 +98,12 @@ jobs: - name: Set up Helm uses: azure/setup-helm@v4 with: - version: latest + # the latest version break on helm plugin install https://github.com/helm-unittest/helm-unittest.git + version: 3.19.0 - name: Install Helm Unittest Plugin run: | - helm plugin install https://github.com/helm-unittest/helm-unittest.git --verify=false + helm plugin install https://github.com/helm-unittest/helm-unittest.git - name: Run Helm unit tests run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e51f2b9..cb2b3ef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,25 +109,27 @@ jobs: -p ${{ secrets.GITHUB_TOKEN }} CHART_VERSION=$(grep "^version:" ./helm/mcp-server/Chart.yaml | cut -d' ' -f2 | tr -d '"') + REPO_OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]') helm push "${{ steps.package.outputs.chart-path }}" \ - oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/helm-charts + oci://${{ env.REGISTRY }}/${REPO_OWNER}/helm-charts - echo "✅ Chart published to: ${{ env.REGISTRY }}/${{ github.repository_owner }}/helm-charts:${CHART_VERSION}" + echo "✅ Chart published to: ${{ env.REGISTRY }}/${REPO_OWNER}/helm-charts:${CHART_VERSION}" - name: Create summary run: | CHART_VERSION=$(grep "^version:" ./helm/mcp-server/Chart.yaml | cut -d' ' -f2 | tr -d '"') + REPO_OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]') echo "## ✅ Helm Chart Released" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Chart: mcp-server" >> $GITHUB_STEP_SUMMARY echo "Version: ${CHART_VERSION}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - echo "Published to: \`oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/helm-charts\`" >> $GITHUB_STEP_SUMMARY + echo "Published to: \`oci://${{ env.REGISTRY }}/${REPO_OWNER}/helm-charts\`" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Install with:" >> $GITHUB_STEP_SUMMARY echo '```bash' >> $GITHUB_STEP_SUMMARY - echo "helm pull oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/helm-charts/mcp-server --version ${CHART_VERSION}" >> $GITHUB_STEP_SUMMARY + echo "helm pull oci://${{ env.REGISTRY }}/${REPO_OWNER}/helm-charts/mcp-server --version ${CHART_VERSION}" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY publish-to-pypi: diff --git a/helm/mcp-server/CONTRIBUTING.md b/helm/mcp-server/CONTRIBUTING.md deleted file mode 100644 index 91a6b55..0000000 --- a/helm/mcp-server/CONTRIBUTING.md +++ /dev/null @@ -1,351 +0,0 @@ -# Contributing to the GitGuardian MCP Server Helm Chart - -Thank you for your interest in contributing to the GitGuardian MCP Server Helm chart! - -## Development Setup - -### Prerequisites - -- Kubernetes cluster (kind, minikube, or similar for local development) -- Helm 3.2.0+ -- kubectl configured to access your cluster -- Docker (for building images) - -### Local Development Cluster - -#### Using kind - -```bash -# Create a kind cluster -kind create cluster --name mcp-dev - -# Verify cluster is running -kubectl cluster-info --context kind-mcp-dev -``` - -#### Using minikube - -```bash -# Start minikube -minikube start - -# Enable ingress addon (if testing ingress) -minikube addons enable ingress -``` - -## Testing the Chart - -### Validate Chart Syntax - -```bash -# Lint the chart -helm lint helm/mcp-server - -# Validate templates render correctly -helm template test helm/mcp-server --debug - -# Render with specific values -helm template test helm/mcp-server -f helm/mcp-server/examples/values-production.yaml -``` - -### Dry Run Installation - -```bash -# Perform a dry run -helm install mcp-server helm/mcp-server \ - --dry-run --debug \ - --set gitguardian.personalAccessToken=test-token -``` - -### Install in Development - -```bash -# Create test secret -kubectl create secret generic gitguardian-pat-test \ - --from-literal=personal-access-token='test-token' - -# Install the chart -helm install mcp-server-test helm/mcp-server \ - --set gitguardian.existingSecret=gitguardian-pat-test \ - --set gitguardian.url=https://dashboard.gitguardian.com - -# Watch the deployment -kubectl get pods -w - -# Check for issues -kubectl describe pod -l app.kubernetes.io/name=gitguardian-mcp-server -``` - -### Testing Upgrades - -```bash -# Make changes to the chart -# Then upgrade -helm upgrade mcp-server-test helm/mcp-server \ - --set gitguardian.existingSecret=gitguardian-pat-test - -# Check rollout status -kubectl rollout status deployment/mcp-server-test - -# View revision history -helm history mcp-server-test -``` - -### Cleanup - -```bash -# Uninstall the release -helm uninstall mcp-server-test - -# Delete the secret -kubectl delete secret gitguardian-pat-test -``` - -## Chart Structure Guidelines - -### File Organization - -``` -helm/mcp-server/ -├── Chart.yaml # Chart metadata -├── values.yaml # Default values -├── templates/ -│ ├── _helpers.tpl # Template helpers -│ ├── deployment.yaml # Main deployment -│ ├── service.yaml # Service definition -│ ├── serviceaccount.yaml -│ ├── secret.yaml # Optional secret -│ ├── ingress.yaml # Optional ingress -│ ├── hpa.yaml # Optional HPA -│ └── NOTES.txt # Post-install notes -├── examples/ # Example configurations -├── README.md # User documentation -├── INSTALL.md # Installation guide -└── DOCKER.md # Docker guide -``` - -### Template Best Practices - -1. **Use helpers for repeated values** - ```yaml - {{- include "mcp-server.fullname" . }} - ``` - -2. **Make resources conditional** - ```yaml - {{- if .Values.ingress.enabled }} - # ingress resource - {{- end }} - ``` - -3. **Validate required values** - ```yaml - {{- if not .Values.gitguardian.existingSecret }} - {{- fail "gitguardian.existingSecret is required" }} - {{- end }} - ``` - -4. **Add annotations for checksums** - ```yaml - checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} - ``` - -5. **Use toYaml for complex structures** - ```yaml - {{- toYaml .Values.resources | nindent 12 }} - ``` - -### values.yaml Guidelines - -1. **Organize logically** - - Group related settings - - Use consistent indentation - - Add comments for clarity - -2. **Provide sensible defaults** - ```yaml - resources: - limits: - cpu: 1000m - memory: 512Mi - requests: - cpu: 100m - memory: 128Mi - ``` - -3. **Document all options** - ```yaml - # GitGuardian instance URL - # Examples: - # - US SaaS: https://dashboard.gitguardian.com - url: "https://dashboard.gitguardian.com" - ``` - -## Making Changes - -### Adding a New Template - -1. Create the template file in `templates/` -2. Add corresponding values in `values.yaml` -3. Test the template renders correctly -4. Update documentation - -Example: Adding a PodDisruptionBudget - -```yaml -# templates/pdb.yaml -{{- if .Values.podDisruptionBudget.enabled }} -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: - name: {{ include "mcp-server.fullname" . }} -spec: - minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} - selector: - matchLabels: - {{- include "mcp-server.selectorLabels" . | nindent 6 }} -{{- end }} -``` - -```yaml -# values.yaml -podDisruptionBudget: - enabled: false - minAvailable: 1 -``` - -### Modifying Existing Templates - -1. Review the template and understand current behavior -2. Make minimal, focused changes -3. Test with various value combinations -4. Update examples if needed -5. Document breaking changes - -### Version Bumping - -When making changes: - -- **Patch version** (0.1.0 -> 0.1.1): Bug fixes, no breaking changes -- **Minor version** (0.1.0 -> 0.2.0): New features, no breaking changes -- **Major version** (0.1.0 -> 1.0.0): Breaking changes - -Update `Chart.yaml`: -```yaml -version: 0.2.0 # Chart version -appVersion: "0.1.0" # App version -``` - -## Testing Checklist - -Before submitting a PR, verify: - -- [ ] `helm lint` passes without errors -- [ ] `helm template` renders all templates correctly -- [ ] Chart installs successfully in a test cluster -- [ ] All example values files work -- [ ] Documentation is updated -- [ ] NOTES.txt provides helpful information -- [ ] Security context is properly configured -- [ ] Resource limits are reasonable -- [ ] Secrets are handled securely - -## Common Scenarios to Test - -### Different Server Types - -```bash -# Test developer server -helm install test-dev helm/mcp-server \ - --set serverType=developer \ - --set gitguardian.existingSecret=pat - -# Test secops server -helm install test-secops helm/mcp-server \ - --set serverType=secops \ - --set gitguardian.existingSecret=pat -``` - -### With and Without Ingress - -```bash -# Without ingress -helm install test-no-ingress helm/mcp-server \ - --set gitguardian.existingSecret=pat - -# With ingress -helm install test-ingress helm/mcp-server \ - --set ingress.enabled=true \ - --set ingress.hosts[0].host=test.local \ - --set gitguardian.existingSecret=pat -``` - -### Different Image Modes - -```bash -# Git-based installation -helm install test-git helm/mcp-server \ - --set image.useDockerImage=false \ - --set gitguardian.existingSecret=pat - -# Docker image -helm install test-docker helm/mcp-server \ - --set image.useDockerImage=true \ - --set image.repository=your-registry/mcp-server \ - --set gitguardian.existingSecret=pat -``` - -## Documentation - -When adding features, update: - -1. **README.md**: User-facing documentation -2. **INSTALL.md**: Installation instructions -3. **values.yaml**: Inline comments -4. **examples/**: Example configurations -5. **NOTES.txt**: Post-install instructions - -## Submitting Changes - -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Test thoroughly -5. Update documentation -6. Submit a pull request - -### PR Description Template - -```markdown -## Description -Brief description of the changes - -## Type of Change -- [ ] Bug fix -- [ ] New feature -- [ ] Breaking change -- [ ] Documentation update - -## Testing -- [ ] Lint passes -- [ ] Templates render correctly -- [ ] Tested in local cluster -- [ ] Documentation updated - -## Additional Notes -Any additional information -``` - -## Getting Help - -- Open an issue on GitHub -- Check existing issues and PRs -- Review Helm documentation: https://helm.sh/docs/ - -## Code of Conduct - -Please be respectful and constructive in all interactions with the community. - -## License - -By contributing, you agree that your contributions will be licensed under the same license as the project (MIT). diff --git a/helm/mcp-server/Chart.yaml b/helm/mcp-server/Chart.yaml index 76408fd..aa63fa2 100644 --- a/helm/mcp-server/Chart.yaml +++ b/helm/mcp-server/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -name: gitguardian-secops-mcp-server -description: A Helm chart for GitGuardian SecOps MCP Server in HTTP mode +name: mcp-server +description: A Helm chart for GitGuardian MCP Server in HTTP mode type: application version: 0.1.0 appVersion: "0.1.0" @@ -9,7 +9,6 @@ keywords: - mcp - security - secrets-detection - - secops home: https://github.com/GitGuardian/ggmcp sources: - https://github.com/GitGuardian/ggmcp diff --git a/helm/mcp-server/DOCKER.md b/helm/mcp-server/DOCKER.md deleted file mode 100644 index 8cfe81e..0000000 --- a/helm/mcp-server/DOCKER.md +++ /dev/null @@ -1,342 +0,0 @@ -# Docker Image Guide - -This guide explains how to build and use Docker images for the GitGuardian MCP Server. - -## Overview - -The Helm chart supports two deployment modes: - -1. **Git-based installation** (Default): Uses `uvx` to install the MCP server directly from the Git repository at startup -2. **Pre-built Docker image**: Uses a pre-built container image with the server already installed - -## Building the Docker Image - -### Prerequisites - -- Docker 20.10+ or compatible container runtime -- Access to the GitGuardian MCP repository - -### Build Commands - -#### For Developer MCP Server - -```bash -# Build the image -docker build -t gitguardian-mcp-server:developer . - -# Build with a specific tag -docker build -t gitguardian-mcp-server:0.1.0-developer . - -# For multi-platform builds (ARM64 and AMD64) -docker buildx build --platform linux/amd64,linux/arm64 \ - -t gitguardian-mcp-server:developer . -``` - -#### For SecOps MCP Server - -The default Dockerfile uses the developer server. To use the SecOps server, override the CMD: - -```bash -# Build and override the command -docker build -t gitguardian-mcp-server:secops . - -# Or run with a different command -docker run --env-file .env gitguardian-mcp-server:developer secops-mcp-server -``` - -### Image Structure - -The Dockerfile creates a multi-stage build: - -1. **Builder stage**: Installs dependencies using `uv` -2. **Production stage**: Creates a minimal runtime image with: - - Python 3.13 slim base - - Non-root user (uid: 1000) - - Pre-installed dependencies - - Security hardening (read-only root filesystem compatible) - -### Testing the Image Locally - -```bash -# Create a .env file with your configuration -cat > .env.docker << EOF -MCP_PORT=8000 -MCP_HOST=0.0.0.0 -ENABLE_LOCAL_OAUTH=false -GITGUARDIAN_URL=https://dashboard.gitguardian.com -GITGUARDIAN_PERSONAL_ACCESS_TOKEN=your_pat_here -EOF - -# Run the container -docker run --rm \ - --env-file .env.docker \ - -p 8000:8000 \ - gitguardian-mcp-server:developer - -# Test the server -curl -X POST http://localhost:8000/tools/list \ - -H "Authorization: Bearer your_pat_here" \ - -H "Content-Type: application/json" \ - -d '{}' -``` - -## Pushing to a Container Registry - -### Docker Hub - -```bash -# Tag the image -docker tag gitguardian-mcp-server:developer your-username/gitguardian-mcp-server:developer - -# Login to Docker Hub -docker login - -# Push the image -docker push your-username/gitguardian-mcp-server:developer -``` - -### GitHub Container Registry (GHCR) - -```bash -# Tag for GHCR -docker tag gitguardian-mcp-server:developer ghcr.io/your-org/gitguardian-mcp-server:developer - -# Login to GHCR -echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin - -# Push the image -docker push ghcr.io/your-org/gitguardian-mcp-server:developer -``` - -### Amazon ECR - -```bash -# Authenticate with ECR -aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com - -# Tag for ECR -docker tag gitguardian-mcp-server:developer aws_account_id.dkr.ecr.region.amazonaws.com/gitguardian-mcp-server:developer - -# Push to ECR -docker push aws_account_id.dkr.ecr.region.amazonaws.com/gitguardian-mcp-server:developer -``` - -### Google Container Registry (GCR) - -```bash -# Tag for GCR -docker tag gitguardian-mcp-server:developer gcr.io/your-project/gitguardian-mcp-server:developer - -# Configure Docker for GCR -gcloud auth configure-docker - -# Push to GCR -docker push gcr.io/your-project/gitguardian-mcp-server:developer -``` - -## Using the Docker Image with Helm - -### Update values.yaml - -```yaml -image: - registry: ghcr.io # or your registry - repository: your-org/gitguardian-mcp-server - tag: "developer" - pullPolicy: IfNotPresent - useDockerImage: true # Important: enables Docker image mode - -# If using a private registry, add pull secrets -imagePullSecrets: - - name: regcred -``` - -### Create Image Pull Secret (for private registries) - -```bash -kubectl create secret docker-registry regcred \ - --docker-server=ghcr.io \ - --docker-username=your-username \ - --docker-password=your-password \ - --docker-email=your-email \ - --namespace gitguardian -``` - -### Install with Docker Image - -```bash -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - --set image.registry=ghcr.io \ - --set image.repository=your-org/gitguardian-mcp-server \ - --set image.tag=developer \ - --set image.useDockerImage=true \ - --set gitguardian.existingSecret=gitguardian-pat -``` - -## Comparison: Git-based vs Docker Image - -### Git-based Installation (Default) - -**Pros:** -- No need to build/maintain Docker images -- Always gets the latest code from the repository -- Simpler CI/CD for development - -**Cons:** -- Slower pod startup time (needs to download and install at startup) -- Requires internet access to GitHub during pod initialization -- Less control over exact versions -- Larger base image (needs Python + uv) - -### Pre-built Docker Image - -**Pros:** -- Faster pod startup time -- No internet access required after image pull -- Immutable deployments (exact version control) -- Smaller attack surface -- Better for air-gapped environments - -**Cons:** -- Requires maintaining a container registry -- Need to rebuild and push for updates -- More complex CI/CD pipeline - -## Production Recommendations - -For production deployments, we recommend: - -1. **Use pre-built Docker images** (`useDockerImage: true`) -2. **Use specific version tags** (not `latest`) -3. **Use private container registry** -4. **Implement image scanning** in CI/CD -5. **Use image pull secrets** for authentication -6. **Enable image signature verification** - -Example production configuration: - -```yaml -image: - registry: your-registry.com - repository: gitguardian/mcp-server - tag: "0.1.0-developer" # Specific version - pullPolicy: IfNotPresent - useDockerImage: true - -imagePullSecrets: - - name: registry-credentials - -# Scan images in CI/CD -podAnnotations: - container.apparmor.security.beta.kubernetes.io/mcp-server: runtime/default -``` - -## Automated Builds with CI/CD - -### GitHub Actions Example - -Create `.github/workflows/docker-build.yml`: - -```yaml -name: Build and Push Docker Image - -on: - push: - tags: - - 'v*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to GHCR - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract version - id: version - run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ghcr.io/${{ github.repository }}:${{ steps.version.outputs.VERSION }}-developer - ghcr.io/${{ github.repository }}:latest-developer -``` - -## Security Scanning - -### Using Trivy - -```bash -# Scan the image for vulnerabilities -docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ - aquasec/trivy image gitguardian-mcp-server:developer - -# Scan with severity threshold -docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ - aquasec/trivy image --severity HIGH,CRITICAL \ - gitguardian-mcp-server:developer -``` - -### Using Snyk - -```bash -# Scan with Snyk -snyk container test gitguardian-mcp-server:developer - -# Monitor the image -snyk container monitor gitguardian-mcp-server:developer -``` - -## Troubleshooting - -### Image pull failures - -```bash -# Check image pull secrets -kubectl get secret regcred -n gitguardian -o yaml - -# Verify the secret is attached to service account -kubectl describe serviceaccount -n gitguardian - -# Check pod events -kubectl describe pod -n gitguardian -``` - -### Container crashes - -```bash -# Check logs -kubectl logs -n gitguardian - -# Check if the command is correct -kubectl get pod -n gitguardian -o yaml | grep -A 5 command: -``` - -### Slow startup - -If using git-based installation and experiencing slow startup: -1. Consider switching to pre-built Docker images -2. Check network connectivity to GitHub -3. Consider using a caching proxy - -## Next Steps - -- Set up automated image builds in CI/CD -- Implement image scanning and vulnerability management -- Configure image pull policies based on your environment -- Set up monitoring and alerting for image updates diff --git a/helm/mcp-server/INSTALL.md b/helm/mcp-server/INSTALL.md deleted file mode 100644 index eb17279..0000000 --- a/helm/mcp-server/INSTALL.md +++ /dev/null @@ -1,293 +0,0 @@ -# Quick Installation Guide - -This guide provides step-by-step instructions for deploying the GitGuardian MCP Server using Helm. - -## Prerequisites - -Before you begin, ensure you have: - -1. A Kubernetes cluster (1.19+) with kubectl configured -2. Helm 3.2.0+ installed -3. A GitGuardian Personal Access Token (PAT) for authentication - -**Note**: Unlike traditional deployments, this Helm chart does NOT require creating Kubernetes secrets for PATs. Authentication is done per-request via HTTP headers. - -## Step 1: Install the Helm Chart - -### Basic Installation - -For a basic installation with default settings: - -```bash -kubectl create namespace gitguardian # Optional: create a dedicated namespace - -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian -``` - -### Installation with Custom Values - -For more control, use one of the example values files: - -```bash -# Basic setup -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - -f helm/mcp-server/examples/values-basic.yaml - -# Production setup with ingress and autoscaling -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - -f helm/mcp-server/examples/values-production.yaml - -# Self-hosted GitGuardian -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - -f helm/mcp-server/examples/values-self-hosted.yaml - -# SecOps server type -helm install mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - -f helm/mcp-server/examples/values-secops.yaml -``` - -## Step 2: Verify the Installation - -Check that the pod is running: - -```bash -kubectl get pods -n gitguardian -l app.kubernetes.io/name=gitguardian-mcp-server -``` - -Check the service: - -```bash -kubectl get service -n gitguardian mcp-server -``` - -View logs: - -```bash -kubectl logs -n gitguardian -l app.kubernetes.io/name=gitguardian-mcp-server -``` - -## Step 3: Test the Connection - -### Port Forward (for testing) - -```bash -kubectl port-forward -n gitguardian service/mcp-server 8000:8000 -``` - -### Test the API - -**Important**: You need a valid GitGuardian Personal Access Token to test the API. - -```bash -# List available tools -curl -X POST http://localhost:8000/tools/list \ - -H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{}' - -# Get authenticated user info -curl -X POST http://localhost:8000/tools/call \ - -H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"name": "get_authenticated_user_info", "arguments": {}}' -``` - -## Step 4: Configure Your MCP Client - -Update your MCP client configuration to use the deployed server: - -### For in-cluster clients: - -```json -{ - "mcpServers": { - "GitGuardian": { - "url": "http://mcp-server.gitguardian.svc.cluster.local:8000", - "transport": "http", - "headers": { - "Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN" - } - } - } -} -``` - -### If you configured an ingress: - -```json -{ - "mcpServers": { - "GitGuardian": { - "url": "https://mcp-server.example.com", - "transport": "http", - "headers": { - "Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN" - } - } - } -} -``` - -## Authentication - -### Per-Request Authentication - -This MCP server uses per-request authentication. Each HTTP request must include your GitGuardian Personal Access Token in the `Authorization` header. - -**Supported formats:** -- `Authorization: Bearer YOUR_PAT` -- `Authorization: Token YOUR_PAT` -- `Authorization: YOUR_PAT` - -### Creating a Personal Access Token - -1. Go to your GitGuardian dashboard -2. Navigate to API > Personal Access Tokens -3. Create a new token with the required scopes: - - For developer server: `scan`, `incidents:read`, `sources:read` - - For honeytokens: add `honeytokens:read`, `honeytokens:write` - - For SecOps: add `incidents:write` - -### No Secrets Required - -Unlike traditional deployments, you do NOT need to: -- Create Kubernetes secrets for PATs -- Store credentials in the cluster -- Manage token rotation through Kubernetes - -Each client manages their own PAT and includes it in their requests. - -## Upgrading - -To upgrade the deployment: - -```bash -helm upgrade mcp-server ./helm/mcp-server \ - --namespace gitguardian \ - -f your-values.yaml -``` - -## Uninstalling - -To remove the deployment: - -```bash -helm uninstall mcp-server --namespace gitguardian -``` - -## Troubleshooting - -### Pod is not starting - -Check pod events: -```bash -kubectl describe pod -n gitguardian -l app.kubernetes.io/name=gitguardian-mcp-server -``` - -### Authentication errors (401 Unauthorized) - -Verify your PAT: -- Check that the token is valid and not expired -- Ensure the token has the required scopes -- Verify the Authorization header format -- Create a new PAT if needed - -### Connection refused - -Verify the service is correctly configured: -```bash -kubectl get endpoints -n gitguardian mcp-server -``` - -### Testing with curl - -```bash -# Port forward the service -kubectl port-forward -n gitguardian service/mcp-server 8000:8000 - -# In another terminal, test the connection -curl -v -X POST http://localhost:8000/tools/list \ - -H "Authorization: Bearer YOUR_PAT" \ - -H "Content-Type: application/json" \ - -d '{}' -``` - -## Multi-User Setup - -Since authentication is per-request, multiple users can use the same deployment with different PATs: - -1. Deploy the MCP server once -2. Each user includes their own PAT in the Authorization header -3. No shared credentials or secrets needed -4. Each user's requests are authenticated independently - -## Production Considerations - -For production deployments: - -1. **Enable TLS/HTTPS**: Use ingress with TLS certificates - ```yaml - ingress: - enabled: true - tls: - - secretName: mcp-server-tls - hosts: - - mcp-server.example.com - ``` - -2. **Enable autoscaling**: Handle variable load - ```yaml - autoscaling: - enabled: true - minReplicas: 2 - maxReplicas: 10 - ``` - -3. **Set resource limits**: Prevent resource exhaustion - ```yaml - resources: - limits: - cpu: 1000m - memory: 512Mi - requests: - cpu: 200m - memory: 256Mi - ``` - -4. **Network policies**: Restrict access to the service - ```yaml - # Create a NetworkPolicy to allow only specific namespaces - apiVersion: networking.k8s.io/v1 - kind: NetworkPolicy - metadata: - name: mcp-server-access - spec: - podSelector: - matchLabels: - app.kubernetes.io/name: gitguardian-mcp-server - ingress: - - from: - - namespaceSelector: - matchLabels: - allowed: "true" - ``` - -5. **Monitoring**: Set up monitoring and alerting - - Pod health checks are included - - Add Prometheus annotations for metrics - - Set up log aggregation - -## Next Steps - -- Configure ingress for external access -- Set up monitoring and alerting -- Enable autoscaling for production workloads -- Review security best practices in the main README -- Configure network policies to restrict access - -For more detailed configuration options, see [README.md](./README.md). diff --git a/helm/mcp-server/README.md b/helm/mcp-server/README.md deleted file mode 100644 index c607431..0000000 --- a/helm/mcp-server/README.md +++ /dev/null @@ -1,367 +0,0 @@ -# GitGuardian SecOps MCP Server Helm Chart - -A Helm chart for deploying GitGuardian SecOps MCP Server in HTTP mode on Kubernetes. - -## Overview - -This Helm chart deploys the GitGuardian SecOps MCP (Model Context Protocol) Server in HTTP/SSE mode, allowing you to host the server as a centralized service for comprehensive security operations that can be consumed by multiple AI agents or applications. - -**Authentication Model**: This server uses per-request authentication via HTTP headers. No secrets or Personal Access Tokens (PATs) are stored in the deployment. Each client request must include authentication credentials in the `Authorization` header. - -## Prerequisites - -- Kubernetes 1.19+ -- Helm 3.2.0+ -- Python and `uv` available in the container image (included in the deployment) -- GitGuardian Personal Access Token (PAT) for each client with appropriate SecOps scopes - -## Installation - -### Quick Start - -1. Install the Helm chart: - -```bash -helm install secops-mcp-server ./helm/mcp-server -``` - -2. The SecOps server will start and be ready to accept requests with per-request authentication. - -### Using a values file - -Create a `my-values.yaml` file: - -```yaml -# GitGuardian instance configuration -gitguardian: - url: "https://dashboard.gitguardian.com" - # SecOps typically requires comprehensive scopes - scopes: "scan,incidents:read,incidents:write,sources:read,honeytokens:read,honeytokens:write" - -# Service configuration -service: - type: ClusterIP - port: 8000 - -# Enable ingress if you want to expose the service externally -ingress: - enabled: true - className: "nginx" - hosts: - - host: secops-mcp.example.com - paths: - - path: / - pathType: Prefix - tls: - - secretName: secops-mcp-tls - hosts: - - secops-mcp.example.com - -# Resource limits for SecOps workloads -resources: - limits: - cpu: 2000m - memory: 1Gi - requests: - cpu: 500m - memory: 512Mi -``` - -Install with your custom values: - -```bash -helm install secops-mcp-server ./helm/mcp-server -f my-values.yaml -``` - -## Configuration - -### GitGuardian Configuration - -#### GitGuardian SaaS (US) - -Default configuration: - -```yaml -gitguardian: - url: "https://dashboard.gitguardian.com" -``` - -#### GitGuardian SaaS (EU) - -For the EU region: - -```yaml -gitguardian: - url: "https://dashboard.eu1.gitguardian.com" -``` - -#### Self-Hosted GitGuardian - -For self-hosted instances: - -```yaml -gitguardian: - url: "https://dashboard.gitguardian.mycorp.local" -``` - -### Authentication - -**Important**: This MCP server uses per-request authentication. No secrets or PATs are stored in the Kubernetes deployment. - -Each HTTP request to the server must include authentication via the `Authorization` header: - -```bash -curl -X POST http://secops-mcp-server:8000/tools/list \ - -H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{}' -``` - -**Supported header formats:** -- `Authorization: Bearer ` -- `Authorization: Token ` -- `Authorization: ` - -**Why per-request authentication?** -- **Security**: No credentials stored in the cluster -- **Multi-tenancy**: Different SecOps teams can use different PATs -- **Flexibility**: Easy to rotate tokens without redeploying -- **Audit trail**: Each request is authenticated individually - -### Required Scopes for SecOps - -SecOps operations typically require the following scopes: -- `scan` - Scan code for secrets -- `incidents:read` - Read security incidents -- `incidents:write` - Manage and resolve incidents -- `sources:read` - Read source information -- `honeytokens:read` - List honeytokens -- `honeytokens:write` - Create and manage honeytokens - -### Service Configuration - -Configure how the service is exposed: - -```yaml -service: - type: ClusterIP # Options: ClusterIP, NodePort, LoadBalancer - port: 8000 - targetPort: 8000 -``` - -### Ingress Configuration - -To expose the SecOps MCP server externally: - -```yaml -ingress: - enabled: true - className: "nginx" - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - hosts: - - host: secops-mcp.example.com - paths: - - path: / - pathType: Prefix - tls: - - secretName: secops-mcp-tls - hosts: - - secops-mcp.example.com -``` - -### Resource Management - -SecOps workloads may require more resources: - -```yaml -resources: - limits: - cpu: 2000m - memory: 1Gi - requests: - cpu: 500m - memory: 512Mi -``` - -### Autoscaling - -Enable horizontal pod autoscaling for variable SecOps workloads: - -```yaml -autoscaling: - enabled: true - minReplicas: 2 - maxReplicas: 10 - targetCPUUtilizationPercentage: 75 - targetMemoryUtilizationPercentage: 80 -``` - -### Security Context - -The chart includes secure defaults: - -```yaml -podSecurityContext: - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 1000 - -securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 -``` - -## Usage - -### Connecting to the SecOps MCP Server - -Once deployed, you can connect to the server using HTTP requests with Bearer token authentication: - -```bash -# Get the service URL -kubectl get service secops-mcp-server - -# List available SecOps tools -curl -X POST http://:8000/tools/list \ - -H "Authorization: Bearer YOUR_PAT" \ - -H "Content-Type: application/json" \ - -d '{}' - -# Example: Get authenticated user info -curl -X POST http://:8000/tools/call \ - -H "Authorization: Bearer YOUR_PAT" \ - -H "Content-Type: application/json" \ - -d '{"name": "get_authenticated_user_info", "arguments": {}}' -``` - -### Using with MCP Clients - -Configure your MCP client to use the HTTP transport with per-request authentication: - -```json -{ - "mcpServers": { - "GitGuardianSecOps": { - "url": "http://secops-mcp-server:8000", - "transport": "http", - "headers": { - "Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN" - } - } - } -} -``` - -## Configuration Parameters - -| Parameter | Description | Default | -|-----------|-------------|---------| -| `replicaCount` | Number of replicas | `1` | -| `image.registry` | Container image registry | `ghcr.io` | -| `image.repository` | Container image repository | `gitguardian/mcp-server` | -| `image.tag` | Image tag | `""` (uses chart appVersion) | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.useDockerImage` | Use pre-built Docker image vs uvx | `false` | -| `mcp.port` | MCP server port | `8000` | -| `mcp.host` | MCP server host | `0.0.0.0` | -| `gitguardian.url` | GitGuardian instance URL | `https://dashboard.gitguardian.com` | -| `gitguardian.scopes` | OAuth scopes (for reference) | `""` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.port` | Service port | `8000` | -| `ingress.enabled` | Enable ingress | `false` | -| `resources.limits.cpu` | CPU limit | `1000m` | -| `resources.limits.memory` | Memory limit | `512Mi` | -| `resources.requests.cpu` | CPU request | `100m` | -| `resources.requests.memory` | Memory request | `128Mi` | -| `autoscaling.enabled` | Enable HPA | `false` | - -## Upgrading - -To upgrade the chart: - -```bash -helm upgrade secops-mcp-server ./helm/mcp-server -f my-values.yaml -``` - -## Uninstallation - -To uninstall the chart: - -```bash -helm uninstall secops-mcp-server -``` - -## Troubleshooting - -### Check Pod Status - -```bash -kubectl get pods -l app.kubernetes.io/name=gitguardian-secops-mcp-server -``` - -### View Pod Logs - -```bash -kubectl logs -l app.kubernetes.io/name=gitguardian-secops-mcp-server -``` - -### Check Service Endpoints - -```bash -kubectl get endpoints secops-mcp-server -``` - -### Test Connectivity - -```bash -# Port forward to test locally -kubectl port-forward service/secops-mcp-server 8000:8000 - -# Test the endpoint (requires a valid PAT with SecOps scopes) -curl -X POST http://localhost:8000/tools/list \ - -H "Authorization: Bearer YOUR_PAT" \ - -H "Content-Type: application/json" \ - -d '{}' -``` - -### Authentication Errors - -If you receive 401 Unauthorized errors: -- Verify your PAT is valid and not expired -- Check the Authorization header format -- Ensure the PAT has the required SecOps scopes -- Create a new PAT at your GitGuardian dashboard - -## Security Considerations - -1. **No stored credentials**: The deployment does not store any PATs or secrets -2. **Per-request authentication**: Each request is authenticated individually -3. **Use TLS/HTTPS**: Enable ingress with TLS for production deployments -4. **Network policies**: Consider implementing Kubernetes network policies to restrict access -5. **RBAC**: The chart creates a service account with minimal permissions -6. **Token management**: SecOps teams are responsible for securing their own PATs -7. **Scope management**: Use least-privilege scopes for each team's PAT - -## Multi-Team SecOps - -This deployment supports multi-team SecOps naturally through per-request authentication: -- Different SecOps teams can use different PATs in their requests -- No shared credentials mean better security isolation between teams -- Each team's requests are authenticated and authorized independently -- Fine-grained access control through PAT scopes - -## Support - -For issues and questions: -- GitHub Issues: https://github.com/GitGuardian/gg-mcp/issues -- Documentation: https://docs.gitguardian.com/ - -## License - -MIT License - see LICENSE file for details diff --git a/helm/mcp-server/examples/values-production.yaml b/helm/mcp-server/examples/values-production.yaml index 73fdc9d..27d702c 100644 --- a/helm/mcp-server/examples/values-production.yaml +++ b/helm/mcp-server/examples/values-production.yaml @@ -1,4 +1,4 @@ -# Production configuration example for GitGuardian SecOps MCP Server +# Production configuration example for GitGuardian MCP Server # This example shows a production-ready setup with ingress, TLS, and autoscaling # Authentication is done per-request via Authorization header diff --git a/helm/mcp-server/examples/values-secops.yaml b/helm/mcp-server/examples/values-secops.yaml deleted file mode 100644 index ea30284..0000000 --- a/helm/mcp-server/examples/values-secops.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# SecOps MCP Server configuration example -# This example shows a typical SecOps deployment -# Authentication is done per-request via Authorization header - -gitguardian: - url: "https://dashboard.gitguardian.com" - -service: - type: ClusterIP - port: 8000 - -# SecOps may require more resources due to comprehensive tooling -resources: - limits: - cpu: 2000m - memory: 1Gi - requests: - cpu: 500m - memory: 512Mi - -# Enable autoscaling for variable load -autoscaling: - enabled: true - minReplicas: 2 - maxReplicas: 5 - targetCPUUtilizationPercentage: 75 - -# Optional: Add node selector for dedicated SecOps nodes -nodeSelector: - workload: secops - -# Optional: Add tolerations for tainted nodes -tolerations: - - key: "workload" - operator: "Equal" - value: "secops" - effect: "NoSchedule" diff --git a/helm/mcp-server/templates/NOTES.txt b/helm/mcp-server/templates/NOTES.txt index afb0dbc..169e62a 100644 --- a/helm/mcp-server/templates/NOTES.txt +++ b/helm/mcp-server/templates/NOTES.txt @@ -1,6 +1,6 @@ Thank you for installing {{ .Chart.Name }}! -Your GitGuardian SecOps MCP Server has been deployed. +Your GitGuardian MCP Server has been deployed. 1. Get the application URL: {{- if .Values.ingress.enabled }} diff --git a/helm/mcp-server/templates/deployment.yaml b/helm/mcp-server/templates/deployment.yaml index 2af2c48..c07ba22 100644 --- a/helm/mcp-server/templates/deployment.yaml +++ b/helm/mcp-server/templates/deployment.yaml @@ -38,13 +38,13 @@ spec: imagePullPolicy: {{ .Values.image.pullPolicy }} {{- if .Values.image.useDockerImage }} command: - - "secops-mcp-server" + - "developer-mcp-server" {{- else }} command: - "uvx" - "--from" - "git+https://github.com/GitGuardian/gg-mcp.git" - - "secops-mcp-server" + - "developer-mcp-server" {{- end }} ports: - name: http diff --git a/helm/mcp-server/tests/deployment_test.yaml b/helm/mcp-server/tests/deployment_test.yaml index 2b31c4f..2a1b138 100644 --- a/helm/mcp-server/tests/deployment_test.yaml +++ b/helm/mcp-server/tests/deployment_test.yaml @@ -8,7 +8,7 @@ tests: of: Deployment - equal: path: metadata.name - value: RELEASE-NAME-gitguardian-secops-mcp-server + value: RELEASE-NAME-mcp-server - equal: path: spec.replicas value: 1 diff --git a/helm/mcp-server/tests/hpa_test.yaml b/helm/mcp-server/tests/hpa_test.yaml index 6c366c4..c565830 100644 --- a/helm/mcp-server/tests/hpa_test.yaml +++ b/helm/mcp-server/tests/hpa_test.yaml @@ -18,7 +18,7 @@ tests: of: HorizontalPodAutoscaler - equal: path: metadata.name - value: RELEASE-NAME-gitguardian-secops-mcp-server + value: RELEASE-NAME-mcp-server - equal: path: spec.minReplicas value: 2 diff --git a/helm/mcp-server/tests/ingress_test.yaml b/helm/mcp-server/tests/ingress_test.yaml index 33a342b..6323fa9 100644 --- a/helm/mcp-server/tests/ingress_test.yaml +++ b/helm/mcp-server/tests/ingress_test.yaml @@ -20,7 +20,7 @@ tests: of: Ingress - equal: path: metadata.name - value: RELEASE-NAME-gitguardian-secops-mcp-server + value: RELEASE-NAME-mcp-server - equal: path: spec.rules[0].host value: mcp-server.example.com diff --git a/helm/mcp-server/tests/service_test.yaml b/helm/mcp-server/tests/service_test.yaml index 4b058da..4cba075 100644 --- a/helm/mcp-server/tests/service_test.yaml +++ b/helm/mcp-server/tests/service_test.yaml @@ -8,7 +8,7 @@ tests: of: Service - equal: path: metadata.name - value: RELEASE-NAME-gitguardian-secops-mcp-server + value: RELEASE-NAME-mcp-server - equal: path: spec.type value: ClusterIP diff --git a/helm/mcp-server/tests/serviceaccount_test.yaml b/helm/mcp-server/tests/serviceaccount_test.yaml index 844d984..6a0d6ca 100644 --- a/helm/mcp-server/tests/serviceaccount_test.yaml +++ b/helm/mcp-server/tests/serviceaccount_test.yaml @@ -10,7 +10,7 @@ tests: of: ServiceAccount - equal: path: metadata.name - value: RELEASE-NAME-gitguardian-secops-mcp-server + value: RELEASE-NAME-mcp-server - it: should support service account annotations set: diff --git a/helm/mcp-server/values.yaml b/helm/mcp-server/values.yaml index ef8c3b2..1f5436d 100644 --- a/helm/mcp-server/values.yaml +++ b/helm/mcp-server/values.yaml @@ -27,7 +27,7 @@ nameOverride: "" # Override the full name of the resources fullnameOverride: "" -# This chart deploys the SecOps MCP Server only +# This chart deploys the MCP Server # MCP Server configuration mcp: From 540052052fc24be51749a1f734ab4cf13b88d948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Delion?= Date: Fri, 14 Nov 2025 08:36:51 +0100 Subject: [PATCH 2/2] fix(ci): Fix a security warning --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb2b3ef..16b0cec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -104,9 +104,9 @@ jobs: - name: Push Helm Chart to OCI Registry run: | - helm registry login ${{ env.REGISTRY }} \ + echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ${{ env.REGISTRY }} \ -u ${{ github.actor }} \ - -p ${{ secrets.GITHUB_TOKEN }} + --password-stdin CHART_VERSION=$(grep "^version:" ./helm/mcp-server/Chart.yaml | cut -d' ' -f2 | tr -d '"') REPO_OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')