This guide covers deploying Global SAST Scanner to Kubernetes clusters using the included Helm chart and deployment script.
- kubectl configured and connected to your cluster
- Helm v3.x installed
- Docker (for building images)
- API Tokens: GitHub and GitLab tokens (see Installation Guide)
The Docker image runs both the API server and the worker from the same build. The default command starts the API (
gsast-api); the Helm chart overrides the command for the worker pod togsast-worker.
The repository includes a comprehensive scripts/deploy-local.sh script that handles everything:
# 1. Generate environment template
./scripts/deploy-local.sh --generate
# 2. Edit the .env file with your tokens
vim .env
# 3. Deploy (builds image and installs to Kubernetes)
./scripts/deploy-local.sh --build
# 4. Access the API
./scripts/deploy-local.sh --port-forwardThat's it! The script handles image building, secret creation, Helm deployment, and provides access instructions.
The deployment script supports many options for different scenarios:
# Deploy with default settings
./scripts/deploy-local.sh
# Build image before deploying
./scripts/deploy-local.sh --build
# Use existing image from registry
./scripts/deploy-local.sh --image your-registry/gsast:tag
# Deploy to custom namespace
./scripts/deploy-local.sh --namespace my-gsast-namespace# Show all available options
./scripts/deploy-local.sh --help
# Port forward to access API locally
./scripts/deploy-local.sh --port-forward
# Clean up and redeploy (if conflicts occur)
./scripts/deploy-local.sh --clean --build
# Force cleanup and redeploy
./scripts/deploy-local.sh --force
# Completely remove deployment and namespace
./scripts/deploy-local.sh --delete# Skip Docker image existence check
./scripts/deploy-local.sh --image custom:tag --skip-image-check
# Custom release name
./scripts/deploy-local.sh --release my-release --namespace my-namespaceThe script uses a .env file for configuration. Generate the template:
./scripts/deploy-local.sh --generateThen edit .env with your values:
# Required: API authentication
API_SECRET_KEY=your_secure_random_key
# Required: GitHub access
GITHUB_API_TOKEN=ghp_your_github_token
# Required: GitLab access
GITLAB_URL=https://gitlab.com
GITLAB_API_TOKEN=glpat_your_gitlab_token
# Optional: External Redis (uses internal Redis if not set)
# REDIS_URL=redis://:password@external-redis:6379If you prefer to use Helm directly:
# Navigate to chart directory
cd helm/gsast/
# Update dependencies
helm dependency update# Create namespace
kubectl create namespace gsast-local
# Create secret with your credentials
kubectl create secret generic gsast-local-secret \
--namespace gsast-local \
--from-literal=API_SECRET_KEY="your-secret-key" \
--from-literal=GITHUB_API_TOKEN="your-github-token" \
--from-literal=GITLAB_API_TOKEN="your-gitlab-token" \
--from-literal=GITLAB_URL="https://gitlab.com"# Install the chart
helm install gsast . \
--namespace gsast-local \
--set existingSecret=gsast-local-secret \
--set worker.image.repositoryPrefix=gsast \
--set worker.image.tag=latest \
--set worker.image.pullPolicy=Never# Port forward to access locally
kubectl port-forward -n gsast-local service/gsast-api 5000:5000
# Or create an ingress (see values.yaml for configuration)The deployment script automatically detects local clusters and:
- Uses
imagePullPolicy: Neverfor local images - Loads built images into the cluster automatically
# For minikube
./scripts/deploy-local.sh --build
# Script automatically runs: minikube image load gsast:latest
# For kind
./scripts/deploy-local.sh --build
# Script automatically runs: kind load docker-image gsast:latest
# For Docker Desktop
./scripts/deploy-local.sh --build
# Uses IfNotPresent pull policyFor production deployments:
# Build and push to your registry
docker build -t your-registry.com/gsast:v1.0 .
docker push your-registry.com/gsast:v1.0
# Deploy with registry image
./scripts/deploy-local.sh --image your-registry.com/gsast:v1.0# Check pods
kubectl get pods -n gsast-local
# Check services
kubectl get svc -n gsast-local
# Check deployments
kubectl get deployments -n gsast-local# API server logs
kubectl logs -n gsast-local -l component=gsast-api -f
# Worker logs
kubectl logs -n gsast-local -l component=gsast-worker -f
# All GSAST logs
kubectl logs -n gsast-local -l app.kubernetes.io/name=gsast -f# Scale workers manually
kubectl scale deployment gsast-worker --replicas=3 -n gsast-local
# Or enable HPA in values.yaml
helm upgrade gsast . \
--set worker.autoscaling.enabled=true \
--set worker.autoscaling.minReplicas=2 \
--set worker.autoscaling.maxReplicas=10The Helm chart supports extensive customization through values.yaml:
api:
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
worker:
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Giredis:
enabled: false # Disable internal Redis
useInternalRedis: false
# Configure external Redis via secret
externalRedis:
existingSecret: "redis-secret"
existingSecretKey: "redis-url"api:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: gsast.your-domain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: gsast-tls
hosts:
- gsast.your-domain.com-
Image Pull Errors
# Check if image exists in cluster kubectl describe pod <pod-name> -n gsast-local # For local clusters, load the image minikube image load gsast:latest # or kind load docker-image gsast:latest --name <cluster-name>
-
Secret Not Found
# Verify secret exists kubectl get secrets -n gsast-local # Check secret contents kubectl describe secret gsast-local-secret -n gsast-local
-
Pod Startup Issues
# Check pod events kubectl describe pod <pod-name> -n gsast-local # Check logs for startup errors kubectl logs <pod-name> -n gsast-local
-
Port Forward Fails
# Check if service exists kubectl get svc -n gsast-local # Try different local port kubectl port-forward -n gsast-local service/gsast-api 8080:5000
# Full cleanup
./scripts/deploy-local.sh --delete
# Or manually
helm uninstall gsast -n gsast-local
kubectl delete namespace gsast-local