diff --git a/.github/workflows/release-production.yml b/.github/workflows/release-production.yml index e783c81..e818e57 100644 --- a/.github/workflows/release-production.yml +++ b/.github/workflows/release-production.yml @@ -44,4 +44,4 @@ jobs: cache-to: type=gha,mode=max platforms: linux/amd64, linux/arm64 push: true - tags: ${{ env.REGISTRY }}/${{ github.repository }}:auth-layer-proxy-${{env.TAG}} + tags: ${{ env.REGISTRY }}/${{ github.repository }}:auth-layer-proxy-${{ env.TAG }} diff --git a/charts/auth-layer-proxy/.helmignore b/charts/auth-layer-proxy/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/auth-layer-proxy/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/auth-layer-proxy/Chart.yaml b/charts/auth-layer-proxy/Chart.yaml new file mode 100644 index 0000000..041a4f4 --- /dev/null +++ b/charts/auth-layer-proxy/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: auth-layer-proxy +description: A Helm chart for deploying the auth-layer-proxy onto a Kubernetes cluster +type: application +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/auth-layer-proxy/README.md b/charts/auth-layer-proxy/README.md new file mode 100644 index 0000000..db2ac01 --- /dev/null +++ b/charts/auth-layer-proxy/README.md @@ -0,0 +1,73 @@ +# HederaTheGraph (HTG) Authentication Layer Proxy Helm Chart + +This chart deploys the HederaTheGraph (HTG) Authentication Layer Proxy to your Kubernetes cluster. +Is based on the project [auth-layer-proxy](link) and is a proxy that adds authentication to the requests made to the TheGraph Admin API. + +## Prerequisites +- Minikube or a Kubernetes cluster [(more here)](https://minikube.sigs.k8s.io/docs/start/) +- Helm 3 [(install instructions here)](https://helm.sh/docs/intro/install/) +- kubectl [(install instructions here)](https://kubernetes.io/docs/tasks/tools/) +- HederaTheGraph Authentication Layer Server [(more here)](https://github.com/hashgraph/hedera-the-graph/tree/main/charts/auth-layer-server) +- HederaTheGraph [(more here)](https://github.com/hashgraph/hedera-the-graph/tree/main/charts/hedera-the-graph) + +## Installation + +To install the Authentication Layer Proxy, run the following commands: + +```bash +helm install htg-auth-proxy . --set configSecrets.clientSecret="" +``` + + +### Helm Chart Overrides +As part of the installation, you can override the default values of the chart. + +Is recommended to use the `values.yaml` file to set the values you want to override. +The following table lists the configurable parameters of the chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `image.repository` | The image repository to pull from | `hederahtg/auth-layer-proxy` | +| `image.tagPrefix` | The image prefix within the repo to pull | `auth-layer-proxy-` | +| `image.tag` | The image tag to pull | `main` | +| `image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `service.type` | The service type | `ClusterIP` | +| `service.proxyPort` | Service port for the proxy endpoint | `10000` | +| `service.adminPort` | Service port for the envoy admin endpoint | `15000` | +| `configEnv` | Configuration environment variables | `[]` | +| `configEnv.SERVICE_TYPE` | EnvoyProxy Configuration downstream address type, can be `LOGICAL_DNS` for a FQDN or `STATIC` when using an IP address | `LOGICAL_DNS` | +| `configEnv.SERVICE_ADDRESS` | EnvoyProxy Configuration downstream address, can be either a FQDN or an IP | `host.docker.internal` | +| `configEnv.SERVICE_PORT` | EnvoyProxy Configuration downstream port, this would be the admin port on TheGraph indexer node | `8020` | +| `configEnv.ENVOY_ADMIN_PORT` | EnvoyProxy Configuration admin port | `15000` | +| `configEnv.PROXY_PORT` | EnvoyProxy Configuration proxy port | `10000` | +| `configEnv.CLIENT_ID` | OAuth Client ID, provided by the auth server | `htg-auth-layer` | +| `configEnv.TOKEN_INTROSPECTION_URL` | OAuth Token Introspection URL, provided by the auth server | `http://host.docker.internal:8080/realms/HederaTheGraph/protocol/openid-connect/token/introspect` | +| `configSecrets.clientSecret` | OAuth Client Secret, provided by the auth server | `` | +| `global.auth.clientSecret` | Global OAuth Client Secret, provided by the auth server, has precedence over `configSecrets.clientSecret` | `` | + +*It is important to note that if the downstream service that we are protecting (in this case TheGraph) will be accessed by the proxy using a FQDN, the `SERVICE_TYPE` should be set to `LOGICAL_DNS` and the `SERVICE_ADDRESS` should be set to the FQDN of the service. Otherwise, if the downstream service is accessed by the proxy using an IP address, the `SERVICE_TYPE` should be set to `STATIC` and the `SERVICE_ADDRESS` should be set to the IP address of the service.* + +### Client Secret Configuration +`auth-layer-proxy` needs a valid `clientSecret` to be able to authenticate with the auth server. This can be provided as a `configSecrets.clientSecret` or as a global `global.auth.clientSecret`. + +`global.auth.clientSecret` has precedence over `configSecrets.clientSecret`. + +#### Install with Client Secret +```bash +helm install htg-auth-proxy . --set configSecrets.clientSecret="" +``` + +#### Install with Global Client Secret +```bash +helm install htg-auth-proxy . --set global.auth.clientSecret="" +``` +### None Provided +If none is provided, the installation will fail with the following error: +``` +A valid client secret must be provided either via .Values.global.auth.clientSecret or .Values.configSecrets.clientSecret +``` +#### Update Client Secret +*Once the chart is installed, the `clientSecret` can be updated using the following command:* +```bash +helm upgrade . --set configSecrets.clientSecret="" +``` diff --git a/charts/auth-layer-proxy/templates/_helpers.tpl b/charts/auth-layer-proxy/templates/_helpers.tpl new file mode 100644 index 0000000..da99bae --- /dev/null +++ b/charts/auth-layer-proxy/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "auth-layer-proxy.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 "auth-layer-proxy.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 "auth-layer-proxy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "auth-layer-proxy.labels" -}} +helm.sh/chart: {{ include "auth-layer-proxy.chart" . }} +{{ include "auth-layer-proxy.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "auth-layer-proxy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "auth-layer-proxy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "auth-layer-proxy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "auth-layer-proxy.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/auth-layer-proxy/templates/configmap.yaml b/charts/auth-layer-proxy/templates/configmap.yaml new file mode 100644 index 0000000..abd3bc6 --- /dev/null +++ b/charts/auth-layer-proxy/templates/configmap.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "auth-layer-proxy.fullname" . }}-env +data: + {{- range $key, $value := .Values.configEnv }} + {{ $key }}: {{ $value | quote }} + {{- end }} diff --git a/charts/auth-layer-proxy/templates/deployment.yaml b/charts/auth-layer-proxy/templates/deployment.yaml new file mode 100644 index 0000000..59ecd07 --- /dev/null +++ b/charts/auth-layer-proxy/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "auth-layer-proxy.fullname" . }} + labels: + {{- include "auth-layer-proxy.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "auth-layer-proxy.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "auth-layer-proxy.selectorLabels" . | nindent 8 }} + spec: + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + containers: + - command: {{ .Values.command }} + envFrom: + - configMapRef: + name: {{ include "auth-layer-proxy.fullname" . }}-env + - secretRef: + name: {{ include "auth-layer-proxy.fullname" . }}-secret + image: "{{ .Values.image.repository }}:{{ .Values.image.tagPrefix }}{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + livenessProbe: + httpGet: + path: /server_info + port: {{ .Values.configEnv.ENVOY_ADMIN_PORT }} + name: {{ .Chart.Name }} + ports: + - containerPort: {{ .Values.configEnv.PROXY_PORT }} + name: proxy + protocol: TCP + - containerPort: {{ .Values.configEnv.ENVOY_ADMIN_PORT }} + name: admin + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: {{ .Values.configEnv.ENVOY_ADMIN_PORT }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + serviceAccountName: {{ include "auth-layer-proxy.serviceAccountName" . }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + diff --git a/charts/auth-layer-proxy/templates/secret.yaml b/charts/auth-layer-proxy/templates/secret.yaml new file mode 100644 index 0000000..f7ef780 --- /dev/null +++ b/charts/auth-layer-proxy/templates/secret.yaml @@ -0,0 +1,8 @@ +{{- $clientSecret := .Values.global.auth.clientSecret | default .Values.configSecrets.clientSecret -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "auth-layer-proxy.fullname" . }}-secret +type: Opaque +data: + CLIENT_SECRET: {{ $clientSecret | required "A valid client secret must be provided either via .Values.global.auth.clientSecret or .Values.configSecrets.clientSecret" | b64enc }} diff --git a/charts/auth-layer-proxy/templates/service.yaml b/charts/auth-layer-proxy/templates/service.yaml new file mode 100644 index 0000000..264c0ef --- /dev/null +++ b/charts/auth-layer-proxy/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "auth-layer-proxy.fullname" . }} + labels: + {{- include "auth-layer-proxy.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - name: proxy + port: {{ .Values.service.proxyPort }} + targetPort: {{ .Values.configEnv.PROXY_PORT }} + - name: admin + port: {{ .Values.service.adminPort }} + targetPort: {{ .Values.configEnv.ENVOY_ADMIN_PORT }} + selector: + {{- include "auth-layer-proxy.selectorLabels" . | nindent 4 }} diff --git a/charts/auth-layer-proxy/templates/serviceaccount.yaml b/charts/auth-layer-proxy/templates/serviceaccount.yaml new file mode 100644 index 0000000..ca85393 --- /dev/null +++ b/charts/auth-layer-proxy/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "auth-layer-proxy.serviceAccountName" . }} + labels: + {{- include "auth-layer-proxy.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/auth-layer-proxy/values.yaml b/charts/auth-layer-proxy/values.yaml new file mode 100644 index 0000000..4b2d4ec --- /dev/null +++ b/charts/auth-layer-proxy/values.yaml @@ -0,0 +1,55 @@ +affinity: {} + +command: ["/etc/envoy/start-envoy.sh"] + +configEnv: + CLIENT_ID: "htg-auth-layer" + ENVOY_ADMIN_PORT: "15000" + PROXY_PORT: "10000" + SERVICE_ADDRESS: "host.docker.internal" + SERVICE_PORT: "8020" + SERVICE_TYPE: "LOGICAL_DNS" + TOKEN_INTROSPECTION_URL: "http://host.docker.internal:8080/realms/HederaTheGraph/protocol/openid-connect/token/introspect" + + +configSecrets: + # If not provided, the helm chart will fail to render the templates + clientSecret: "" + +fullnameOverride: "" + +global: + auth: + clientSecret: "" + +image: + pullPolicy: IfNotPresent + repository: ghcr.io/hashgraph/hedera-the-graph + tag: "main" + tagPrefix: "auth-layer-proxy-" + +imagePullSecrets: [] + +nameOverride: "" + +nodeSelector: {} + +podAnnotations: {} + +podSecurityContext: {} + +resources: {} + +securityContext: {} + +service: + adminPort: 15000 + proxyPort: 10000 + type: ClusterIP + +serviceAccount: + annotations: {} + create: true + name: "" + +tolerations: []