valueFrom.secretKeyRef. If your security policies don’t allow secrets in environment variables, turn on secrets from files, and the chart mounts each secret as a file instead.
Astro Private Cloud 2.2This feature was introduced in Astro Private Cloud 2.2. To access this feature, upgrade your Astro Private Cloud installation to 2.2 or later.
PreviewSecrets from files is in Preview. Some platform components don’t support it yet and keep their secrets in environment variables. See Secrets that stay in environment variables.
How it works
The feature covers two kinds of components:- Components that run a secrets loader, code in the APC image that reads the secret files when the container starts and passes each value to the application. These are the APC API, APC Worker, Navigator, DP-Link, the data plane internal API, Pilot, the Prometheus service discovery reloader, and the database bootstrapper.
- Third-party components that read secret files with their own software: the Vector logging sidecar, the external Elasticsearch proxy, the Prometheus federation authentication proxy, PostgreSQL, and the PostgreSQL exporter.
- Mounts each of the component’s secrets as a file, most of them in
/etc/astronomer/secrets/, with mode0440. - Sets the Pod’s
fsGrouptoglobal.secretsFromFiles.fsGroup, which defaults to1000, so that the component’s non-root process can read the files. On OpenShift, the chart doesn’t set anfsGroup, because OpenShift assigns one to each namespace. - Removes the environment variables that referenced those secrets.
helm upgradefails if your values would also put one of the component’s secrets in its environment, for example in the component’senvlist. The upgrade fails before it changes anything in your cluster.- When the container starts, the loader exits with an error if one of the component’s secrets is also in its environment, or if a file that it needs is missing or unreadable. Most loaders also exit on an empty file. See Fix startup errors for the exceptions.
- The Vector logging sidecar, the external Elasticsearch proxy, and the federation authentication proxy don’t start if a secret file is missing or empty.
- PostgreSQL ignores an empty password file after its data folder exists, and its entrypoint passes the password to the database server in the server’s environment.
- The PostgreSQL exporter’s init container refuses an empty connection string. If you use the split datasource, the exporter doesn’t check for an empty password file.
kubectl exec <pod-name> -- env. After a loader reads a file, it still passes the value to its application in the process’s own environment, because the application reads its configuration from there. Processes that the application starts inherit those values.
Components read their secret files when they start. After you change a Kubernetes Secret, restart the Pods that use it, as you would for a secret in an environment variable.
Components and settings
Each component has its ownsecretsFromFiles.enabled setting. If you don’t set it, the component follows global.secretsFromFiles.enabled. The database bootstrapper is the exception: its setting, global.dbBootstrapper.secretsFromFiles.enabled, defaults to false and doesn’t follow the global setting.
Secrets that stay in environment variables
The following secrets have nosecretsFromFiles setting, and stay in environment variables whatever you set:
- Grafana’s database connection
- The registry’s notification header
- The secrets of Laminar
- Entries that you add to
astronomer.mcpServer.secret. The Astro Private Cloud MCP server has no secrets of its own, and the chart doesn’t refuse these entries while the feature is on.
global.dbBootstrapper.secretsFromFiles.enabled.
Environment variables that you add to a component’s own values also stay environment variables when the component has no secretsFromFiles setting. For example, registry storage credentials in astronomer.registry.extraEnvVars and Vector credentials in vector.extraEnv stay environment variables.
Secrets from files doesn’t change Airflow Deployments. To keep Airflow connections and variables out of environment variables, use a secrets backend.
Prerequisites
- Astro Private Cloud 2.2 or later.
- Permission to run
helm upgradeon your platform release. In a split installation, the control plane and each data plane are separate Helm releases. See Apply a config change. - The platform images that your APC chart version pins. Images from versions earlier than 2.2 can’t read secrets from files. If you override an image for a component that the feature covers, use an image from the same APC release as the chart.
Turn on secrets from files
1
Move secrets out of environment variable lists
While the feature applies to a component, If you store your external Elasticsearch credentials inline in
helm upgrade fails if one of the following lists in your values.yaml file contains one of the component’s secrets:astronomer.houston.env,astronomer.navigator.env, andastronomer.dpLink.envastronomer.commander.envandastronomer.pilot.envprometheus.filesdReloader.extraEnvglobal.customLogging.extraEnvpostgresql.extraEnv
HOUSTON_SECRETS_FROM_FILES or a <NAME>_FILE path. In astronomer.dpLink.env, astronomer.pilot.env, and the extraEnv lists, it refuses any entry that takes its value from a Kubernetes Secret.To give the APC API, Navigator, or DP-Link a secret of your own, add it to the component’s secret list instead of its env list. The chart delivers each entry as a file named after its envName, and the secrets loader requires that file. For example:global.customLogging.secret, store them under the elastic key of a Kubernetes Secret instead, and name the Secret in global.customLogging.secretName. See Save your Elastic Cloud deployment credentials.For entries in the other lists, remove the entry. The chart delivers those components’ secrets itself.2
(Optional) Check the PostgreSQL exporter's connection string
Skip this step unless If you already use the split datasource, with
global.prometheusPostgresExporter.enabled is true in your values.The exporter can’t read a whole connection string from a file. With the feature on, an init container named split-data-source-name reads the connection string from prometheus-postgres-exporter.config.datasource.connectionSecret and writes the database user, password, and address to separate files that the exporter reads. Only the init container mounts the Kubernetes Secret that holds the connection string.The init container fails, and the exporter doesn’t start, if the connection string:- Is missing or empty.
- Isn’t a
postgres://orpostgresql://URL. For example, ahost=... user=...connection string. - Contains a comma. Percent-encode it as
%2C. - Has an invalid percent-escape or a control character, or a user or password that starts or ends with whitespace.
- Has no user or no host.
connectionSecret set to null and a passwordSecret, it keeps working, and the exporter reads its password from a file.To keep the exporter on environment variables instead, turn the feature off for it:3
Turn on the feature
Add the following values to your
values.yaml file:global.secretsFromFiles.enabled turns on the feature for every component that doesn’t set its own setting to false. The database bootstrapper needs its own setting, as Components and settings explains.In a split installation, add these values to the values file of each release, the control plane and each data plane, where you want the feature.Change global.secretsFromFiles.fsGroup only if a component’s image runs with a group other than 1000.4
(Optional) Keep a component on environment variables
To keep one component on environment variables while the feature is on for the rest of the platform, set the component’s own setting to To turn on the feature for some components only, leave
false. For example:global.secretsFromFiles.enabled set to false, and set those components’ settings to true.Each secretsFromFiles.enabled setting must be true, false, or unset. A quoted value, such as "false", fails the render.5
Apply the change
Apply your updated
values.yaml file with helm upgrade. See Apply a config change.If the chart refuses your values, helm upgrade fails before it changes anything in your cluster, and the error names the setting to change. See Fix Helm upgrade errors.The Pods of each component that the change affects restart.6
Verify the change
-
List the environment variables that still take their values from Kubernetes Secrets:
The command lists the Pod, container, and variable name for each one, and never a value. With the feature on for every covered component, the output lists only the secrets that stay in environment variables, such as
GF_DATABASE_URLin the Grafana Pod andREGISTRY_NOTIFICATIONS_ENDPOINTS_0_HEADERSin the registry Pod. In a split installation, run the command on each cluster. -
Confirm that a component loaded its secrets. For example, for the APC API:
The output looks similar to the following:The number depends on your configuration. The secrets loader logs this line when the container starts, so the line can be missing from the log of a container that has run for a long time.
Turn off secrets from files
Setglobal.secretsFromFiles.enabled to false. If you turned on global.dbBootstrapper.secretsFromFiles.enabled, set it to false too. Then apply the change.
The components go back to environment variables that reference the same Kubernetes Secrets. A component whose own setting is true keeps reading its secrets from files.
Troubleshoot
Fix Helm upgrade errors
When the chart refuses your values, the error starts with a token for the problem, then names the setting to change:Fix startup errors
When a secrets loader finds a problem, the container exits, and the Pod restarts with theCrashLoopBackOff status. The container’s log lists each problem on its own line, with the variable name and a token, and ends with a line that describes how to fix the problems. For example:
If the cause is a permission error, check that the Pod’s
securityContext.fsGroup is set, and that no admission policy in your cluster removes or replaces it.