diff --git a/.github/workflows/publish-chart.yml b/.github/workflows/publish-chart.yml new file mode 100644 index 000000000..dbbd35804 --- /dev/null +++ b/.github/workflows/publish-chart.yml @@ -0,0 +1,56 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Publish Helm Chart + +on: + push: + tags: + - '*' + +permissions: + contents: read + packages: write + +jobs: + publish: + name: Package and Push Helm Chart + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + + - name: Log in to GHCR + run: | + echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io --username "${{ github.actor }}" --password-stdin + + - name: Update chart version + run: | + TAG="${GITHUB_REF_NAME#v}" + sed -i "s/^version:.*/version: ${TAG}/" charts/scion/Chart.yaml + sed -i "s/^appVersion:.*/appVersion: \"${TAG}\"/" charts/scion/Chart.yaml + + - name: Lint chart + run: helm lint charts/scion + + - name: Package chart + run: helm package charts/scion + + - name: Push chart to GHCR + run: | + CHART_PKG=$(ls scion-*.tgz) + helm push "${CHART_PKG}" oci://ghcr.io/googlecloudplatform/scion/charts diff --git a/charts/scion/Chart.yaml b/charts/scion/Chart.yaml new file mode 100644 index 000000000..3bf4ac291 --- /dev/null +++ b/charts/scion/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: scion +description: Scion AI agent orchestration platform - hub and runtime broker +type: application +version: 0.1.0 +appVersion: "0.1.0" +home: https://github.com/GoogleCloudPlatform/scion +sources: + - https://github.com/GoogleCloudPlatform/scion +maintainers: + - name: GoogleCloudPlatform + url: https://github.com/GoogleCloudPlatform +keywords: + - scion + - ai + - agents + - kubernetes diff --git a/charts/scion/templates/NOTES.txt b/charts/scion/templates/NOTES.txt new file mode 100644 index 000000000..89858ee11 --- /dev/null +++ b/charts/scion/templates/NOTES.txt @@ -0,0 +1,47 @@ +{{- if eq .Values.mode "hub" }} +Scion Hub deployed successfully! + +1. Access the hub: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + https://{{ .host }} +{{- end }} +{{- else }} + kubectl port-forward svc/{{ include "scion.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }} + Then open: http://localhost:{{ .Values.service.port }} +{{- end }} + +2. Check health: + kubectl get pods -l {{ include "scion.selectorLabels" . | replace ": " "=" | replace "\n" "," }} + +{{- if not .Values.auth.existingSecret }} + +WARNING: No session secret configured (auth.existingSecret is empty). +Create a secret with a random session key: + + kubectl create secret generic scion-session \ + --from-literal=session-secret=$(openssl rand -hex 32) + +Then set auth.existingSecret=scion-session in your values. +{{- end }} + +{{- if .Values.ingress.enabled }} + +NOTE: If using SSE (Server-Sent Events) or WebSocket connections, ensure +your Ingress controller supports long-lived connections and has appropriate +timeout settings (e.g., proxy-read-timeout >= 300s for nginx). +{{- end }} +{{- else }} +Scion Broker deployed successfully! + +The broker is running on port {{ .Values.broker.port }}. +{{- if .Values.broker.hubEndpoint }} +Hub endpoint: {{ .Values.broker.hubEndpoint }} +{{- else }} + +WARNING: No hub endpoint configured (broker.hubEndpoint is empty). +Set broker.hubEndpoint to the hub's URL. +{{- end }} +{{- end }} + +Documentation: https://github.com/GoogleCloudPlatform/scion diff --git a/charts/scion/templates/_helpers.tpl b/charts/scion/templates/_helpers.tpl new file mode 100644 index 000000000..177a6e0d2 --- /dev/null +++ b/charts/scion/templates/_helpers.tpl @@ -0,0 +1,80 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "scion.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "scion.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "scion.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "scion.labels" -}} +helm.sh/chart: {{ include "scion.chart" . }} +{{ include "scion.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "scion.selectorLabels" -}} +app.kubernetes.io/name: {{ include "scion.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "scion.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "scion.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Return the image reference +*/}} +{{- define "scion.image" -}} +{{- $tag := default .Chart.AppVersion .Values.image.tag }} +{{- printf "%s:%s" .Values.image.repository $tag }} +{{- end }} + +{{/* +Return the agent namespace for RBAC (defaults to release namespace) +*/}} +{{- define "scion.agentNamespace" -}} +{{- default .Release.Namespace .Values.rbac.agentNamespace }} +{{- end }} diff --git a/charts/scion/templates/configmap.yaml b/charts/scion/templates/configmap.yaml new file mode 100644 index 000000000..a15d3ab99 --- /dev/null +++ b/charts/scion/templates/configmap.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- if eq .Values.mode "hub" }} + SCION_SERVER_HUB_HOST: "0.0.0.0" + SCION_SERVER_LOGFORMAT: "json" + {{- with .Values.server.logLevel }} + SCION_SERVER_LOGLEVEL: {{ . | quote }} + {{- end }} + {{- with .Values.database.path }} + SCION_SERVER_DATABASE_URL: {{ . | quote }} + {{- end }} + {{- with .Values.storage.provider }} + SCION_SERVER_STORAGE_PROVIDER: {{ . | quote }} + {{- end }} + {{- with .Values.storage.bucket }} + SCION_HUB_STORAGE_BUCKET: {{ . | quote }} + {{- end }} + {{- with .Values.secrets.backend }} + SCION_SERVER_SECRETS_BACKEND: {{ . | quote }} + {{- end }} + {{- with .Values.secrets.gcpProjectId }} + SCION_SERVER_SECRETS_GCPPROJECTID: {{ . | quote }} + {{- end }} + {{- with .Values.server.publicUrl }} + SCION_SERVER_BASE_URL: {{ . | quote }} + {{- end }} + {{- if .Values.server.adminEmails }} + SCION_SERVER_HUB_ADMINEMAILS: {{ join "," .Values.server.adminEmails | quote }} + {{- end }} + {{- end }} + {{- with .Values.imageRegistry }} + SCION_IMAGE_REGISTRY: {{ . | quote }} + {{- end }} + {{- if .Values.telemetry.cloudLogging.enabled }} + SCION_LOG_GCP: "true" + {{- with .Values.telemetry.cloudLogging.gcpProjectId }} + SCION_CLOUD_LOGGING_PROJECT_ID: {{ . | quote }} + {{- end }} + {{- with .Values.telemetry.cloudLogging.logId }} + SCION_CLOUD_LOGGING_LOG_ID: {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.telemetry.otelLogBridge.enabled }} + SCION_OTEL_LOG_BRIDGE: "true" + {{- end }} diff --git a/charts/scion/templates/deployment.yaml b/charts/scion/templates/deployment.yaml new file mode 100644 index 000000000..9ffc61010 --- /dev/null +++ b/charts/scion/templates/deployment.yaml @@ -0,0 +1,185 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "scion.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "scion.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "scion.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: scion + image: {{ include "scion.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + args: + - "--global" + - "server" + - "start" + - "--foreground" + - "--production" + {{- if eq .Values.mode "hub" }} + - "--enable-hub" + - "--enable-web" + - "--web-port" + - {{ .Values.server.port | quote }} + {{- if .Values.broker.enabled }} + - "--enable-runtime-broker" + - "--runtime-broker-port" + - {{ .Values.broker.port | quote }} + {{- if .Values.broker.autoProvide }} + - "--auto-provide" + {{- end }} + {{- end }} + {{- with .Values.database.path }} + - "--db" + - {{ . | quote }} + {{- end }} + {{- if eq .Values.storage.provider "gcs" }} + {{- with .Values.storage.bucket }} + - "--storage-bucket" + - {{ . | quote }} + {{- end }} + {{- else if eq .Values.storage.provider "local" }} + {{- with .Values.storage.localPath }} + - "--storage-dir" + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.server.adminEmails }} + - "--admin-emails" + - {{ join "," .Values.server.adminEmails | quote }} + {{- end }} + {{- else }} + {{/* broker-only mode */}} + - "--enable-runtime-broker" + - "--runtime-broker-port" + - {{ .Values.broker.port | quote }} + {{- if .Values.broker.autoProvide }} + - "--auto-provide" + {{- end }} + {{- end }} + {{- if eq .Values.server.logLevel "debug" }} + - "--debug" + {{- end }} + {{- with .Values.server.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ include "scion.fullname" . }} + env: + {{- if and (eq .Values.mode "hub") .Values.auth.existingSecret }} + - name: SCION_SERVER_SESSION_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.auth.existingSecret }} + key: {{ .Values.auth.existingSecretKey }} + {{- end }} + {{- with .Values.server.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + {{- if eq .Values.mode "hub" }} + - name: http + containerPort: {{ .Values.server.port }} + protocol: TCP + {{- end }} + {{- if or (eq .Values.mode "broker") .Values.broker.enabled }} + - name: broker + containerPort: {{ .Values.broker.port }} + protocol: TCP + {{- end }} + {{- if eq .Values.mode "hub" }} + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 15 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /readyz + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if and (eq .Values.mode "hub") .Values.persistence.enabled }} + - name: data + mountPath: /data + {{- end }} + - name: tmp + mountPath: /tmp + - name: home + mountPath: /home/nonroot + - name: settings + mountPath: /home/nonroot/.scion/settings.yaml + subPath: settings.yaml + readOnly: true + volumes: + {{- if and (eq .Values.mode "hub") .Values.persistence.enabled }} + - name: data + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "scion.fullname" .) }} + {{- end }} + - name: tmp + emptyDir: {} + - name: home + emptyDir: {} + - name: settings + configMap: + name: {{ include "scion.fullname" . }}-settings + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/scion/templates/ingress.yaml b/charts/scion/templates/ingress.yaml new file mode 100644 index 000000000..d90ca32a8 --- /dev/null +++ b/charts/scion/templates/ingress.yaml @@ -0,0 +1,44 @@ +{{- if and (eq .Values.mode "hub") .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + annotations: + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "scion.fullname" $ }} + port: + name: http + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/scion/templates/pvc.yaml b/charts/scion/templates/pvc.yaml new file mode 100644 index 000000000..fa9388899 --- /dev/null +++ b/charts/scion/templates/pvc.yaml @@ -0,0 +1,21 @@ +{{- if and (eq .Values.mode "hub") .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode }} + {{- with .Values.persistence.storageClass }} + storageClassName: {{ . }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size }} +{{- end }} diff --git a/charts/scion/templates/role.yaml b/charts/scion/templates/role.yaml new file mode 100644 index 000000000..7f572e0b7 --- /dev/null +++ b/charts/scion/templates/role.yaml @@ -0,0 +1,47 @@ +{{- if .Values.rbac.create -}} +{{- if .Values.rbac.clusterWide }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "scion.fullname" . }} + namespace: {{ include "scion.agentNamespace" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "create", "delete"] + - apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] + - apiGroups: [""] + resources: ["pods/log"] + verbs: ["get"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "list", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "create", "list", "delete"] + {{- if .Values.rbac.secretProviderClass }} + - apiGroups: ["secrets-store.csi.x-k8s.io"] + resources: ["secretproviderclasses"] + verbs: ["create", "list", "delete"] + {{- end }} +{{- end }} diff --git a/charts/scion/templates/rolebinding.yaml b/charts/scion/templates/rolebinding.yaml new file mode 100644 index 000000000..f3a3c5bb8 --- /dev/null +++ b/charts/scion/templates/rolebinding.yaml @@ -0,0 +1,42 @@ +{{- if .Values.rbac.create -}} +{{- if .Values.rbac.clusterWide }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "scion.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "scion.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "scion.fullname" . }} + namespace: {{ include "scion.agentNamespace" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "scion.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "scion.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/scion/templates/service.yaml b/charts/scion/templates/service.yaml new file mode 100644 index 000000000..fe1388bf4 --- /dev/null +++ b/charts/scion/templates/service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "scion.fullname" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- if or .Values.service.annotations .Values.commonAnnotations }} + annotations: + {{- with .Values.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + {{- if eq .Values.mode "hub" }} + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + {{- end }} + {{- if or (eq .Values.mode "broker") .Values.broker.enabled }} + - port: {{ .Values.broker.port }} + targetPort: broker + protocol: TCP + name: broker + {{- end }} + selector: + {{- include "scion.selectorLabels" . | nindent 4 }} diff --git a/charts/scion/templates/serviceaccount.yaml b/charts/scion/templates/serviceaccount.yaml new file mode 100644 index 000000000..a8e0132bd --- /dev/null +++ b/charts/scion/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "scion.serviceAccountName" . }} + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- with .Values.serviceAccount.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/scion/templates/settings-configmap.yaml b/charts/scion/templates/settings-configmap.yaml new file mode 100644 index 000000000..b3b1d18bb --- /dev/null +++ b/charts/scion/templates/settings-configmap.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "scion.fullname" . }}-settings + labels: + {{- include "scion.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + settings.yaml: | + schema_version: "1" + {{- with .Values.imageRegistry }} + image_registry: {{ . | quote }} + {{- end }} diff --git a/charts/scion/values.yaml b/charts/scion/values.yaml new file mode 100644 index 000000000..2f662ebae --- /dev/null +++ b/charts/scion/values.yaml @@ -0,0 +1,271 @@ +# Scion Helm Chart Values +# See: https://github.com/GoogleCloudPlatform/scion + +# -- Deployment mode: "hub" (hub+broker co-located) or "broker" (broker-only) +mode: hub + +# -- Number of replicas. MUST be 1 when using SQLite (default). +replicaCount: 1 + +image: + # -- Container image repository + repository: ghcr.io/googlecloudplatform/scion + # -- Image tag (defaults to Chart appVersion) + tag: "" + # -- Image pull policy + pullPolicy: IfNotPresent + +# -- Image pull secrets +imagePullSecrets: [] + +# -- Override the chart name +nameOverride: "" +# -- Override the full release name +fullnameOverride: "" + +# -- Additional labels to add to all resources +commonLabels: {} + +# -- Additional annotations to add to all resources +commonAnnotations: {} + +# ============================================================================= +# Scion Server Configuration +# ============================================================================= + +server: + # -- Hub API + Web UI port (combined mode) + port: 8080 + # -- Public URL for the hub (used for OAuth callbacks, broker connections) + # Example: https://hub.example.com + publicUrl: "" + # -- Admin email addresses (auto-promoted to admin role) + adminEmails: [] + # -- Log level: debug, info, warn, error + logLevel: "info" + + # -- Additional CLI arguments passed to `scion server start` + extraArgs: [] + + # -- Additional environment variables (list of {name, value} or {name, valueFrom}) + extraEnv: [] + +# ============================================================================= +# Runtime Broker Configuration +# ============================================================================= + +broker: + # -- Enable runtime broker (always true in hub mode, configurable in broker mode) + enabled: true + # -- Broker port + port: 9800 + # -- How the broker connects to the hub (internal URL, auto-configured in hub mode) + hubEndpoint: "" + # -- URL that agents inside containers use to reach the hub + containerHubEndpoint: "" + # -- Auto-provide groves + autoProvide: true + # -- Broker name + name: "" + # -- Broker nickname + nickname: "" + + # -- For broker-only mode: K8s Secret containing broker-credentials.json + credentialsSecret: "" + +# ============================================================================= +# Database Configuration +# ============================================================================= + +database: + # -- Database driver (only "sqlite" is currently supported) + driver: "sqlite" + # -- Database path inside the container (on the PVC) + path: "/data/hub.db" + +# ============================================================================= +# Storage Configuration +# ============================================================================= + +storage: + # -- Storage provider: "local" or "gcs" + provider: "gcs" + # -- GCS bucket name (required when provider is "gcs") + bucket: "" + # -- Local storage path (only when provider is "local") + localPath: "/data/storage" + +# ============================================================================= +# Secrets Backend +# ============================================================================= + +secrets: + # -- Secrets backend: "local" or "gcpsm" + backend: "local" + # -- GCP project ID (required when backend is "gcpsm") + gcpProjectId: "" + +# ============================================================================= +# Authentication +# ============================================================================= + +auth: + # -- Authorized email domains for login + authorizedDomains: [] + # -- Session secret (required). Reference to an existing K8s Secret. + existingSecret: "" + # -- Key in the existing secret that contains the session secret + existingSecretKey: "session-secret" + +# -- Reference to a K8s Secret containing OAuth credentials. +# Expected keys: see values documentation for full list. +oauthSecret: "" + +# -- Reference to a K8s Secret containing GitHub App credentials. +githubAppSecret: "" + +# ============================================================================= +# Telemetry +# ============================================================================= + +telemetry: + # -- Enable Cloud Logging + cloudLogging: + enabled: false + gcpProjectId: "" + logId: "" + # -- Enable OTEL log bridge + otelLogBridge: + enabled: false + +# ============================================================================= +# Image Registry (for agent container images) +# ============================================================================= + +# -- Container image registry for agent images (e.g., ghcr.io/myorg) +imageRegistry: "" + +# ============================================================================= +# Kubernetes Resources +# ============================================================================= + +# -- Resource requests and limits for the hub pod +resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" + +# ============================================================================= +# Persistence (SQLite) +# ============================================================================= + +persistence: + # -- Enable persistent storage for SQLite database + enabled: true + # -- Storage class name (empty = default) + storageClass: "" + # -- PVC size + size: "10Gi" + # -- Access mode + accessMode: ReadWriteOnce + # -- Use an existing PVC instead of creating one + existingClaim: "" + +# ============================================================================= +# Service +# ============================================================================= + +service: + # -- Service type + type: ClusterIP + # -- Service port + port: 8080 + # -- Additional annotations (e.g., for cloud load balancers) + annotations: {} + +# ============================================================================= +# Ingress +# ============================================================================= + +ingress: + # -- Enable Ingress resource + enabled: false + # -- Ingress class name + className: "" + # -- Ingress annotations + annotations: {} + # -- Ingress hosts + hosts: + - host: hub.example.com + paths: + - path: / + pathType: Prefix + # -- Ingress TLS configuration + tls: [] + # - secretName: hub-tls + # hosts: + # - hub.example.com + +# ============================================================================= +# Service Account +# ============================================================================= + +serviceAccount: + # -- Create a ServiceAccount + create: true + # -- ServiceAccount name (auto-generated if empty) + name: "" + # -- Annotations (e.g., for GKE Workload Identity) + annotations: {} + # iam.gke.io/gcp-service-account: scion-hub@my-project.iam.gserviceaccount.com + +# ============================================================================= +# RBAC +# ============================================================================= + +rbac: + # -- Create RBAC resources for managing agent pods + create: true + # -- Use ClusterRole (true) or namespace-scoped Role (false) + clusterWide: false + # -- Namespace for agent pods (only used when clusterWide is false). + # Defaults to the release namespace. + agentNamespace: "" + # -- Enable SecretProviderClass CRD permissions (GKE Secret Store CSI) + secretProviderClass: false + +# ============================================================================= +# Pod Configuration +# ============================================================================= + +# -- Node selector +nodeSelector: {} + +# -- Tolerations +tolerations: [] + +# -- Affinity rules +affinity: {} + +# -- Pod annotations +podAnnotations: {} + +# -- Pod labels +podLabels: {} + +# -- Pod security context +podSecurityContext: + fsGroup: 65532 + +# -- Container security context +securityContext: + runAsNonRoot: true + runAsUser: 65532 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL