Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 24 additions & 29 deletions charts/github-sts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,39 @@ A Kubernetes Helm chart for deploying the GitHub Security Token Service (STS).

### Quick Start

1. **Using an existing secret (recommended):**
1. **Create a Kubernetes secret with your GitHub App private key:**

First, create the secret:
```bash
kubectl create secret generic github-sts-credentials \
--from-literal=github-app-id="YOUR_GITHUB_APP_ID" \
kubectl create secret generic my-github-app-credentials \
--from-file=github-app-private-key=/path/to/private_key.pem
```

Then install with the existing secret:
```bash
helm install github-sts . \
--set github.existingSecret="github-sts-credentials"
```

2. **With `--set-file` for the private key:**
2. **Install with the app configured:**

```bash
helm install github-sts . \
--set github.appId="YOUR_GITHUB_APP_ID" \
--set-file github.appPrivateKey=/path/to/private_key.pem
--set github.apps.default.appId="YOUR_GITHUB_APP_ID" \
--set github.apps.default.existingSecret="my-github-app-credentials"
```

> **Note:** Avoid passing multi-line PEM keys via `--set` on the command line.
> Use `--set-file`, an existing secret, or a values file instead to prevent
> shell history exposure and YAML escaping issues.

3. **Using Vault:**
3. **Multiple apps:**

If you have Vault integration configured:
```bash
export GITHUB_APP_ID=$(vault kv get -field=github_app_id homelab/github-action/octo-sts)
kubectl create secret generic app1-credentials \
--from-file=github-app-private-key=/path/to/app1_key.pem
kubectl create secret generic app2-credentials \
--from-file=github-app-private-key=/path/to/app2_key.pem

helm install github-sts . \
--set github.appId="$GITHUB_APP_ID" \
--set-file github.appPrivateKey=/path/to/private_key.pem
--set github.apps.app1.appId="111" \
--set github.apps.app1.existingSecret="app1-credentials" \
--set github.apps.app2.appId="222" \
--set github.apps.app2.existingSecret="app2-credentials"
```

> **Note:** Each app's private key must be stored in an existing Kubernetes Secret.
> The app name is used in policy paths: `{policy.basePath}/{appName}/{identity}.sts.yaml`

## Configuration

Key configuration options (see `values.yaml` for all options):
Expand All @@ -63,18 +58,16 @@ Key configuration options (see `values.yaml` for all options):
| `autoscaling.enabled` | `false` | Enable HPA |
| `ingress.enabled` | `false` | Enable Ingress (traditional API) |
| `httproute.enabled` | `false` | Enable HTTPRoute (Gateway API) |
| `github.appId` | `""` | GitHub App ID (required) |
| `github.appPrivateKey` | `""` | GitHub App Private Key (required) |
| `github.existingSecret` | `""` | Use an existing secret for credentials |
| `github.appName` | `"default"` | GitHub App name for env-configured app |
| `github.apps` | `{}` | Map of GitHub App configs (appId, existingSecret, secretPrivateKeyKey) |

## Ingress & Routing

### Ingress (Traditional)

```bash
helm install github-sts . \
--set github.existingSecret="github-sts-credentials" \
--set github.apps.default.appId="YOUR_APP_ID" \
--set github.apps.default.existingSecret="my-github-app-credentials" \
--set ingress.enabled=true \
--set ingress.className="nginx" \
--set ingress.hosts[0].host="github-sts.example.com"
Expand All @@ -86,7 +79,8 @@ Requires Gateway API CRDs. HTTPRoute is more powerful and flexible than Ingress.

```bash
helm install github-sts . \
--set github.existingSecret="github-sts-credentials" \
--set github.apps.default.appId="YOUR_APP_ID" \
--set github.apps.default.existingSecret="my-github-app-credentials" \
--set httproute.enabled=true \
--set httproute.parentRefs[0].name="my-gateway" \
--set httproute.hostnames[0]="github-sts.example.com"
Expand All @@ -96,7 +90,8 @@ helm install github-sts . \

```bash
helm upgrade github-sts . \
--set github.existingSecret="github-sts-credentials"
--set github.apps.default.appId="YOUR_APP_ID" \
--set github.apps.default.existingSecret="my-github-app-credentials"
```

## Uninstall
Expand Down
104 changes: 104 additions & 0 deletions charts/github-sts/ci/full-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# CI test values: full configuration with all features enabled
replicaCount: 2

image:
registry: "ghcr.io"
repository: "AlexandreODelisle/github-sts"
tag: "v1.0.0"

serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::role/github-sts"

service:
type: ClusterIP
port: 8080
targetPort: 8080

ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: github-sts.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: github-sts-tls
hosts:
- github-sts.example.com

autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
targetCPUUtilizationPercentage: 75

resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi

logging:
level: "INFO"
accessLevel: "INFO"
suppressHealthLogs: true
audit:
fileEnabled: true
filePath: "/var/log/github-sts/audit.json"
fileMaxBytes: 10485760
fileBackupCount: 5

policy:
backend: "github"
basePath: ".github/sts"
cacheTtlSeconds: 120

oidc:
allowedIssuers:
- "https://token.actions.githubusercontent.com"
- "https://accounts.google.com"

jti:
backend: "memory"
ttlSeconds: 3600

metrics:
enabled: true
prefix: "pygithubsts"
rateLimitPoll:
enabled: true
intervalSeconds: 60
reachabilityProbe:
enabled: true
intervalSeconds: 30

serviceMonitor:
enabled: true
interval: 30s
scrapeTimeout: 10s
path: /metrics
honorLabels: true

github:
apps:
default:
appId: 12345
existingSecret: "github-app-default-credentials"
deploy-bot:
appId: 67890
existingSecret: "deploy-bot-credentials"

