From cef1b5e2d232ce41f02c1c651ce41538198678f6 Mon Sep 17 00:00:00 2001 From: xiangyisss Date: Thu, 11 Sep 2025 13:06:34 +0200 Subject: [PATCH 1/4] fix: enhance APP_KEY validation and update secret.yaml to use new appKey function --- charts/exivity/templates/_helpers.tpl | 50 +++++++++++++++++++++++++++ charts/exivity/templates/secret.yaml | 8 +---- charts/exivity/values.yaml | 2 +- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/charts/exivity/templates/_helpers.tpl b/charts/exivity/templates/_helpers.tpl index cbd3fc89..98974e56 100644 --- a/charts/exivity/templates/_helpers.tpl +++ b/charts/exivity/templates/_helpers.tpl @@ -11,3 +11,53 @@ and emit the whole block indented 8 spaces. {{- $merged := merge $globalSC $override -}} {{- toYaml $merged | nindent 8 -}} {{- end -}} + +{{/* +Validate and generate APP_KEY for Laravel applications. +This function ensures APP_KEY meets Laravel's encryption requirements to prevent runtime errors. + +Usage: {{ include "exivity.appKey" . }} + +Returns base64-encoded APP_KEY value that can be used directly in secret data. + +Validation rules: +- Plain keys: Must be exactly 32 characters (for AES-256-CBC) +- Base64 keys: Must have 'base64:' prefix and decode to 16 or 32 bytes (for AES-128/AES-256) +- Empty/missing: Generates secure random 32-character key +- During upgrades: Reuses existing secret if no new key provided + +Fails with descriptive error if APP_KEY doesn't meet Laravel requirements. +*/}} +{{- define "exivity.appKey" -}} + {{- $existingSecret := "" -}} + {{- if .Release.IsUpgrade -}} + {{- $existingSecret = lookup "v1" "Secret" .Release.Namespace (printf "%s-app-key" (include "exivity.fullname" .)) -}} + {{- end -}} + + {{- if and .Values.secret.appKey (ne .Values.secret.appKey "") -}} + {{/* Validate provided APP_KEY for Laravel compatibility */}} + {{- $appKey := .Values.secret.appKey -}} + {{- if hasPrefix "base64:" $appKey -}} + {{/* Validate base64 format APP_KEY */}} + {{- $base64Part := $appKey | trimPrefix "base64:" -}} + {{- $decoded := $base64Part | b64dec -}} + {{- $decodedLen := len $decoded -}} + {{- if and (ne $decodedLen 16) (ne $decodedLen 32) -}} + {{- fail (printf "Invalid APP_KEY: Laravel requires base64 decoded key to be 16 bytes (AES-128) or 32 bytes (AES-256), got %d bytes.\nThis prevents Laravel RuntimeException: 'Unsupported cipher or incorrect key length'.\nGenerate a valid key with: php artisan key:generate --show" $decodedLen) -}} + {{- end -}} + {{- else -}} + {{/* Validate plain text APP_KEY */}} + {{- if ne (len $appKey) 32 -}} + {{- fail (printf "Invalid APP_KEY: Laravel requires plain key to be exactly 32 characters for AES-256-CBC, got %d characters.\nThis prevents Laravel RuntimeException: 'Unsupported cipher or incorrect key length'.\nProvide a 32-character key or use base64: prefix format.\nGenerate a valid key with: php artisan key:generate --show" (len $appKey)) -}} + {{- end -}} + {{- end -}} + {{/* Return validated APP_KEY */}} + {{- .Values.secret.appKey | b64enc -}} + {{- else if and .Release.IsUpgrade $existingSecret $existingSecret.data -}} + {{/* Reuse existing secret during upgrade when no new key provided */}} + {{- index $existingSecret.data "EXIVITY_APP_KEY" -}} + {{- else -}} + {{/* Generate secure random 32-character APP_KEY */}} + {{- randAlphaNum 32 | b64enc -}} + {{- end -}} +{{- end -}} diff --git a/charts/exivity/templates/secret.yaml b/charts/exivity/templates/secret.yaml index ee879f8f..234829ca 100644 --- a/charts/exivity/templates/secret.yaml +++ b/charts/exivity/templates/secret.yaml @@ -5,13 +5,7 @@ metadata: labels: {{- include "exivity.labels" $ | indent 4 }} data: - {{- if .Release.IsUpgrade }} - EXIVITY_APP_KEY: {{ index (lookup "v1" "Secret" .Release.Namespace (printf "%s-app-key" (include "exivity.fullname" $))).data "EXIVITY_APP_KEY" }} - {{- else if not (empty .Values.secret.appKey) }} - EXIVITY_APP_KEY: {{ .Values.secret.appKey | b64enc }} - {{- else }} - EXIVITY_APP_KEY: {{ randAlphaNum 32 | b64enc }} - {{- end }} + EXIVITY_APP_KEY: {{ include "exivity.appKey" . }} --- apiVersion: v1 diff --git a/charts/exivity/values.yaml b/charts/exivity/values.yaml index 6864c0a9..f5a86cb7 100644 --- a/charts/exivity/values.yaml +++ b/charts/exivity/values.yaml @@ -9,7 +9,7 @@ licence: "demo" # Secret keys used for application security. Random values are generated on installation if not set. # Random values are generated on installation if not set, but it's recommended to specify values for production. secret: - appKey: "" # Used to encrypt application data. Specify a value for production. Max length: 64 characters. + appKey: "" The key must be a 32-character random string encoded in base64. Using php artisan key:generate is safer and easier. jwtSecret: "" # Used for signing JWTs. Specify a value for production. ingress: From 0021857763d336f8ea4aa94a31244d6b32c677a7 Mon Sep 17 00:00:00 2001 From: xiangyisss Date: Thu, 11 Sep 2025 13:15:27 +0200 Subject: [PATCH 2/4] fix: correct formatting for appKey in values.yaml --- charts/exivity/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/exivity/values.yaml b/charts/exivity/values.yaml index 2b0c492a..52ccc406 100644 --- a/charts/exivity/values.yaml +++ b/charts/exivity/values.yaml @@ -9,7 +9,7 @@ licence: "demo" # Secret keys used for application security. Random values are generated on installation if not set. # Random values are generated on installation if not set, but it's recommended to specify values for production. secret: - appKey: "" The key must be a 32-character random string encoded in base64. Using php artisan key:generate is safer and easier. + appKey: "" # The key must be a 32-character random string encoded in base64. Using php artisan key:generate is safer and easier. jwtSecret: "" # Used for signing JWTs. Specify a value for production. ingress: From 2d110deaa243cc520c95f1eb771877863a25f0ff Mon Sep 17 00:00:00 2001 From: xiangyisss Date: Fri, 12 Sep 2025 11:52:22 +0200 Subject: [PATCH 3/4] fix: handling appKey validation logic in schema.json --- charts/exivity/templates/_helpers.tpl | 50 --------------------------- charts/exivity/templates/secret.yaml | 11 +++++- charts/exivity/values.schema.json | 9 +++-- charts/exivity/values.yaml | 2 +- 4 files changed, 17 insertions(+), 55 deletions(-) diff --git a/charts/exivity/templates/_helpers.tpl b/charts/exivity/templates/_helpers.tpl index 98974e56..cbd3fc89 100644 --- a/charts/exivity/templates/_helpers.tpl +++ b/charts/exivity/templates/_helpers.tpl @@ -11,53 +11,3 @@ and emit the whole block indented 8 spaces. {{- $merged := merge $globalSC $override -}} {{- toYaml $merged | nindent 8 -}} {{- end -}} - -{{/* -Validate and generate APP_KEY for Laravel applications. -This function ensures APP_KEY meets Laravel's encryption requirements to prevent runtime errors. - -Usage: {{ include "exivity.appKey" . }} - -Returns base64-encoded APP_KEY value that can be used directly in secret data. - -Validation rules: -- Plain keys: Must be exactly 32 characters (for AES-256-CBC) -- Base64 keys: Must have 'base64:' prefix and decode to 16 or 32 bytes (for AES-128/AES-256) -- Empty/missing: Generates secure random 32-character key -- During upgrades: Reuses existing secret if no new key provided - -Fails with descriptive error if APP_KEY doesn't meet Laravel requirements. -*/}} -{{- define "exivity.appKey" -}} - {{- $existingSecret := "" -}} - {{- if .Release.IsUpgrade -}} - {{- $existingSecret = lookup "v1" "Secret" .Release.Namespace (printf "%s-app-key" (include "exivity.fullname" .)) -}} - {{- end -}} - - {{- if and .Values.secret.appKey (ne .Values.secret.appKey "") -}} - {{/* Validate provided APP_KEY for Laravel compatibility */}} - {{- $appKey := .Values.secret.appKey -}} - {{- if hasPrefix "base64:" $appKey -}} - {{/* Validate base64 format APP_KEY */}} - {{- $base64Part := $appKey | trimPrefix "base64:" -}} - {{- $decoded := $base64Part | b64dec -}} - {{- $decodedLen := len $decoded -}} - {{- if and (ne $decodedLen 16) (ne $decodedLen 32) -}} - {{- fail (printf "Invalid APP_KEY: Laravel requires base64 decoded key to be 16 bytes (AES-128) or 32 bytes (AES-256), got %d bytes.\nThis prevents Laravel RuntimeException: 'Unsupported cipher or incorrect key length'.\nGenerate a valid key with: php artisan key:generate --show" $decodedLen) -}} - {{- end -}} - {{- else -}} - {{/* Validate plain text APP_KEY */}} - {{- if ne (len $appKey) 32 -}} - {{- fail (printf "Invalid APP_KEY: Laravel requires plain key to be exactly 32 characters for AES-256-CBC, got %d characters.\nThis prevents Laravel RuntimeException: 'Unsupported cipher or incorrect key length'.\nProvide a 32-character key or use base64: prefix format.\nGenerate a valid key with: php artisan key:generate --show" (len $appKey)) -}} - {{- end -}} - {{- end -}} - {{/* Return validated APP_KEY */}} - {{- .Values.secret.appKey | b64enc -}} - {{- else if and .Release.IsUpgrade $existingSecret $existingSecret.data -}} - {{/* Reuse existing secret during upgrade when no new key provided */}} - {{- index $existingSecret.data "EXIVITY_APP_KEY" -}} - {{- else -}} - {{/* Generate secure random 32-character APP_KEY */}} - {{- randAlphaNum 32 | b64enc -}} - {{- end -}} -{{- end -}} diff --git a/charts/exivity/templates/secret.yaml b/charts/exivity/templates/secret.yaml index 234829ca..b97db3bb 100644 --- a/charts/exivity/templates/secret.yaml +++ b/charts/exivity/templates/secret.yaml @@ -5,7 +5,16 @@ metadata: labels: {{- include "exivity.labels" $ | indent 4 }} data: - EXIVITY_APP_KEY: {{ include "exivity.appKey" . }} + {{- if and .Values.secret.appKey (ne .Values.secret.appKey "") }} + {{/* Use provided APP_KEY (validation handled by values.schema.json) */}} + EXIVITY_APP_KEY: {{ .Values.secret.appKey | b64enc }} + {{- else if .Release.IsUpgrade }} + {{/* Reuse existing secret during upgrade when no new key provided */}} + EXIVITY_APP_KEY: {{ index (lookup "v1" "Secret" .Release.Namespace (printf "%s-app-key" (include "exivity.fullname" $))).data "EXIVITY_APP_KEY" }} + {{- else }} + {{/* Generate secure random 32-character APP_KEY for new installations */}} + EXIVITY_APP_KEY: {{ randAlphaNum 32 | b64enc }} + {{- end }} --- apiVersion: v1 diff --git a/charts/exivity/values.schema.json b/charts/exivity/values.schema.json index a91625a9..35c5912a 100644 --- a/charts/exivity/values.schema.json +++ b/charts/exivity/values.schema.json @@ -39,11 +39,14 @@ "appKey": { "type": "string", "default": "", - "title": "The appKey Schema", + "title": "Laravel Application Key", + "description": "ERROR PREVENTION: APP_KEY must be either: (1) Empty string for auto-generation, (2) Plain 32 alphanumeric characters, OR (3) Base64-encoded key with 'base64:' prefix. Invalid APP_KEY causes Laravel RuntimeException: 'Unsupported cipher or incorrect key length'. Generate with: php artisan key:generate --show", "examples": [ - "ieR3rai9aijeghingo9LeaCaipah4lohxiliekaem3chahph0iemeeghai3ohfah" + "", + "abcdefghijklmnopqrstuvwxyz123456", + "base64:MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=" ], - "maxLength": 64 + "pattern": "^(|[a-zA-Z0-9]{32}|base64:[A-Za-z0-9+/]{16,88}={0,2})$" }, "jwtSecret": { "type": "string", diff --git a/charts/exivity/values.yaml b/charts/exivity/values.yaml index 52ccc406..7665b8e0 100644 --- a/charts/exivity/values.yaml +++ b/charts/exivity/values.yaml @@ -9,7 +9,7 @@ licence: "demo" # Secret keys used for application security. Random values are generated on installation if not set. # Random values are generated on installation if not set, but it's recommended to specify values for production. secret: - appKey: "" # The key must be a 32-character random string encoded in base64. Using php artisan key:generate is safer and easier. + appKey: "" # Laravel encryption key. Must be 32 characters (plain) or base64-encoded with 'base64:' prefix. Validated by values.schema.json. Generate with: php artisan key:generate --show jwtSecret: "" # Used for signing JWTs. Specify a value for production. ingress: From 51e20144b2c274d9fa8dbf0fa6c07ce84f35cb87 Mon Sep 17 00:00:00 2001 From: Steffen Exler Date: Wed, 3 Dec 2025 17:17:00 +0100 Subject: [PATCH 4/4] feat: enhance description for Laravel application key in values.schema.json Signed-off-by: Steffen Exler --- charts/exivity/values.schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/exivity/values.schema.json b/charts/exivity/values.schema.json index 8e7ba37c..be145db3 100644 --- a/charts/exivity/values.schema.json +++ b/charts/exivity/values.schema.json @@ -41,10 +41,10 @@ "type": "string", "default": "", "title": "Laravel Application Key", - "description": "ERROR PREVENTION: APP_KEY must be either: (1) Empty string for auto-generation, (2) Plain 32 alphanumeric characters, OR (3) Base64-encoded key with 'base64:' prefix. Invalid APP_KEY causes Laravel RuntimeException: 'Unsupported cipher or incorrect key length'. Generate with: php artisan key:generate --show", + "description": "The application encryption key used by Laravel for encrypting and decrypting sensitive data with AES-256-CBC cipher. This value can be left empty for automatic generation during installation or specified as a base64-encoded key with the 'base64:' prefix (standard Laravel format). If an invalid or incorrectly formatted key is provided, a Laravel RuntimeException will be thrown. A valid key can be generated using: php artisan key:generate --show", "examples": [ "", - "abcdefghijklmnopqrstuvwxyz123456", + "ZC9GxTNHyDyYOZYidN240FuhsB0QJxZs", "base64:MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=" ], "pattern": "^(|[a-zA-Z0-9]{32}|base64:[A-Za-z0-9+/]{16,88}={0,2})$"