From 25afc12ddfed4036fa53cc1be36fab5ad29f717e Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 2 Nov 2026 12:09:39 +0530 Subject: [PATCH 1/4] [INFRA-1332] feat(plane-enterprise): env.sync_config_from_env, and correct the skip_env_var docs (3.11.4) The chart documented env.skip_env_var: '0' as making the API read instance settings (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) from the environment. The commercial API entrypoint forces SKIP_ENV_VAR=1, so the API never sees it; only worker, beat and the consumers do, and the two disagree. Add env.sync_config_from_env (default false). It renders PLANE_SYNC_CONFIG_FROM_ENV=1, which makes the API copy every setting the environment sets into the database on start (plane-ee #10852). It is rendered only when on, so existing releases render byte-identical apart from the version label. Correct values.yaml, the README section and parameter table, the rotation runbook and the install notes. Add a notes warning when skip_env_var is not '1', and a Rancher question for the new value. --- charts/plane-enterprise/Chart.yaml | 2 +- charts/plane-enterprise/README.md | 18 ++++++++++++----- .../external-secrets/rotation-runbook.md | 2 +- charts/plane-enterprise/questions.yml | 6 ++++++ charts/plane-enterprise/templates/NOTES.txt | 7 +++++-- .../templates/config-secrets/app-env.yaml | 9 ++++++--- charts/plane-enterprise/values.yaml | 20 +++++++++++++------ 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/charts/plane-enterprise/Chart.yaml b/charts/plane-enterprise/Chart.yaml index bc95403d..ffdec431 100644 --- a/charts/plane-enterprise/Chart.yaml +++ b/charts/plane-enterprise/Chart.yaml @@ -5,7 +5,7 @@ description: Meet Plane. An Enterprise software development tool to manage issue type: application -version: 3.11.3 +version: 3.11.4 appVersion: "4.0.1" home: https://plane.so/ diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md index af62f11f..00df623b 100644 --- a/charts/plane-enterprise/README.md +++ b/charts/plane-enterprise/README.md @@ -1738,16 +1738,23 @@ needed for the upgrade that crosses into 3.6.0. ### 6. Secrets that live in the database, not the environment -By default (`SKIP_ENV_VAR=1`) the API reads about twenty settings — SMTP password, Google/GitHub/GitLab/OIDC client secrets, `LLM_API_KEY`, `LDAP_BIND_PASSWORD`, SAML certificate — from the instance-configuration table, seeded from the environment only on first startup. **Rotating those through a Secret has no effect** while that is the case. +The API reads about twenty instance settings — SMTP password, Google/GitHub/GitLab/OIDC client secrets, `LLM_API_KEY`, `LDAP_BIND_PASSWORD`, SAML certificate, and the login toggles such as `IS_OIDC_ENABLED` — from the instance-configuration table, seeded from the environment only on first startup. **Changing or rotating those through the environment has no effect** after that. -Set `env.skip_env_var: '0'` to make the API re-read them from the environment on every start, which makes the external secret the source of truth: +Set `env.sync_config_from_env: true` to copy every one of those settings the environment sets (through `extraEnv` or `external_secrets.app_env_existingSecret`) into the database on each API start, which makes the external secret or your GitOps values the source of truth: ```yaml env: - skip_env_var: '0' + sync_config_from_env: true +extraEnv: + - name: IS_OIDC_ENABLED + value: "1" ``` -The trade-off: edits made to those settings in the god-mode admin UI are overwritten on the next restart. +- Settings the environment leaves unset or empty keep their stored value, so anything configured in the god-mode admin UI keeps working. +- The trade-off: a god-mode edit to a setting the environment sets lasts only until the next restart. +- The API logs the names (never the values) of the settings it changed: `PLANE_SYNC_CONFIG_FROM_ENV: applied from the environment: IS_OIDC_ENABLED`. Plane versions that predate the flag ignore it, so no such line appears. + +Do not use `env.skip_env_var: '0'` for this. The API ignores it and keeps reading the database, while worker, beat and the consumers switch to the environment, so the two can disagree. Leave it at `'1'`. ### AI providers, including Amazon Bedrock @@ -1805,7 +1812,8 @@ chart: an empty credential is *present*, and a present credential denies the cha | `external_secrets.app_keys_existingSecret` | | One Secret for the shared signing/encryption keys. | | `external_secrets.ssl_token_existingSecret` | | DNS-01 API token for the cert-manager Issuer; must contain the key `api-token`. | | `env.requireExplicitSecrets` | false | Fail the render instead of falling back to the chart's public example keys. Will default to `true` in the next major version. | -| `env.skip_env_var` | '1' | `'0'` makes the API re-read the database-resident secrets (SMTP, OAuth, LLM, LDAP) from the environment on every start. | +| `env.skip_env_var` | '1' | Leave at `'1'`. The API ignores `'0'`; only worker, beat and the consumers switch to the environment. Use `env.sync_config_from_env` instead. | +| `env.sync_config_from_env` | false | On each API start, copy every instance setting the environment sets (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) into the database, so the environment wins. | | `global.forceRedeploy` | false | Restart every workload on every `helm upgrade`, as versions before 3.1.0 did. Off means upgrades roll only what changed. | ### Provider examples diff --git a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md index 06de7b92..5f434136 100644 --- a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md +++ b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md @@ -78,7 +78,7 @@ Both fail **silently**: decryption errors are swallowed and the values come back **The bundled `local_setup` infrastructure is out of scope.** The chart's own postgres/rabbitmq/minio/opensearch StatefulSets are intended for local and evaluation use; rotating their credentials means changing the password inside the container as well, which the chart does not orchestrate. Everything here assumes managed backends. -**Database-resident secrets do not rotate through the environment.** With the default `SKIP_ENV_VAR=1`, the SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, seeded from the environment only on first boot. Set `env.skip_env_var: '0'` to make the environment the source of truth on every restart — at the cost of god-mode admin UI edits to those settings being overwritten. +**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, seeded from the environment only on first boot. Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. `env.skip_env_var: '0'` does not do this: the API ignores it. **Silo, live and Plane AI rotate like the API from planeVersion v3.2.0** — they read discrete parts, so nothing recomposes a DSN and a Reloader restart is all that is needed. diff --git a/charts/plane-enterprise/questions.yml b/charts/plane-enterprise/questions.yml index b0a2ca3f..1f32a298 100644 --- a/charts/plane-enterprise/questions.yml +++ b/charts/plane-enterprise/questions.yml @@ -2158,6 +2158,12 @@ questions: type: boolean default: false group: "Service Account" +- variable: env.sync_config_from_env + label: "Apply Instance Settings from the Environment" + description: "On each API start, copies every instance setting the environment sets (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) into the database, so the environment wins. A god-mode edit to such a setting lasts only until the next restart." + type: boolean + default: false + group: "Service Account" - variable: external_secrets.otel_env_existingSecret label: "OpenTelemetry Envs Secrets File Name" description: "Supplies OTEL_EXPORTER_OTLP_HEADERS. Leave blank to let the chart create the Secret from the OTLP Exporter Headers value." diff --git a/charts/plane-enterprise/templates/NOTES.txt b/charts/plane-enterprise/templates/NOTES.txt index 9b14492e..47bf7f24 100644 --- a/charts/plane-enterprise/templates/NOTES.txt +++ b/charts/plane-enterprise/templates/NOTES.txt @@ -123,8 +123,11 @@ Warn rather than reorder: reordering would change which value existing installs {{- end }} {{- /* Secrets that env rotation cannot reach. */}} -{{- if and (eq (.Values.env.skip_env_var | default "1" | toString) "1") (or .Values.external_secrets.app_keys_existingSecret $externalInfra) }} -{{- $warnings = append $warnings "env.skip_env_var is '1', so the SMTP password, OAuth client secrets, LLM_API_KEY\n and LDAP_BIND_PASSWORD are read from the instance-configuration table in the\n database, seeded from the environment only on first startup. Rotating those through\n a Secret will have no effect. Set env.skip_env_var='0' to make the environment the\n source of truth on every restart." }} +{{- if and (not .Values.env.sync_config_from_env) (or .Values.external_secrets.app_keys_existingSecret $externalInfra) }} +{{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n read from the instance-configuration table in the database, seeded from the\n environment only on first startup. Rotating those through a Secret will have no\n effect. Set env.sync_config_from_env=true to apply the environment on every restart." }} +{{- end }} +{{- if ne (.Values.env.skip_env_var | default "1" | toString) "1" }} +{{- $warnings = append $warnings "env.skip_env_var is not '1'. The API ignores it and keeps reading instance settings\n from the database, while worker, beat and the consumers read the environment, so the\n two can disagree. Set it back to '1' and use env.sync_config_from_env=true to make\n the environment the source of truth." }} {{- end }} {{- /* Static object-storage keys where a cloud identity would do. */}} diff --git a/charts/plane-enterprise/templates/config-secrets/app-env.yaml b/charts/plane-enterprise/templates/config-secrets/app-env.yaml index 14f225de..63ee4860 100644 --- a/charts/plane-enterprise/templates/config-secrets/app-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/app-env.yaml @@ -123,10 +123,13 @@ data: PAYMENT_SERVER_BASE_URL: {{ .Values.license.licenseServer | quote }} DEFAULT_API_RATE_LIMIT: {{ .Values.env.api_key_rate_limit | default "120/minute" | quote }} - {{- /* '0' makes the API re-read SMTP/OAuth/LLM/LDAP secrets from the environment on - every start instead of from the instance-configuration table, which is what - lets an external secret store rotate them. See values.yaml env.skip_env_var. */}} + {{- /* The API always reads instance settings from the database; '0' only affects + worker, beat and the consumers. See values.yaml env.skip_env_var. */}} SKIP_ENV_VAR: {{ .Values.env.skip_env_var | default "1" | quote }} + {{- /* Rendered only when on, so existing releases render byte-identical. */}} + {{- if .Values.env.sync_config_from_env }} + PLANE_SYNC_CONFIG_FROM_ENV: "1" + {{- end }} MINIO_ENDPOINT_SSL: {{ .Values.services.minio.env.minio_endpoint_ssl | default false | ternary "1" "0" | quote }} USE_STORAGE_PROXY: {{ .Values.env.use_storage_proxy | default false | ternary "1" "0" | quote }} ALLOW_ALL_ATTACHMENT_TYPES: {{ .Values.env.allow_all_attachment_types | default false | ternary "1" "0" | quote }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index a65723b9..9f9b6408 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -1185,14 +1185,22 @@ env: # the next major version. requireExplicitSecrets: false - # SKIP_ENV_VAR=1 (the default) makes the API read SMTP, OAuth-provider, LLM and - # LDAP secrets from the instance-configuration table in the database, seeded from - # the environment only on first startup — so rotating those through a Secret has - # no effect. Set '0' when an external secret store is the source of truth: the - # API then re-seeds them from the environment on every start. Trade-off: edits - # made in the god-mode admin UI for those settings get overwritten on restart. + # Instance settings (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) live in + # the instance-configuration table in the database, seeded from the environment + # only on first startup. Leave this at '1'. The API always reads the database + # whatever this says; '0' only moves worker, beat and the consumers to the + # environment, so the two can disagree. To make the environment win, use + # sync_config_from_env below. skip_env_var: '1' + # Copy every instance setting the environment sets (extraEnv or + # external_secrets.app_env_existingSecret) into the database on each API start, + # so an external secret store or GitOps values are the source of truth and + # rotation takes effect on restart. Keys left unset or empty keep their stored + # value. Trade-off: a god-mode admin UI edit to a key the environment sets lasts + # only until the next restart. Plane versions that predate it ignore the flag. + sync_config_from_env: false + # Kubernetes internal cluster domain used to build in-cluster service URLs default_cluster_domain: 'cluster.local' From 2f93b41228004fb9bfe4211aa44b45d63089df02 Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 2 Nov 2026 12:26:56 +0530 Subject: [PATCH 2/4] [INFRA-1332] docs(plane-enterprise): list the 73 settings sync_config_from_env applies Add a table of every instance setting the API reads from the database, by area, marking the 10 stored encrypted, with the formats that are not plain toggles (seconds, days, comma-separated, JSON). Checked against the registry in plane-ee (core + extended). Correct "seeded from the environment on first startup": the OIDC, SAML and LDAP settings never are, so on a fresh install they could only be set in god-mode. --- charts/plane-enterprise/README.md | 25 ++++++++++++++++++- .../external-secrets/rotation-runbook.md | 2 +- charts/plane-enterprise/templates/NOTES.txt | 2 +- charts/plane-enterprise/values.yaml | 5 ++-- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md index 00df623b..31dd6e2e 100644 --- a/charts/plane-enterprise/README.md +++ b/charts/plane-enterprise/README.md @@ -1738,7 +1738,7 @@ needed for the upgrade that crosses into 3.6.0. ### 6. Secrets that live in the database, not the environment -The API reads about twenty instance settings — SMTP password, Google/GitHub/GitLab/OIDC client secrets, `LLM_API_KEY`, `LDAP_BIND_PASSWORD`, SAML certificate, and the login toggles such as `IS_OIDC_ENABLED` — from the instance-configuration table, seeded from the environment only on first startup. **Changing or rotating those through the environment has no effect** after that. +The API reads the 73 instance settings listed below — sign-in methods, SSO providers, SMTP, the AI key and a few limits — from the instance-configuration table, which the god-mode admin UI edits. Most are copied from the environment once, on first startup; the OIDC, SAML and LDAP settings are never read from it. **Setting or rotating any of them through the environment has no effect** after first startup. Set `env.sync_config_from_env: true` to copy every one of those settings the environment sets (through `extraEnv` or `external_secrets.app_env_existingSecret`) into the database on each API start, which makes the external secret or your GitOps values the source of truth: @@ -1756,6 +1756,29 @@ extraEnv: Do not use `env.skip_env_var: '0'` for this. The API ignores it and keeps reading the database, while worker, beat and the consumers switch to the environment, so the two can disagree. Leave it at `'1'`. +**Settings that `sync_config_from_env` applies.** Set each as an environment variable of the same name. Toggles take `"1"` or `"0"`. 🔒 marks a secret, which the database stores encrypted; supply those from a Secret (`external_secrets.app_env_existingSecret`) rather than `extraEnv`. + +| Area | Environment variables | Notes | +| --- | --- | --- | +| Sign-in | `ENABLE_SIGNUP`, `ENABLE_EMAIL_PASSWORD`, `ENABLE_MAGIC_LINK_LOGIN` | Magic links also need SMTP. | +| Workspaces | `DISABLE_WORKSPACE_CREATION` | | +| Security | `DISABLE_ACCESS_TOKENS`, `HIDE_EMAIL_CHANGE_DETAILS`, `SESSION_COOKIE_AGE`, `ADMIN_SESSION_COOKIE_AGE`, `WORK_ITEM_EXPORT_EXPIRY_SECONDS` | Ages and expiry are in seconds. | +| OIDC | `IS_OIDC_ENABLED`, `OIDC_PROVIDER_NAME`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` 🔒, `OIDC_AUTHORIZE_URL`, `OIDC_TOKEN_URL`, `OIDC_USERINFO_URL`, `OIDC_LOGOUT_URL`, `ENABLE_OIDC_IDP_SYNC` | | +| SAML | `IS_SAML_ENABLED`, `SAML_PROVIDER_NAME`, `SAML_ENTITY_ID`, `SAML_SSO_URL`, `SAML_LOGOUT_URL`, `SAML_CERTIFICATE` 🔒, `SAML_NAME_ID_FORMAT`, `SAML_ATTRIBUTE_MAPPING`, `SAML_DISABLE_REQUESTED_AUTHN_CONTEXT`, `ENABLE_SAML_IDP_SYNC` | `SAML_ATTRIBUTE_MAPPING` is a JSON object, such as `{"display_name": "preferred_username"}`; keys it leaves out keep their defaults. | +| LDAP | `IS_LDAP_ENABLED`, `LDAP_PROVIDER_NAME`, `LDAP_SERVER_URI`, `LDAP_BIND_DN`, `LDAP_BIND_PASSWORD` 🔒, `LDAP_USER_SEARCH_BASE`, `LDAP_USER_SEARCH_FILTER`, `LDAP_USER_ATTRIBUTES` | `LDAP_USER_ATTRIBUTES` is comma-separated. | +| Google | `IS_GOOGLE_ENABLED`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` 🔒, `ENABLE_GOOGLE_SYNC` | | +| GitHub | `IS_GITHUB_ENABLED`, `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` 🔒, `GITHUB_ORGANIZATION_ID`, `ENABLE_GITHUB_SYNC` | `GITHUB_ORGANIZATION_ID` limits sign-in to that organization's members. | +| GitLab | `IS_GITLAB_ENABLED`, `GITLAB_HOST`, `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` 🔒, `ENABLE_GITLAB_SYNC` | | +| Gitea | `IS_GITEA_ENABLED`, `GITEA_HOST`, `GITEA_CLIENT_ID`, `GITEA_CLIENT_SECRET` 🔒, `ENABLE_GITEA_SYNC` | | +| Email (SMTP) | `ENABLE_SMTP`, `EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_HOST_USER`, `EMAIL_HOST_PASSWORD` 🔒, `EMAIL_FROM`, `EMAIL_USE_TLS`, `EMAIL_USE_SSL` | | +| AI | `LLM_PROVIDER`, `LLM_MODEL`, `LLM_API_KEY` 🔒, `GPT_ENGINE` | `GPT_ENGINE` is deprecated; use `LLM_MODEL`. | +| Images | `UNSPLASH_ACCESS_KEY` 🔒 | | +| Chat support | `IS_CHAT_SUPPORT_ENABLED`, `CHAT_SUPPORT_APP_ID` | | +| Projects | `PROJECT_IDENTIFIER_MAX_LENGTH` | 1 to 255. | +| Log retention | `WEBHOOK_EVENTS_RETENTION_IN_DAYS`, `API_LOGS_RETENTION_IN_DAYS` | In days. | + +The `ENABLE_*_SYNC` and `ENABLE_*_IDP_SYNC` toggles refresh a user's profile from that provider at each sign-in. + ### AI providers, including Amazon Bedrock `external_secrets.ai_providers_existingSecret` replaces the whole provider-key group — diff --git a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md index 5f434136..70605a4a 100644 --- a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md +++ b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md @@ -78,7 +78,7 @@ Both fail **silently**: decryption errors are swallowed and the values come back **The bundled `local_setup` infrastructure is out of scope.** The chart's own postgres/rabbitmq/minio/opensearch StatefulSets are intended for local and evaluation use; rotating their credentials means changing the password inside the container as well, which the chart does not orchestrate. Everything here assumes managed backends. -**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, seeded from the environment only on first boot. Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. `env.skip_env_var: '0'` does not do this: the API ignores it. +**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, not the environment (some are copied from it once, on first boot; `LDAP_BIND_PASSWORD` never is). Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. `env.skip_env_var: '0'` does not do this: the API ignores it. **Silo, live and Plane AI rotate like the API from planeVersion v3.2.0** — they read discrete parts, so nothing recomposes a DSN and a Reloader restart is all that is needed. diff --git a/charts/plane-enterprise/templates/NOTES.txt b/charts/plane-enterprise/templates/NOTES.txt index 47bf7f24..60306fda 100644 --- a/charts/plane-enterprise/templates/NOTES.txt +++ b/charts/plane-enterprise/templates/NOTES.txt @@ -124,7 +124,7 @@ Warn rather than reorder: reordering would change which value existing installs {{- /* Secrets that env rotation cannot reach. */}} {{- if and (not .Values.env.sync_config_from_env) (or .Values.external_secrets.app_keys_existingSecret $externalInfra) }} -{{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n read from the instance-configuration table in the database, seeded from the\n environment only on first startup. Rotating those through a Secret will have no\n effect. Set env.sync_config_from_env=true to apply the environment on every restart." }} +{{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n read from the instance-configuration table in the database, not the environment\n (some are copied from it once, on first startup). Rotating those through a Secret\n will have no effect. Set env.sync_config_from_env=true to apply the environment on every restart." }} {{- end }} {{- if ne (.Values.env.skip_env_var | default "1" | toString) "1" }} {{- $warnings = append $warnings "env.skip_env_var is not '1'. The API ignores it and keeps reading instance settings\n from the database, while worker, beat and the consumers read the environment, so the\n two can disagree. Set it back to '1' and use env.sync_config_from_env=true to make\n the environment the source of truth." }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index 9f9b6408..00bd3de0 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -1186,8 +1186,8 @@ env: requireExplicitSecrets: false # Instance settings (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) live in - # the instance-configuration table in the database, seeded from the environment - # only on first startup. Leave this at '1'. The API always reads the database + # the instance-configuration table in the database; most are copied from the + # environment once, on first startup, and OIDC/SAML/LDAP never are. Leave this at '1'. The API always reads the database # whatever this says; '0' only moves worker, beat and the consumers to the # environment, so the two can disagree. To make the environment win, use # sync_config_from_env below. @@ -1199,6 +1199,7 @@ env: # rotation takes effect on restart. Keys left unset or empty keep their stored # value. Trade-off: a god-mode admin UI edit to a key the environment sets lasts # only until the next restart. Plane versions that predate it ignore the flag. + # The README lists all 73 settings it covers. sync_config_from_env: false # Kubernetes internal cluster domain used to build in-cluster service URLs From b864ff1208cae9f55a21f0bd869f8d4a19831981 Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 2 Nov 2026 12:39:09 +0530 Subject: [PATCH 3/4] [INFRA-1332] docs(plane-enterprise): deprecate env.skip_env_var in favour of sync_config_from_env Two switches with overlapping names left it unclear which one to use. The API never honoured skip_env_var, and with sync_config_from_env its only remaining effect is to point worker, beat and the consumers at the environment while the API reads the database. Drop it from values.yaml so sync_config_from_env is the one documented switch, and mark it deprecated in the README, parameter table, runbook and install notes, with a two-step migration (enable the sync, then remove skip_env_var). The template keeps rendering it with the same default, so every existing set of values renders byte-identical. --- charts/plane-enterprise/README.md | 7 +++-- .../external-secrets/rotation-runbook.md | 2 +- charts/plane-enterprise/templates/NOTES.txt | 2 +- .../templates/config-secrets/app-env.yaml | 4 +-- charts/plane-enterprise/values.yaml | 27 +++++++++---------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md index 31dd6e2e..0f29062e 100644 --- a/charts/plane-enterprise/README.md +++ b/charts/plane-enterprise/README.md @@ -1754,7 +1754,10 @@ extraEnv: - The trade-off: a god-mode edit to a setting the environment sets lasts only until the next restart. - The API logs the names (never the values) of the settings it changed: `PLANE_SYNC_CONFIG_FROM_ENV: applied from the environment: IS_OIDC_ENABLED`. Plane versions that predate the flag ignore it, so no such line appears. -Do not use `env.skip_env_var: '0'` for this. The API ignores it and keeps reading the database, while worker, beat and the consumers switch to the environment, so the two can disagree. Leave it at `'1'`. +**`env.skip_env_var` is deprecated: leave it unset.** It was the old switch for this, but the API never honoured it. `'0'` only moves worker, beat and the consumers to the environment, so they can disagree with the API. If you set it to `'0'` today, either through `env.skip_env_var` or a `SKIP_ENV_VAR` entry in `extraEnv`, move off it in two upgrades so the workers never read a stale value in between: + +1. Turn on `env.sync_config_from_env` and upgrade. The API copies your environment values into the database. +2. Remove the `skip_env_var` setting and upgrade again. The workers now read the same values from the database. **Settings that `sync_config_from_env` applies.** Set each as an environment variable of the same name. Toggles take `"1"` or `"0"`. 🔒 marks a secret, which the database stores encrypted; supply those from a Secret (`external_secrets.app_env_existingSecret`) rather than `extraEnv`. @@ -1835,8 +1838,8 @@ chart: an empty credential is *present*, and a present credential denies the cha | `external_secrets.app_keys_existingSecret` | | One Secret for the shared signing/encryption keys. | | `external_secrets.ssl_token_existingSecret` | | DNS-01 API token for the cert-manager Issuer; must contain the key `api-token`. | | `env.requireExplicitSecrets` | false | Fail the render instead of falling back to the chart's public example keys. Will default to `true` in the next major version. | -| `env.skip_env_var` | '1' | Leave at `'1'`. The API ignores `'0'`; only worker, beat and the consumers switch to the environment. Use `env.sync_config_from_env` instead. | | `env.sync_config_from_env` | false | On each API start, copy every instance setting the environment sets (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) into the database, so the environment wins. | +| `env.skip_env_var` | (unset) | **Deprecated**; leave unset. Still rendered, defaulting to `'1'`, so existing values keep working. Use `env.sync_config_from_env`. | | `global.forceRedeploy` | false | Restart every workload on every `helm upgrade`, as versions before 3.1.0 did. Off means upgrades roll only what changed. | ### Provider examples diff --git a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md index 70605a4a..61db8abc 100644 --- a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md +++ b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md @@ -78,7 +78,7 @@ Both fail **silently**: decryption errors are swallowed and the values come back **The bundled `local_setup` infrastructure is out of scope.** The chart's own postgres/rabbitmq/minio/opensearch StatefulSets are intended for local and evaluation use; rotating their credentials means changing the password inside the container as well, which the chart does not orchestrate. Everything here assumes managed backends. -**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, not the environment (some are copied from it once, on first boot; `LDAP_BIND_PASSWORD` never is). Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. `env.skip_env_var: '0'` does not do this: the API ignores it. +**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, not the environment (some are copied from it once, on first boot; `LDAP_BIND_PASSWORD` never is). Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. The deprecated `env.skip_env_var` does not do this: the API ignores it. **Silo, live and Plane AI rotate like the API from planeVersion v3.2.0** — they read discrete parts, so nothing recomposes a DSN and a Reloader restart is all that is needed. diff --git a/charts/plane-enterprise/templates/NOTES.txt b/charts/plane-enterprise/templates/NOTES.txt index 60306fda..8b4e499b 100644 --- a/charts/plane-enterprise/templates/NOTES.txt +++ b/charts/plane-enterprise/templates/NOTES.txt @@ -127,7 +127,7 @@ Warn rather than reorder: reordering would change which value existing installs {{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n read from the instance-configuration table in the database, not the environment\n (some are copied from it once, on first startup). Rotating those through a Secret\n will have no effect. Set env.sync_config_from_env=true to apply the environment on every restart." }} {{- end }} {{- if ne (.Values.env.skip_env_var | default "1" | toString) "1" }} -{{- $warnings = append $warnings "env.skip_env_var is not '1'. The API ignores it and keeps reading instance settings\n from the database, while worker, beat and the consumers read the environment, so the\n two can disagree. Set it back to '1' and use env.sync_config_from_env=true to make\n the environment the source of truth." }} +{{- $warnings = append $warnings "env.skip_env_var is deprecated, and the API ignores this value: it keeps reading\n instance settings from the database while worker, beat and the consumers read the\n environment, so the two can disagree. Turn on env.sync_config_from_env first, then\n remove env.skip_env_var in a later upgrade (see the chart README)." }} {{- end }} {{- /* Static object-storage keys where a cloud identity would do. */}} diff --git a/charts/plane-enterprise/templates/config-secrets/app-env.yaml b/charts/plane-enterprise/templates/config-secrets/app-env.yaml index 63ee4860..ccd7ff46 100644 --- a/charts/plane-enterprise/templates/config-secrets/app-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/app-env.yaml @@ -123,8 +123,8 @@ data: PAYMENT_SERVER_BASE_URL: {{ .Values.license.licenseServer | quote }} DEFAULT_API_RATE_LIMIT: {{ .Values.env.api_key_rate_limit | default "120/minute" | quote }} - {{- /* The API always reads instance settings from the database; '0' only affects - worker, beat and the consumers. See values.yaml env.skip_env_var. */}} + {{- /* env.skip_env_var is deprecated and gone from values.yaml; the same default + keeps existing releases unchanged. The API ignores '0'. */}} SKIP_ENV_VAR: {{ .Values.env.skip_env_var | default "1" | quote }} {{- /* Rendered only when on, so existing releases render byte-identical. */}} {{- if .Values.env.sync_config_from_env }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index 00bd3de0..3904d1bd 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -1185,23 +1185,20 @@ env: # the next major version. requireExplicitSecrets: false - # Instance settings (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) live in - # the instance-configuration table in the database; most are copied from the - # environment once, on first startup, and OIDC/SAML/LDAP never are. Leave this at '1'. The API always reads the database - # whatever this says; '0' only moves worker, beat and the consumers to the - # environment, so the two can disagree. To make the environment win, use - # sync_config_from_env below. - skip_env_var: '1' - - # Copy every instance setting the environment sets (extraEnv or - # external_secrets.app_env_existingSecret) into the database on each API start, - # so an external secret store or GitOps values are the source of truth and - # rotation takes effect on restart. Keys left unset or empty keep their stored - # value. Trade-off: a god-mode admin UI edit to a key the environment sets lasts - # only until the next restart. Plane versions that predate it ignore the flag. - # The README lists all 73 settings it covers. + # Make the environment the source of truth for Plane's instance settings, the + # ones the god-mode admin UI edits (sign-in, SSO, SMTP, AI key, limits). They + # live in the database: most are copied from the environment once, on first + # startup, and OIDC/SAML/LDAP never are. With this on, every such setting set in + # extraEnv or external_secrets.app_env_existingSecret is copied into the + # database on each API start, so rotation takes effect on restart. Settings left + # unset or empty keep their stored value. Trade-off: a god-mode edit to a setting + # the environment sets lasts only until the next restart. Plane versions that + # predate it ignore the flag. The README lists all 73 settings. sync_config_from_env: false + # skip_env_var is deprecated and no longer listed: the API never honoured it. + # Leave it unset and use sync_config_from_env. See the chart README. + # Kubernetes internal cluster domain used to build in-cluster service URLs default_cluster_domain: 'cluster.local' From 20de28bb81fad13adbb23dfb0621b00cef652814 Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Mon, 2 Nov 2026 13:27:49 +0530 Subject: [PATCH 4/4] [INFRA-1332] docs(plane-enterprise): instance settings are managed in god-mode; remove env.skip_env_var from values Instance settings (sign-in, SSO providers, SMTP, LLM key) are managed in the god-mode admin UI by design, not through environment variables. The chart documented env.skip_env_var: '0' as making the API read them from the environment, which the commercial API never did. Drop sync_config_from_env (its app side, plane-ee #10852, was closed) and remove env.skip_env_var from values.yaml. The README, rotation runbook and install notes now say to manage and rotate these settings in god-mode. The template keeps rendering SKIP_ENV_VAR with default "1", so every existing release renders byte-identical, and the install notes warn anyone who still sets '0' to save their settings in god-mode and then remove it. --- charts/plane-enterprise/README.md | 48 ++----------------- .../external-secrets/rotation-runbook.md | 2 +- charts/plane-enterprise/questions.yml | 6 --- charts/plane-enterprise/templates/NOTES.txt | 6 +-- .../templates/config-secrets/app-env.yaml | 9 ++-- charts/plane-enterprise/values.yaml | 14 ------ 6 files changed, 10 insertions(+), 75 deletions(-) diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md index 0f29062e..afe2ecb2 100644 --- a/charts/plane-enterprise/README.md +++ b/charts/plane-enterprise/README.md @@ -1736,51 +1736,11 @@ From chart 3.6.0 onward that Secret is rendered as base64 `data` rather than `st Helm can express the deletion and this stops recurring. The one-time cleanup above is still needed for the upgrade that crosses into 3.6.0. -### 6. Secrets that live in the database, not the environment +### 6. Settings managed in god-mode, not the environment -The API reads the 73 instance settings listed below — sign-in methods, SSO providers, SMTP, the AI key and a few limits — from the instance-configuration table, which the god-mode admin UI edits. Most are copied from the environment once, on first startup; the OIDC, SAML and LDAP settings are never read from it. **Setting or rotating any of them through the environment has no effect** after first startup. +Instance settings — sign-in methods, Google/GitHub/GitLab/Gitea/OIDC/SAML/LDAP, SMTP (including its password), `LLM_API_KEY` and the other options on the god-mode admin pages — are managed in the god-mode admin UI by design and stored in the database. Environment variables do not configure them, so **rotating them through a Secret has no effect**: change them in god-mode. -Set `env.sync_config_from_env: true` to copy every one of those settings the environment sets (through `extraEnv` or `external_secrets.app_env_existingSecret`) into the database on each API start, which makes the external secret or your GitOps values the source of truth: - -```yaml -env: - sync_config_from_env: true -extraEnv: - - name: IS_OIDC_ENABLED - value: "1" -``` - -- Settings the environment leaves unset or empty keep their stored value, so anything configured in the god-mode admin UI keeps working. -- The trade-off: a god-mode edit to a setting the environment sets lasts only until the next restart. -- The API logs the names (never the values) of the settings it changed: `PLANE_SYNC_CONFIG_FROM_ENV: applied from the environment: IS_OIDC_ENABLED`. Plane versions that predate the flag ignore it, so no such line appears. - -**`env.skip_env_var` is deprecated: leave it unset.** It was the old switch for this, but the API never honoured it. `'0'` only moves worker, beat and the consumers to the environment, so they can disagree with the API. If you set it to `'0'` today, either through `env.skip_env_var` or a `SKIP_ENV_VAR` entry in `extraEnv`, move off it in two upgrades so the workers never read a stale value in between: - -1. Turn on `env.sync_config_from_env` and upgrade. The API copies your environment values into the database. -2. Remove the `skip_env_var` setting and upgrade again. The workers now read the same values from the database. - -**Settings that `sync_config_from_env` applies.** Set each as an environment variable of the same name. Toggles take `"1"` or `"0"`. 🔒 marks a secret, which the database stores encrypted; supply those from a Secret (`external_secrets.app_env_existingSecret`) rather than `extraEnv`. - -| Area | Environment variables | Notes | -| --- | --- | --- | -| Sign-in | `ENABLE_SIGNUP`, `ENABLE_EMAIL_PASSWORD`, `ENABLE_MAGIC_LINK_LOGIN` | Magic links also need SMTP. | -| Workspaces | `DISABLE_WORKSPACE_CREATION` | | -| Security | `DISABLE_ACCESS_TOKENS`, `HIDE_EMAIL_CHANGE_DETAILS`, `SESSION_COOKIE_AGE`, `ADMIN_SESSION_COOKIE_AGE`, `WORK_ITEM_EXPORT_EXPIRY_SECONDS` | Ages and expiry are in seconds. | -| OIDC | `IS_OIDC_ENABLED`, `OIDC_PROVIDER_NAME`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` 🔒, `OIDC_AUTHORIZE_URL`, `OIDC_TOKEN_URL`, `OIDC_USERINFO_URL`, `OIDC_LOGOUT_URL`, `ENABLE_OIDC_IDP_SYNC` | | -| SAML | `IS_SAML_ENABLED`, `SAML_PROVIDER_NAME`, `SAML_ENTITY_ID`, `SAML_SSO_URL`, `SAML_LOGOUT_URL`, `SAML_CERTIFICATE` 🔒, `SAML_NAME_ID_FORMAT`, `SAML_ATTRIBUTE_MAPPING`, `SAML_DISABLE_REQUESTED_AUTHN_CONTEXT`, `ENABLE_SAML_IDP_SYNC` | `SAML_ATTRIBUTE_MAPPING` is a JSON object, such as `{"display_name": "preferred_username"}`; keys it leaves out keep their defaults. | -| LDAP | `IS_LDAP_ENABLED`, `LDAP_PROVIDER_NAME`, `LDAP_SERVER_URI`, `LDAP_BIND_DN`, `LDAP_BIND_PASSWORD` 🔒, `LDAP_USER_SEARCH_BASE`, `LDAP_USER_SEARCH_FILTER`, `LDAP_USER_ATTRIBUTES` | `LDAP_USER_ATTRIBUTES` is comma-separated. | -| Google | `IS_GOOGLE_ENABLED`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` 🔒, `ENABLE_GOOGLE_SYNC` | | -| GitHub | `IS_GITHUB_ENABLED`, `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` 🔒, `GITHUB_ORGANIZATION_ID`, `ENABLE_GITHUB_SYNC` | `GITHUB_ORGANIZATION_ID` limits sign-in to that organization's members. | -| GitLab | `IS_GITLAB_ENABLED`, `GITLAB_HOST`, `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET` 🔒, `ENABLE_GITLAB_SYNC` | | -| Gitea | `IS_GITEA_ENABLED`, `GITEA_HOST`, `GITEA_CLIENT_ID`, `GITEA_CLIENT_SECRET` 🔒, `ENABLE_GITEA_SYNC` | | -| Email (SMTP) | `ENABLE_SMTP`, `EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_HOST_USER`, `EMAIL_HOST_PASSWORD` 🔒, `EMAIL_FROM`, `EMAIL_USE_TLS`, `EMAIL_USE_SSL` | | -| AI | `LLM_PROVIDER`, `LLM_MODEL`, `LLM_API_KEY` 🔒, `GPT_ENGINE` | `GPT_ENGINE` is deprecated; use `LLM_MODEL`. | -| Images | `UNSPLASH_ACCESS_KEY` 🔒 | | -| Chat support | `IS_CHAT_SUPPORT_ENABLED`, `CHAT_SUPPORT_APP_ID` | | -| Projects | `PROJECT_IDENTIFIER_MAX_LENGTH` | 1 to 255. | -| Log retention | `WEBHOOK_EVENTS_RETENTION_IN_DAYS`, `API_LOGS_RETENTION_IN_DAYS` | In days. | - -The `ENABLE_*_SYNC` and `ENABLE_*_IDP_SYNC` toggles refresh a user's profile from that provider at each sign-in. +Earlier chart versions documented `env.skip_env_var: '0'` for this. It never changed what the API reads, and it has been removed from `values.yaml`. If you set it, save those settings in god-mode first, then remove it: while it is set, worker, beat and the consumers read the environment instead of the database and can disagree with the API. ### AI providers, including Amazon Bedrock @@ -1838,8 +1798,6 @@ chart: an empty credential is *present*, and a present credential denies the cha | `external_secrets.app_keys_existingSecret` | | One Secret for the shared signing/encryption keys. | | `external_secrets.ssl_token_existingSecret` | | DNS-01 API token for the cert-manager Issuer; must contain the key `api-token`. | | `env.requireExplicitSecrets` | false | Fail the render instead of falling back to the chart's public example keys. Will default to `true` in the next major version. | -| `env.sync_config_from_env` | false | On each API start, copy every instance setting the environment sets (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) into the database, so the environment wins. | -| `env.skip_env_var` | (unset) | **Deprecated**; leave unset. Still rendered, defaulting to `'1'`, so existing values keep working. Use `env.sync_config_from_env`. | | `global.forceRedeploy` | false | Restart every workload on every `helm upgrade`, as versions before 3.1.0 did. Off means upgrades roll only what changed. | ### Provider examples diff --git a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md index 61db8abc..043136ec 100644 --- a/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md +++ b/charts/plane-enterprise/examples/external-secrets/rotation-runbook.md @@ -78,7 +78,7 @@ Both fail **silently**: decryption errors are swallowed and the values come back **The bundled `local_setup` infrastructure is out of scope.** The chart's own postgres/rabbitmq/minio/opensearch StatefulSets are intended for local and evaluation use; rotating their credentials means changing the password inside the container as well, which the chart does not orchestrate. Everything here assumes managed backends. -**Database-resident secrets do not rotate through the environment by default.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` live in the instance-configuration table, not the environment (some are copied from it once, on first boot; `LDAP_BIND_PASSWORD` never is). Set `env.sync_config_from_env: true` to copy the environment's values into the database on every API start, so a rotation takes effect on the next restart — at the cost of god-mode admin UI edits to those settings lasting only until then. The deprecated `env.skip_env_var` does not do this: the API ignores it. +**Database-resident secrets do not rotate through the environment.** The SMTP password, OAuth client secrets, `LLM_API_KEY` and `LDAP_BIND_PASSWORD` are managed in the god-mode admin UI and stored in the database, by design. Rotate them there; changing the Secret has no effect. (`env.skip_env_var` does not change this and is no longer a chart value.) **Silo, live and Plane AI rotate like the API from planeVersion v3.2.0** — they read discrete parts, so nothing recomposes a DSN and a Reloader restart is all that is needed. diff --git a/charts/plane-enterprise/questions.yml b/charts/plane-enterprise/questions.yml index 1f32a298..b0a2ca3f 100644 --- a/charts/plane-enterprise/questions.yml +++ b/charts/plane-enterprise/questions.yml @@ -2158,12 +2158,6 @@ questions: type: boolean default: false group: "Service Account" -- variable: env.sync_config_from_env - label: "Apply Instance Settings from the Environment" - description: "On each API start, copies every instance setting the environment sets (SMTP, OAuth/OIDC/SAML/LDAP, LLM key, login toggles) into the database, so the environment wins. A god-mode edit to such a setting lasts only until the next restart." - type: boolean - default: false - group: "Service Account" - variable: external_secrets.otel_env_existingSecret label: "OpenTelemetry Envs Secrets File Name" description: "Supplies OTEL_EXPORTER_OTLP_HEADERS. Leave blank to let the chart create the Secret from the OTLP Exporter Headers value." diff --git a/charts/plane-enterprise/templates/NOTES.txt b/charts/plane-enterprise/templates/NOTES.txt index 8b4e499b..6bd59b0f 100644 --- a/charts/plane-enterprise/templates/NOTES.txt +++ b/charts/plane-enterprise/templates/NOTES.txt @@ -123,11 +123,11 @@ Warn rather than reorder: reordering would change which value existing installs {{- end }} {{- /* Secrets that env rotation cannot reach. */}} -{{- if and (not .Values.env.sync_config_from_env) (or .Values.external_secrets.app_keys_existingSecret $externalInfra) }} -{{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n read from the instance-configuration table in the database, not the environment\n (some are copied from it once, on first startup). Rotating those through a Secret\n will have no effect. Set env.sync_config_from_env=true to apply the environment on every restart." }} +{{- if or .Values.external_secrets.app_keys_existingSecret $externalInfra }} +{{- $warnings = append $warnings "The SMTP password, OAuth client secrets, LLM_API_KEY and LDAP_BIND_PASSWORD are\n managed in the god-mode admin UI and stored in the database, not read from the\n environment. Rotating them through a Secret has no effect; change them in god-mode." }} {{- end }} {{- if ne (.Values.env.skip_env_var | default "1" | toString) "1" }} -{{- $warnings = append $warnings "env.skip_env_var is deprecated, and the API ignores this value: it keeps reading\n instance settings from the database while worker, beat and the consumers read the\n environment, so the two can disagree. Turn on env.sync_config_from_env first, then\n remove env.skip_env_var in a later upgrade (see the chart README)." }} +{{- $warnings = append $warnings "env.skip_env_var is no longer a chart value. Instance settings are managed in\n god-mode and the API ignores '0', but worker, beat and the consumers read the\n environment while it is set, so they can disagree with the API. Save those settings\n in god-mode, then remove env.skip_env_var." }} {{- end }} {{- /* Static object-storage keys where a cloud identity would do. */}} diff --git a/charts/plane-enterprise/templates/config-secrets/app-env.yaml b/charts/plane-enterprise/templates/config-secrets/app-env.yaml index ccd7ff46..6e53b146 100644 --- a/charts/plane-enterprise/templates/config-secrets/app-env.yaml +++ b/charts/plane-enterprise/templates/config-secrets/app-env.yaml @@ -123,13 +123,10 @@ data: PAYMENT_SERVER_BASE_URL: {{ .Values.license.licenseServer | quote }} DEFAULT_API_RATE_LIMIT: {{ .Values.env.api_key_rate_limit | default "120/minute" | quote }} - {{- /* env.skip_env_var is deprecated and gone from values.yaml; the same default - keeps existing releases unchanged. The API ignores '0'. */}} + {{- /* Instance settings are managed in god-mode by design; the API always reads them + from the database. env.skip_env_var is no longer in values.yaml: the default + keeps existing releases unchanged, and NOTES warns about an explicit '0'. */}} SKIP_ENV_VAR: {{ .Values.env.skip_env_var | default "1" | quote }} - {{- /* Rendered only when on, so existing releases render byte-identical. */}} - {{- if .Values.env.sync_config_from_env }} - PLANE_SYNC_CONFIG_FROM_ENV: "1" - {{- end }} MINIO_ENDPOINT_SSL: {{ .Values.services.minio.env.minio_endpoint_ssl | default false | ternary "1" "0" | quote }} USE_STORAGE_PROXY: {{ .Values.env.use_storage_proxy | default false | ternary "1" "0" | quote }} ALLOW_ALL_ATTACHMENT_TYPES: {{ .Values.env.allow_all_attachment_types | default false | ternary "1" "0" | quote }} diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml index 3904d1bd..9cf95eda 100644 --- a/charts/plane-enterprise/values.yaml +++ b/charts/plane-enterprise/values.yaml @@ -1185,20 +1185,6 @@ env: # the next major version. requireExplicitSecrets: false - # Make the environment the source of truth for Plane's instance settings, the - # ones the god-mode admin UI edits (sign-in, SSO, SMTP, AI key, limits). They - # live in the database: most are copied from the environment once, on first - # startup, and OIDC/SAML/LDAP never are. With this on, every such setting set in - # extraEnv or external_secrets.app_env_existingSecret is copied into the - # database on each API start, so rotation takes effect on restart. Settings left - # unset or empty keep their stored value. Trade-off: a god-mode edit to a setting - # the environment sets lasts only until the next restart. Plane versions that - # predate it ignore the flag. The README lists all 73 settings. - sync_config_from_env: false - - # skip_env_var is deprecated and no longer listed: the API never honoured it. - # Leave it unset and use sync_config_from_env. See the chart README. - # Kubernetes internal cluster domain used to build in-cluster service URLs default_cluster_domain: 'cluster.local'