extraEnv:
- name: LOG_FORMAT
value: "json"

podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
13 changes: 13 additions & 0 deletions charts/github-sts/ci/multi-app-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# CI test values: multiple GitHub Apps deployment
github:
apps:
deploy-bot:
appId: 11111
existingSecret: "deploy-bot-credentials"
release-bot:
appId: 22222
existingSecret: "release-bot-credentials"
ci-bot:
appId: 33333
existingSecret: "ci-bot-credentials"
secretPrivateKeyKey: "private-key.pem"
3 changes: 3 additions & 0 deletions charts/github-sts/ci/no-apps-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# CI test values: no apps configured (lint-only, should show WARNING in NOTES)
github:
apps: {}
6 changes: 6 additions & 0 deletions charts/github-sts/ci/single-app-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# CI test values: single GitHub App deployment
github:
apps:
default:
appId: 12345
existingSecret: "github-app-default-credentials"
14 changes: 10 additions & 4 deletions charts/github-sts/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ Access the application via port-forward:

{{- end }}

{{- if and (not .Values.github.appId) (not .Values.github.existingSecret) }}

WARNING: No GitHub App credentials configured!
Set github.appId and github.appPrivateKey, or provide github.existingSecret.
{{- if not .Values.github.apps }}

WARNING: No GitHub Apps configured!
Configure at least one app under github.apps with appId and existingSecret.
Example:
github:
apps:
default:
appId: "12345"
existingSecret: "my-github-app-credentials"
{{- end }}

{{- if .Values.serviceMonitor.enabled }}
Expand Down
17 changes: 3 additions & 14 deletions charts/github-sts/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,10 @@ Return the proper image name.
{{- end }}

{{/*
Return true if GitHub credentials are configured (either via existingSecret or inline values).
Return true if at least one GitHub App is configured.
*/}}
{{- define "github-sts.hasCredentials" -}}
{{- if or .Values.github.existingSecret (and .Values.github.appId .Values.github.appPrivateKey) -}}
{{- define "github-sts.hasApps" -}}
{{- if .Values.github.apps -}}
true
{{- end -}}
{{- end }}

{{/*
Return the name of the credentials secret.
*/}}
{{- define "github-sts.credentialsSecretName" -}}
{{- if .Values.github.existingSecret -}}
{{- .Values.github.existingSecret }}
{{- else -}}
{{- include "github-sts.fullname" . }}-credentials
{{- end -}}
{{- end }}
9 changes: 9 additions & 0 deletions charts/github-sts/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ data:
rate_limit_poll_interval_seconds: {{ .Values.metrics.rateLimitPoll.intervalSeconds }}
reachability_probe_enabled: {{ .Values.metrics.reachabilityProbe.enabled }}
reachability_probe_interval_seconds: {{ .Values.metrics.reachabilityProbe.intervalSeconds }}

{{- if .Values.github.apps }}
apps:
{{- range $appName, $appConfig := .Values.github.apps }}
{{ $appName }}:
app_id: {{ $appConfig.appId | int }}
private_key_path: {{ printf "/etc/github-sts/apps/%s/%s" $appName ($appConfig.secretPrivateKeyKey | default "github-app-private-key") | quote }}
{{- end }}
{{- end }}
28 changes: 13 additions & 15 deletions charts/github-sts/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ spec:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
Expand Down Expand Up @@ -45,20 +44,6 @@ spec:
env:
- name: PYGITHUBSTS_CONFIG_PATH
value: "/etc/github-sts/config.yaml"
- name: PYGITHUBSTS_GITHUB_APP_NAME
value: {{ .Values.github.appName | quote }}
{{- if include "github-sts.hasCredentials" . }}
- name: PYGITHUBSTS_GITHUB_APP_ID
valueFrom:
secretKeyRef:
name: {{ include "github-sts.credentialsSecretName" . }}
key: {{ .Values.github.secretAppIdKey | default "github-app-id" }}
- name: PYGITHUBSTS_GITHUB_APP_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: {{ include "github-sts.credentialsSecretName" . }}
key: {{ .Values.github.secretPrivateKeyKey | default "github-app-private-key" }}
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
Expand Down Expand Up @@ -99,6 +84,11 @@ spec:
{{- with .Values.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- range $appName, $appConfig := .Values.github.apps }}
- name: github-app-{{ $appName }}-key
mountPath: /etc/github-sts/apps/{{ $appName }}
readOnly: true
{{- end }}
volumes:
- name: tmp
emptyDir: {}
Expand All @@ -113,6 +103,14 @@ spec:
{{- with .Values.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- range $appName, $appConfig := .Values.github.apps }}
- name: github-app-{{ $appName }}-key
secret:
secretName: {{ $appConfig.existingSecret }}
items:
- key: {{ $appConfig.secretPrivateKeyKey | default "github-app-private-key" }}
path: {{ $appConfig.secretPrivateKeyKey | default "github-app-private-key" }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
Expand Down
15 changes: 2 additions & 13 deletions charts/github-sts/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,2 @@
{{- if and (not .Values.github.existingSecret) .Values.github.appId .Values.github.appPrivateKey }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "github-sts.credentialsSecretName" . }}
labels:
{{- include "github-sts.labels" . | nindent 4 }}
type: Opaque
stringData:
github-app-id: {{ .Values.github.appId | quote }}
github-app-private-key: |
{{- .Values.github.appPrivateKey | nindent 4 }}
{{- end }}
{{/* Secret is no longer created by the chart. */}}
{{/* All GitHub App credentials must be provided via existingSecret in github.apps entries. */}}
Loading
Loading