Fix Helm chart self-hosting footguns
Address the highest-impact Kubernetes chart issues from #1245. Align PG_ADDR with postgresql.host/port, wire OAUTH2_SERVER_SIGNING_KEY, add early validation for required base64 and PEM secrets, and isolate the main service/deployment with component labels so Chrome pods are not selected by server traffic. Update chart values and documentation to clarify required secret formats, managed PostgreSQL prerequisites, ACME account key persistence, and current Azure Blob compatibility caveats for S3 proxy deployments. Signed-off-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
committed by
Bryan Frimin
parent
e732f7e706
commit
7191a28be2
@@ -40,6 +40,8 @@ export ENCRYPTION_KEY=$(openssl rand -base64 32)
|
|||||||
export COOKIE_SECRET=$(openssl rand -base64 32)
|
export COOKIE_SECRET=$(openssl rand -base64 32)
|
||||||
export PASSWORD_PEPPER=$(openssl rand -base64 32)
|
export PASSWORD_PEPPER=$(openssl rand -base64 32)
|
||||||
export TRUST_TOKEN_SECRET=$(openssl rand -base64 32)
|
export TRUST_TOKEN_SECRET=$(openssl rand -base64 32)
|
||||||
|
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
|
||||||
|
-out oauth2_signing_key.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Download remote dependencies
|
#### Download remote dependencies
|
||||||
@@ -57,6 +59,7 @@ helm install my-probo ./charts/probo \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.enabled=true \
|
--set postgresql.enabled=true \
|
||||||
--set postgresql.auth.postgresUser="probod" \
|
--set postgresql.auth.postgresUser="probod" \
|
||||||
--set postgresql.auth.postgresPassword="your-db-password" \
|
--set postgresql.auth.postgresPassword="your-db-password" \
|
||||||
@@ -76,6 +79,7 @@ helm install my-probo ./charts/probo \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set probo.mailer.smtp.password="smtp-password" \
|
--set probo.mailer.smtp.password="smtp-password" \
|
||||||
--set postgresql.enabled=true \
|
--set postgresql.enabled=true \
|
||||||
--set postgresql.auth.postgresPassword="probod" \
|
--set postgresql.auth.postgresPassword="probod" \
|
||||||
@@ -174,6 +178,7 @@ All deployments require:
|
|||||||
- `probo.auth.cookieSecret` - For session management
|
- `probo.auth.cookieSecret` - For session management
|
||||||
- `probo.auth.passwordPepper` - For password hashing
|
- `probo.auth.passwordPepper` - For password hashing
|
||||||
- `probo.trustAuth.tokenSecret` - For trust center tokens
|
- `probo.trustAuth.tokenSecret` - For trust center tokens
|
||||||
|
- `probo.oauth2.signingKey` - PEM private key used to sign OAuth2 tokens
|
||||||
- `postgresql.host` - PostgreSQL server hostname
|
- `postgresql.host` - PostgreSQL server hostname
|
||||||
- `postgresql.password` - Database password
|
- `postgresql.password` - Database password
|
||||||
- `s3.accessKeyId` - S3 access credentials
|
- `s3.accessKeyId` - S3 access credentials
|
||||||
@@ -200,6 +205,7 @@ helm install my-probo ././charts/probo \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.host="mydb.abc123.us-east-1.rds.amazonaws.com" \
|
--set postgresql.host="mydb.abc123.us-east-1.rds.amazonaws.com" \
|
||||||
--set postgresql.password="<rds-password>" \
|
--set postgresql.password="<rds-password>" \
|
||||||
--set s3.region="us-east-1" \
|
--set s3.region="us-east-1" \
|
||||||
@@ -225,6 +231,7 @@ helm install my-probo ././charts/probo \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.host="10.0.0.5" \
|
--set postgresql.host="10.0.0.5" \
|
||||||
--set postgresql.password="<cloudsql-password>" \
|
--set postgresql.password="<cloudsql-password>" \
|
||||||
--set s3.endpoint="https://storage.googleapis.com" \
|
--set s3.endpoint="https://storage.googleapis.com" \
|
||||||
@@ -235,7 +242,8 @@ helm install my-probo ././charts/probo \
|
|||||||
|
|
||||||
### Azure
|
### Azure
|
||||||
- PostgreSQL: Azure Database for PostgreSQL
|
- PostgreSQL: Azure Database for PostgreSQL
|
||||||
- Storage: Azure Blob Storage (with S3 compatibility)
|
- Storage: Prefer native S3-compatible backends (Azure Blob via S3 proxies is
|
||||||
|
currently not officially supported)
|
||||||
- Kubernetes: Azure Kubernetes Service (AKS)
|
- Kubernetes: Azure Kubernetes Service (AKS)
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
@@ -244,12 +252,13 @@ helm install my-probo ././charts/probo \
|
|||||||
```bash
|
```bash
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
# - Azure Database for PostgreSQL instance
|
# - Azure Database for PostgreSQL instance
|
||||||
# - Azure Blob Storage container with S3 compatibility
|
# - Prefer AWS S3/GCS/Spaces (Azure Blob via S3 proxy is not officially supported)
|
||||||
helm install my-probo ././charts/probo \
|
helm install my-probo ././charts/probo \
|
||||||
--set probo.encryptionKey="$ENCRYPTION_KEY" \
|
--set probo.encryptionKey="$ENCRYPTION_KEY" \
|
||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.host="mydb.postgres.database.azure.com" \
|
--set postgresql.host="mydb.postgres.database.azure.com" \
|
||||||
--set postgresql.password="<azure-db-password>" \
|
--set postgresql.password="<azure-db-password>" \
|
||||||
--set s3.endpoint="https://<your-storage-account>.blob.core.windows.net" \
|
--set s3.endpoint="https://<your-storage-account>.blob.core.windows.net" \
|
||||||
@@ -259,7 +268,9 @@ helm install my-probo ././charts/probo \
|
|||||||
--set s3.usePathStyle=true
|
--set s3.usePathStyle=true
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** Azure Blob Storage requires `s3.usePathStyle=true` to construct URLs correctly (path-style: `https://account.blob.core.windows.net/container/...` instead of virtual-hosted style: `https://bucket.account.blob.core.windows.net/...`).
|
> **Note:** `s3.usePathStyle=true` is necessary for some S3-compatible
|
||||||
|
> providers, but it does not address known Azure Blob metadata incompatibilities
|
||||||
|
> when used behind S3 proxies.
|
||||||
|
|
||||||
### DigitalOcean
|
### DigitalOcean
|
||||||
- PostgreSQL: Managed PostgreSQL Database
|
- PostgreSQL: Managed PostgreSQL Database
|
||||||
@@ -277,6 +288,7 @@ helm install my-probo ././charts/probo \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.host="db-postgresql-nyc1-12345.ondigitalocean.com" \
|
--set postgresql.host="db-postgresql-nyc1-12345.ondigitalocean.com" \
|
||||||
--set postgresql.password="<db-password>" \
|
--set postgresql.password="<db-password>" \
|
||||||
--set s3.region="nyc3" \
|
--set s3.region="nyc3" \
|
||||||
@@ -391,6 +403,7 @@ spec:
|
|||||||
| metrics.serviceMonitor.relabelings | list | `[]` | Relabeling configs for the ServiceMonitor |
|
| metrics.serviceMonitor.relabelings | list | `[]` | Relabeling configs for the ServiceMonitor |
|
||||||
| probo.baseUrl | string | `"probo.example.com"` | Public hostname where Probo will be accessible |
|
| probo.baseUrl | string | `"probo.example.com"` | Public hostname where Probo will be accessible |
|
||||||
| probo.encryptionKey | string | `""` | **REQUIRED** Base64-encoded encryption key (generate with: openssl rand -base64 32) |
|
| probo.encryptionKey | string | `""` | **REQUIRED** Base64-encoded encryption key (generate with: openssl rand -base64 32) |
|
||||||
|
| probo.oauth2.signingKey | string | `""` | **REQUIRED** PEM private key for OAuth2 signing (set with --set-file) |
|
||||||
| probo.service.port | int | `8080` | Probo application service port |
|
| probo.service.port | int | `8080` | Probo application service port |
|
||||||
| probo.metrics.port | int | `8081` | Probo metrics service port |
|
| probo.metrics.port | int | `8081` | Probo metrics service port |
|
||||||
| probo.tracing.enabled | bool | `false` | Enable OpenTelemetry tracing |
|
| probo.tracing.enabled | bool | `false` | Enable OpenTelemetry tracing |
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ This Helm chart deploys Probo - an open-source SOC-2 compliance platform - on Ku
|
|||||||
- S3 or S3-compatible object storage (AWS S3, GCS, DigitalOcean Spaces, SeaweedFS, etc.)
|
- S3 or S3-compatible object storage (AWS S3, GCS, DigitalOcean Spaces, SeaweedFS, etc.)
|
||||||
- OpenSSL installed (for generating secrets)
|
- OpenSSL installed (for generating secrets)
|
||||||
|
|
||||||
|
> Azure Blob behind S3 compatibility proxies currently has known metadata
|
||||||
|
> compatibility issues. Prefer native S3-compatible backends for production.
|
||||||
|
|
||||||
## Installing the Chart
|
## Installing the Chart
|
||||||
|
|
||||||
### From OCI Registry
|
### From OCI Registry
|
||||||
@@ -21,6 +24,7 @@ helm install probo oci://artifact.probo.inc/probo/probo --version <chart-version
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set postgresql.host="postgres.example.com" \
|
--set postgresql.host="postgres.example.com" \
|
||||||
--set postgresql.password="<db-password>" \
|
--set postgresql.password="<db-password>" \
|
||||||
--set s3.bucket="probo-production" \
|
--set s3.bucket="probo-production" \
|
||||||
@@ -39,6 +43,10 @@ export COOKIE_SECRET=$(openssl rand -base64 32)
|
|||||||
export PASSWORD_PEPPER=$(openssl rand -base64 32)
|
export PASSWORD_PEPPER=$(openssl rand -base64 32)
|
||||||
export TRUST_TOKEN_SECRET=$(openssl rand -base64 32)
|
export TRUST_TOKEN_SECRET=$(openssl rand -base64 32)
|
||||||
|
|
||||||
|
# Generate OAuth2 signing key (PEM)
|
||||||
|
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
|
||||||
|
-out oauth2_signing_key.pem
|
||||||
|
|
||||||
# Generate private key and certificate valid for 10 years
|
# Generate private key and certificate valid for 10 years
|
||||||
TEMP_KEY=$(mktemp)
|
TEMP_KEY=$(mktemp)
|
||||||
TEMP_CERT=$(mktemp)
|
TEMP_CERT=$(mktemp)
|
||||||
@@ -65,6 +73,7 @@ helm install probo . \
|
|||||||
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
--set probo.auth.cookieSecret="$COOKIE_SECRET" \
|
||||||
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
--set probo.auth.passwordPepper="$PASSWORD_PEPPER" \
|
||||||
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
--set probo.trustAuth.tokenSecret="$TRUST_TOKEN_SECRET" \
|
||||||
|
--set-file probo.oauth2.signingKey="./oauth2_signing_key.pem" \
|
||||||
--set probo.saml.privateKey="$SAML_PRIVATE_KEY" \
|
--set probo.saml.privateKey="$SAML_PRIVATE_KEY" \
|
||||||
--set probo.saml.certificate="$SAML_CERTIFICATE" \
|
--set probo.saml.certificate="$SAML_CERTIFICATE" \
|
||||||
--set postgresql.host="postgres.example.com" \
|
--set postgresql.host="postgres.example.com" \
|
||||||
@@ -111,6 +120,8 @@ probo:
|
|||||||
cookieDomain: "example.com"
|
cookieDomain: "example.com"
|
||||||
cookieSecret: "<secret>"
|
cookieSecret: "<secret>"
|
||||||
passwordPepper: "<secret>"
|
passwordPepper: "<secret>"
|
||||||
|
oauth2:
|
||||||
|
signingKey: "<PEM private key>"
|
||||||
trustAuth:
|
trustAuth:
|
||||||
cookieDomain: "example.com"
|
cookieDomain: "example.com"
|
||||||
tokenSecret: "<secret>"
|
tokenSecret: "<secret>"
|
||||||
@@ -156,11 +167,20 @@ The following parameters **must** be configured:
|
|||||||
| `probo.auth.cookieSecret` | Cookie signing secret (32+ bytes) |
|
| `probo.auth.cookieSecret` | Cookie signing secret (32+ bytes) |
|
||||||
| `probo.auth.passwordPepper` | Password hashing pepper (32+ bytes) |
|
| `probo.auth.passwordPepper` | Password hashing pepper (32+ bytes) |
|
||||||
| `probo.trustAuth.tokenSecret` | Trust token secret (32+ bytes) |
|
| `probo.trustAuth.tokenSecret` | Trust token secret (32+ bytes) |
|
||||||
|
| `probo.oauth2.signingKey` | PEM-encoded OAuth2 private signing key |
|
||||||
| `postgresql.host` | PostgreSQL hostname |
|
| `postgresql.host` | PostgreSQL hostname |
|
||||||
| `postgresql.password` | PostgreSQL password |
|
| `postgresql.password` | PostgreSQL password |
|
||||||
| `s3.accessKeyId` | S3 access key ID |
|
| `s3.accessKeyId` | S3 access key ID |
|
||||||
| `s3.secretAccessKey` | S3 secret access key |
|
| `s3.secretAccessKey` | S3 secret access key |
|
||||||
|
|
||||||
|
### Secret Format Quick Reference
|
||||||
|
|
||||||
|
- `probo.encryptionKey`, `probo.auth.cookieSecret`,
|
||||||
|
`probo.auth.passwordPepper`, `probo.trustAuth.tokenSecret`:
|
||||||
|
base64-encoded 32-byte secrets (for example: `openssl rand -base64 32`)
|
||||||
|
- `probo.oauth2.signingKey`: PEM-encoded private key (`--set-file` strongly
|
||||||
|
recommended)
|
||||||
|
|
||||||
### Key Configuration Parameters
|
### Key Configuration Parameters
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
| Parameter | Description | Default |
|
||||||
@@ -169,6 +189,7 @@ The following parameters **must** be configured:
|
|||||||
| `image.tag` | Probo image tag | Chart appVersion |
|
| `image.tag` | Probo image tag | Chart appVersion |
|
||||||
| `replicaCount` | Number of Probo replicas | `1` |
|
| `replicaCount` | Number of Probo replicas | `1` |
|
||||||
| `probo.baseUrl` | Public baseUrl | `probo.example.com` |
|
| `probo.baseUrl` | Public baseUrl | `probo.example.com` |
|
||||||
|
| `probo.oauth2.signingKey` | OAuth2 signing key (PEM private key) | `""` (required) |
|
||||||
| `postgresql.host` | PostgreSQL host | `""` (required) |
|
| `postgresql.host` | PostgreSQL host | `""` (required) |
|
||||||
| `postgresql.port` | PostgreSQL port | `5432` |
|
| `postgresql.port` | PostgreSQL port | `5432` |
|
||||||
| `postgresql.database` | Database name | `probod` |
|
| `postgresql.database` | Database name | `probod` |
|
||||||
@@ -178,7 +199,7 @@ The following parameters **must** be configured:
|
|||||||
| `s3.bucket` | S3 bucket name | `probod` |
|
| `s3.bucket` | S3 bucket name | `probod` |
|
||||||
| `s3.region` | AWS region | `us-east-1` |
|
| `s3.region` | AWS region | `us-east-1` |
|
||||||
| `s3.endpoint` | S3 endpoint (for S3-compatible) | `""` |
|
| `s3.endpoint` | S3 endpoint (for S3-compatible) | `""` |
|
||||||
| `s3.usePathStyle` | Use path-style URLs (required for Azure Blob Storage) | `false` |
|
| `s3.usePathStyle` | Use path-style URLs for selected S3-compatible backends | `false` |
|
||||||
| `chrome.enabled` | Deploy Chrome | `true` |
|
| `chrome.enabled` | Deploy Chrome | `true` |
|
||||||
| `chrome.external.addr` | External Chrome (if disabled) | `""` |
|
| `chrome.external.addr` | External Chrome (if disabled) | `""` |
|
||||||
| `ingress.enabled` | Enable ingress | `false` |
|
| `ingress.enabled` | Enable ingress | `false` |
|
||||||
@@ -204,9 +225,25 @@ The chart deploys the following:
|
|||||||
|
|
||||||
Database migrations run automatically when Probo starts. No manual intervention is required.
|
Database migrations run automatically when Probo starts. No manual intervention is required.
|
||||||
|
|
||||||
|
For managed PostgreSQL providers (notably PostgreSQL >= 15), ensure the
|
||||||
|
Probo role can own and modify the `public` schema before first startup:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER SCHEMA public OWNER TO probod;
|
||||||
|
GRANT ALL ON SCHEMA public TO probod;
|
||||||
|
```
|
||||||
|
|
||||||
|
Probo migrations also require these extensions to be installable:
|
||||||
|
|
||||||
|
- `citext`
|
||||||
|
- `pgcrypto`
|
||||||
|
- `unaccent`
|
||||||
|
- `pg_stat_statements`
|
||||||
|
|
||||||
### TLS/SSL Configuration
|
### TLS/SSL Configuration
|
||||||
|
|
||||||
For secure PostgreSQL connections, you can provide a CA certificate bundle in two ways:
|
For secure PostgreSQL connections, you can provide a CA certificate bundle in
|
||||||
|
two ways:
|
||||||
|
|
||||||
1. **Inline CA Bundle** (`postgresql.caBundle`): Provide the certificate content directly in values.yaml
|
1. **Inline CA Bundle** (`postgresql.caBundle`): Provide the certificate content directly in values.yaml
|
||||||
```yaml
|
```yaml
|
||||||
@@ -234,7 +271,8 @@ For secure PostgreSQL connections, you can provide a CA certificate bundle in tw
|
|||||||
readOnly: true
|
readOnly: true
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** Using `caBundlePath` is recommended for large CA bundles (e.g., system CA bundles) as it avoids environment variable size limitations.
|
**Note:** Using `caBundlePath` is recommended for large CA bundles (for
|
||||||
|
example system CA bundles) as it avoids environment variable size limitations.
|
||||||
|
|
||||||
### Backup
|
### Backup
|
||||||
|
|
||||||
@@ -277,6 +315,15 @@ Check the Probo logs for database connection errors. The application will fail t
|
|||||||
|
|
||||||
Check the Probo logs for S3 connection errors when uploading files.
|
Check the Probo logs for S3 connection errors when uploading files.
|
||||||
|
|
||||||
|
### `IP geolocation table is empty` warning
|
||||||
|
|
||||||
|
If startup logs show:
|
||||||
|
|
||||||
|
`IP geolocation table is empty; run geoloc-import to populate it`
|
||||||
|
|
||||||
|
the instance is running correctly, but geolocation data is missing. Populate
|
||||||
|
it by running the `geoloc-import` command in your operational workflow.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### AWS Deployment
|
### AWS Deployment
|
||||||
|
|||||||
@@ -157,3 +157,34 @@ Chrome DevTools Protocol address
|
|||||||
{{- .Values.chrome.external.addr | required "chrome.external.addr is required when chrome.enabled=false" }}
|
{{- .Values.chrome.external.addr | required "chrome.external.addr is required when chrome.enabled=false" }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Validate a required 32-byte base64 secret.
|
||||||
|
*/}}
|
||||||
|
{{- define "probo.requireBase64Key32" -}}
|
||||||
|
{{- $name := .name -}}
|
||||||
|
{{- $value := .value | required (printf "%s is required" $name) -}}
|
||||||
|
{{- if not (regexMatch "^[A-Za-z0-9+/]{43}=$" $value) -}}
|
||||||
|
{{- fail (printf "%s must be a base64-encoded 32-byte secret (example: openssl rand -base64 32)" $name) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $decoded := b64dec $value -}}
|
||||||
|
{{- if ne (len $decoded) 32 -}}
|
||||||
|
{{- fail (printf "%s must decode to exactly 32 bytes" $name) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $value -}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Validate a required PEM private key.
|
||||||
|
*/}}
|
||||||
|
{{- define "probo.requirePEMPrivateKey" -}}
|
||||||
|
{{- $name := .name -}}
|
||||||
|
{{- $value := .value | required (printf "%s is required" $name) -}}
|
||||||
|
{{- if not (contains "-----BEGIN" $value) -}}
|
||||||
|
{{- fail (printf "%s must be a PEM-encoded private key" $name) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if not (contains "PRIVATE KEY-----" $value) -}}
|
||||||
|
{{- fail (printf "%s must be a PEM-encoded private key" $name) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $value -}}
|
||||||
|
{{- end }}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ spec:
|
|||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
{{- include "probo.selectorLabels" . | nindent 6 }}
|
{{- include "probo.selectorLabels" . | nindent 6 }}
|
||||||
|
app.kubernetes.io/component: server
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@@ -20,6 +21,7 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "probo.labels" . | nindent 8 }}
|
{{- include "probo.labels" . | nindent 8 }}
|
||||||
|
app.kubernetes.io/component: server
|
||||||
{{- with .Values.podLabels }}
|
{{- with .Values.podLabels }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -75,7 +77,7 @@ spec:
|
|||||||
value: {{ join "," .Values.probo.cors.allowedOrigins | quote }}
|
value: {{ join "," .Values.probo.cors.allowedOrigins | quote }}
|
||||||
# PostgreSQL Database
|
# PostgreSQL Database
|
||||||
- name: PG_ADDR
|
- name: PG_ADDR
|
||||||
value: {{ if .Values.postgresql.enabled }}{{ printf "%s-postgresql-demo:5432" .Release.Name | quote }}{{ else }}{{ .Values.probo.pg.addr | required "probo.pg.addr is required when postgresql.enabled=false" | quote }}{{ end }}
|
value: {{ printf "%s:%v" (include "probo.postgresql.host" .) (include "probo.postgresql.port" .) | quote }}
|
||||||
- name: PG_USERNAME
|
- name: PG_USERNAME
|
||||||
value: {{ include "probo.postgresql.username" . | quote }}
|
value: {{ include "probo.postgresql.username" . | quote }}
|
||||||
- name: PG_PASSWORD
|
- name: PG_PASSWORD
|
||||||
@@ -128,6 +130,11 @@ spec:
|
|||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: {{ include "probo.fullname" . }}
|
name: {{ include "probo.fullname" . }}
|
||||||
key: password-pepper
|
key: password-pepper
|
||||||
|
- name: OAUTH2_SERVER_SIGNING_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "probo.fullname" . }}
|
||||||
|
key: oauth2-signing-key
|
||||||
- name: AUTH_PASSWORD_ITERATIONS
|
- name: AUTH_PASSWORD_ITERATIONS
|
||||||
value: {{ .Values.probo.auth.passwordIterations | quote }}
|
value: {{ .Values.probo.auth.passwordIterations | quote }}
|
||||||
{{- if .Values.probo.saml.enabled }}
|
{{- if .Values.probo.saml.enabled }}
|
||||||
@@ -271,6 +278,13 @@ spec:
|
|||||||
value: {{ .Values.probo.customDomains.acme.email | quote }}
|
value: {{ .Values.probo.customDomains.acme.email | quote }}
|
||||||
- name: ACME_KEY_TYPE
|
- name: ACME_KEY_TYPE
|
||||||
value: {{ .Values.probo.customDomains.acme.keyType | quote }}
|
value: {{ .Values.probo.customDomains.acme.keyType | quote }}
|
||||||
|
{{- if .Values.probo.customDomains.acme.accountKey }}
|
||||||
|
- name: ACME_ACCOUNT_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ include "probo.fullname" . }}
|
||||||
|
key: acme-account-key
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
# Connectors (Slack OAuth2)
|
# Connectors (Slack OAuth2)
|
||||||
{{- range .Values.probo.connectors }}
|
{{- range .Values.probo.connectors }}
|
||||||
|
|||||||
@@ -17,10 +17,14 @@ stringData:
|
|||||||
s3-secret-key: {{ include "probo.s3.secretAccessKey" . | quote }}
|
s3-secret-key: {{ include "probo.s3.secretAccessKey" . | quote }}
|
||||||
|
|
||||||
# Application secrets
|
# Application secrets
|
||||||
encryption-key: {{ .Values.probo.encryptionKey | required "probo.encryptionKey is required" | quote }}
|
encryption-key: {{ include "probo.requireBase64Key32" (dict "name" "probo.encryptionKey" "value" .Values.probo.encryptionKey) | quote }}
|
||||||
cookie-secret: {{ .Values.probo.auth.cookieSecret | required "probo.auth.cookieSecret is required" | quote }}
|
cookie-secret: {{ include "probo.requireBase64Key32" (dict "name" "probo.auth.cookieSecret" "value" .Values.probo.auth.cookieSecret) | quote }}
|
||||||
password-pepper: {{ .Values.probo.auth.passwordPepper | required "probo.auth.passwordPepper is required" | quote }}
|
password-pepper: {{ include "probo.requireBase64Key32" (dict "name" "probo.auth.passwordPepper" "value" .Values.probo.auth.passwordPepper) | quote }}
|
||||||
trust-token-secret: {{ .Values.probo.trustAuth.tokenSecret | required "probo.trustAuth.tokenSecret is required" | quote }}
|
oauth2-signing-key: {{ include "probo.requirePEMPrivateKey" (dict "name" "probo.oauth2.signingKey" "value" .Values.probo.oauth2.signingKey) | quote }}
|
||||||
|
trust-token-secret: {{ include "probo.requireBase64Key32" (dict "name" "probo.trustAuth.tokenSecret" "value" .Values.probo.trustAuth.tokenSecret) | quote }}
|
||||||
|
{{- if .Values.probo.customDomains.acme.accountKey }}
|
||||||
|
acme-account-key: {{ include "probo.requirePEMPrivateKey" (dict "name" "probo.customDomains.acme.accountKey" "value" .Values.probo.customDomains.acme.accountKey) | quote }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
# Optional SMTP credentials
|
# Optional SMTP credentials
|
||||||
{{- if .Values.probo.mailer.smtp.user }}
|
{{- if .Values.probo.mailer.smtp.user }}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ metadata:
|
|||||||
name: {{ include "probo.fullname" . }}
|
name: {{ include "probo.fullname" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "probo.labels" . | nindent 4 }}
|
{{- include "probo.labels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: server
|
||||||
{{- with .Values.service.annotations }}
|
{{- with .Values.service.annotations }}
|
||||||
annotations:
|
annotations:
|
||||||
{{- toYaml . | nindent 4 }}
|
{{- toYaml . | nindent 4 }}
|
||||||
@@ -42,3 +43,4 @@ spec:
|
|||||||
name: metrics
|
name: metrics
|
||||||
selector:
|
selector:
|
||||||
{{- include "probo.selectorLabels" . | nindent 4 }}
|
{{- include "probo.selectorLabels" . | nindent 4 }}
|
||||||
|
app.kubernetes.io/component: server
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ spec:
|
|||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
{{- include "probo.selectorLabels" . | nindent 6 }}
|
{{- include "probo.selectorLabels" . | nindent 6 }}
|
||||||
|
app.kubernetes.io/component: server
|
||||||
endpoints:
|
endpoints:
|
||||||
- port: metrics
|
- port: metrics
|
||||||
path: /metrics
|
path: /metrics
|
||||||
|
|||||||
@@ -126,6 +126,12 @@ probo:
|
|||||||
# REQUIRED: Generate with: openssl rand -base64 32
|
# REQUIRED: Generate with: openssl rand -base64 32
|
||||||
passwordPepper: "CHANGE_ME_PASSWORD_PEPPER"
|
passwordPepper: "CHANGE_ME_PASSWORD_PEPPER"
|
||||||
|
|
||||||
|
oauth2:
|
||||||
|
# REQUIRED: PEM-encoded private key (RSA recommended)
|
||||||
|
# Example: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 > oauth2_signing_key.pem
|
||||||
|
# Then set with --set-file probo.oauth2.signingKey=oauth2_signing_key.pem
|
||||||
|
signingKey: "CHANGE_ME_OAUTH2_SIGNING_KEY_PEM"
|
||||||
|
|
||||||
# Trust center authentication
|
# Trust center authentication
|
||||||
trustAuth:
|
trustAuth:
|
||||||
cookieName: "TCT"
|
cookieName: "TCT"
|
||||||
@@ -190,6 +196,8 @@ probo:
|
|||||||
email: "admin@example.com"
|
email: "admin@example.com"
|
||||||
keyType: "EC256"
|
keyType: "EC256"
|
||||||
insecureTls: false
|
insecureTls: false
|
||||||
|
# Optional persisted account key to avoid creating a new ACME account on restarts
|
||||||
|
accountKey: ""
|
||||||
|
|
||||||
# External OAuth2 connectors (optional)
|
# External OAuth2 connectors (optional)
|
||||||
connectors:
|
connectors:
|
||||||
@@ -227,7 +235,7 @@ postgresql:
|
|||||||
maxConnIdleTimeSeconds: 1800
|
maxConnIdleTimeSeconds: 1800
|
||||||
maxConnLifetimeSeconds: 3600
|
maxConnLifetimeSeconds: 3600
|
||||||
# Uncomment if using TLS with custom CA
|
# Uncomment if using TLS with custom CA
|
||||||
# caCertBundle: |
|
# caBundle: |
|
||||||
# -----BEGIN CERTIFICATE-----
|
# -----BEGIN CERTIFICATE-----
|
||||||
# ...
|
# ...
|
||||||
# -----END CERTIFICATE-----
|
# -----END CERTIFICATE-----
|
||||||
@@ -261,13 +269,8 @@ s3:
|
|||||||
# accessKeyId: "..." # Spaces access key
|
# accessKeyId: "..." # Spaces access key
|
||||||
# secretAccessKey: "..." # Spaces secret
|
# secretAccessKey: "..." # Spaces secret
|
||||||
|
|
||||||
# Azure Blob Storage example (uncomment and adjust):
|
# Azure Blob through S3-compat proxies has known metadata compatibility gaps.
|
||||||
# region: "eastus"
|
# Prefer AWS S3 / GCS / Spaces for production until native Azure Blob support lands.
|
||||||
# bucket: "probo-container"
|
|
||||||
# endpoint: "https://mystorageaccount.blob.core.windows.net"
|
|
||||||
# accessKeyId: "mystorageaccount" # Storage account name
|
|
||||||
# secretAccessKey: "..." # Storage account access key
|
|
||||||
# usePathStyle: true # Required for Azure Blob Storage
|
|
||||||
|
|
||||||
# Chrome for PDF generation
|
# Chrome for PDF generation
|
||||||
chrome:
|
chrome:
|
||||||
|
|||||||
@@ -167,6 +167,8 @@ probo:
|
|||||||
# Public hostname where Probo will be accessible
|
# Public hostname where Probo will be accessible
|
||||||
# This should match your ingress host
|
# This should match your ingress host
|
||||||
baseUrl: probo.example.com
|
baseUrl: probo.example.com
|
||||||
|
# REQUIRED: Generate with openssl rand -base64 32
|
||||||
|
encryptionKey: ""
|
||||||
|
|
||||||
service:
|
service:
|
||||||
port: 8080
|
port: 8080
|
||||||
@@ -183,12 +185,12 @@ probo:
|
|||||||
batchTimeout: 5
|
batchTimeout: 5
|
||||||
exportTimeout: 30
|
exportTimeout: 30
|
||||||
maxQueueSize: 2048
|
maxQueueSize: 2048
|
||||||
# pg:
|
|
||||||
# addr: "probo-postgresql-demo-app:5432"
|
# OAuth2 signing key used by bootstrap to sign auth tokens
|
||||||
# username: "postgres"
|
# REQUIRED: PEM-encoded private key (RSA is recommended)
|
||||||
# password: "probod"
|
# Generate with: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048
|
||||||
# database: "probod"
|
oauth2:
|
||||||
# pool-size: 100
|
signingKey: ""
|
||||||
|
|
||||||
# CORS configuration
|
# CORS configuration
|
||||||
cors:
|
cors:
|
||||||
@@ -208,7 +210,11 @@ probo:
|
|||||||
invitationTokenValidity: 3600
|
invitationTokenValidity: 3600
|
||||||
cookieName: "SSID"
|
cookieName: "SSID"
|
||||||
cookieDomain: "probo.example.com"
|
cookieDomain: "probo.example.com"
|
||||||
|
# REQUIRED: Generate with openssl rand -base64 32
|
||||||
|
cookieSecret: ""
|
||||||
cookieDuration: 24
|
cookieDuration: 24
|
||||||
|
# REQUIRED: Generate with openssl rand -base64 32
|
||||||
|
passwordPepper: ""
|
||||||
passwordIterations: 1000000
|
passwordIterations: 1000000
|
||||||
|
|
||||||
# SAML authentication (optional)
|
# SAML authentication (optional)
|
||||||
@@ -232,6 +238,7 @@ probo:
|
|||||||
tlsHttpServer: 443
|
tlsHttpServer: 443
|
||||||
# Trust token signing secret (REQUIRED, at least 32 bytes)
|
# Trust token signing secret (REQUIRED, at least 32 bytes)
|
||||||
# Generate with: openssl rand -base64 32
|
# Generate with: openssl rand -base64 32
|
||||||
|
tokenSecret: ""
|
||||||
scope: "trust_center_readonly"
|
scope: "trust_center_readonly"
|
||||||
tokenType: "trust_center_access"
|
tokenType: "trust_center_access"
|
||||||
|
|
||||||
@@ -280,6 +287,9 @@ probo:
|
|||||||
email: "admin@example.com"
|
email: "admin@example.com"
|
||||||
keyType: "EC256"
|
keyType: "EC256"
|
||||||
insecureTls: false
|
insecureTls: false
|
||||||
|
# Optional persisted ACME account key (PEM-encoded)
|
||||||
|
# If unset, a new account may be created on each restart
|
||||||
|
accountKey: ""
|
||||||
|
|
||||||
# External OAuth2 connectors (optional)
|
# External OAuth2 connectors (optional)
|
||||||
connectors: []
|
connectors: []
|
||||||
@@ -349,7 +359,7 @@ s3:
|
|||||||
endpoint: ""
|
endpoint: ""
|
||||||
accessKeyId: "" # REQUIRED when seaweedfs.enabled=false: S3 access key
|
accessKeyId: "" # REQUIRED when seaweedfs.enabled=false: S3 access key
|
||||||
secretAccessKey: "" # REQUIRED when seaweedfs.enabled=false: S3 secret key
|
secretAccessKey: "" # REQUIRED when seaweedfs.enabled=false: S3 secret key
|
||||||
# Use path-style URLs (required for Azure Blob Storage and some S3-compatible services)
|
# Use path-style URLs for selected S3-compatible services
|
||||||
# When true: https://endpoint/bucket/key
|
# When true: https://endpoint/bucket/key
|
||||||
# When false (default): https://bucket.endpoint/key
|
# When false (default): https://bucket.endpoint/key
|
||||||
usePathStyle: false
|
usePathStyle: false
|
||||||
|
|||||||
Reference in New Issue
Block a user