| status | date | decision-makers | consulted | informed |
|---|---|---|---|---|
| accepted | 2026-10-22 | kubara-Team | kubara-Team | - |
Improve Environment Variable Handling
Context and Problem Statement
kubara currently has a hard dependency on a .env file across init, generate, and bootstrap, and uses both .env and config.yaml to define platform parameters. This creates several problems:
- Cluster configuration (
PROJECT_NAME,PROJECT_STAGE,ARGOCD_GIT_URL,ARGOCD_GIT_HTTPS_URL,ARGOCD_GIT_AUTH_MODE,ARGOCD_HELM_REPO_URL) lives in.env. It is unclear whether these settings apply only to the Hub cluster or to Spoke clusters as well. - Initializing a project requires a two-step command flow: running
kubara init --prepto generate.env, editing it, and then runningkubara initto copy parts of those values intoconfig.yaml. - Later runs using
kubara init --overwriteread.envto overwrite values inconfig.yaml, maintaining two conflicting sources of truth. kubara generaterequires.envand injects its contents into template contexts under.env, creating the risk of leaking secrets into rendered GitOps manifests committed to version control. This MUST be removed.- Requiring a
.envfile on disk makes CI/CD and non-interactive automation unnecessarily cumbersome when environment variables are already available in the process environment. - Existing environment variables are prefixed with
ARGOCD_, coupling credential names to a specific tool rather than GitOps repository access generically, and require users to manually supplyARGOCD_WIZARD_ACCOUNT_PASSWORD. This is not in line with our aim to support multiple gitops engines.
We need a clear boundary: config.yaml MUST be the sole source of truth for platform configuration (schema changes are covered in a separate ADR), the hard dependency on .env MUST be removed in favor of checking OS environment variables first and falling back to .env, ARGOCD_WIZARD_ACCOUNT_PASSWORD MUST be autogenerated, and environment variables MUST be reduced to GITOPS_-prefixed repository credentials needed only for initial bootstrap. Old names MUST also be recognized for backward compatibility.
Decision Drivers
- Single source of truth for all cluster and platform configuration in
config.yaml. - Zero risk of secret leakage into generated GitOps manifests.
- No hard dependency on a
.envfile; first-class support for OS environment variables with.envas an optional fallback. - Minimal credential surface area limited strictly to initial bootstrap repository access.
- Simpler initialization flow without
--prep,--overwrite, or.envscaffolding.
Considered Options
- Keep the existing two-stage command workflow and hard
.envdependency across commands. - Move everything into
config.yamlusing external secret references or inline encryption usingageorsops. - Remove the hard
.envdependency, move all configuration toconfig.yaml, autogenerate the Argo CDwizardpassword, and restrict environment variables (and optional.env) toGITOPS_-prefixed bootstrap repository credentials.
Decision Outcome
Chosen option: remove the hard .env dependency, move all configuration to config.yaml, autogenerate the Argo CD wizard password, and restrict environment variables (and optional .env) to GITOPS_-prefixed bootstrap repository credentials.
Accept the old ARGOCD_ prefix for backward compatibility, but emit a warning.
| previous variable in .env | moves to |
|---|---|
| PROJECT_NAME | config.yaml |
| PROJECT_STAGE | config.yaml |
| ARGOCD_GIT_URL | config.yaml |
| ARGOCD_GIT_AUTH_MODE | config.yaml (inferred from url) |
| ARGOCD_HELM_REPO_URL | config.yaml |
| ARGOCD_WIZARD_ACCOUNT_PASSWORD | autogenerated and printed once at bootstrap |
| ARGOCD_GIT_SSH_PRIVATE_KEY | GITOPS_GIT_SSH_PRIVATE_KEY / GITOPS_GIT_SSH_PRIVATE_KEY_PATH |
| ARGOCD_GIT_USERNAME | GITOPS_GIT_USERNAME |
| ARGOCD_GIT_PAT_OR_PASSWORD | GITOPS_GIT_PASSWORD |
| ARGOCD_HELM_REPO_USERNAME | GITOPS_HELM_REPO_USERNAME |
| ARGOCD_HELM_REPO_PASSWORD | GITOPS_HELM_REPO_PASSWORD |
| ARGOCD_GIT_GITHUB_APP_ID | GITOPS_GIT_GITHUB_APP_ID |
| ARGOCD_GIT_GITHUB_APP_INSTALLATION_ID | GITOPS_GIT_GITHUB_APP_INSTALLATION_ID |
| ARGOCD_GIT_GITHUB_APP_PRIVATE_KEY | GITOPS_GIT_GITHUB_APP_PRIVATE_KEY / GITOPS_GIT_GITHUB_APP_PRIVATE_KEY_PATH |
| ARGOCD_GIT_GITHUB_APP_ENTERPRISE_BASE_URL | GITOPS_GIT_GITHUB_APP_ENTERPRISE_BASE_URL |
| DOCKERCONFIG_BASE64 | unchanged |
If an existing .env contains deprecated or removed fields, kubara logs a warning.
Credential resolution order
Only kubara bootstrap reads bootstrap credentials. When resolving credentials, kubara checks sources in the following order:
- OS environment variables (checked first).
.envfile, used as a fallback for any variables not set in the process environment).- Error if required bootstrap credentials are still missing or invalid after checking both sources.
The .env file is completely optional. If the default .env file does not exist and required credentials are provided via OS environment variables, kubara bootstrap succeeds without requiring a .env file on disk.
Variable names are identical in OS environment variables and in .env (the KUBARA_ prefix is dropped).
Configuration and credential boundary
All non-secret configuration (PROJECT_NAME, PROJECT_STAGE, ARGOCD_GIT_URL, ARGOCD_GIT_HTTPS_URL, ARGOCD_GIT_AUTH_MODE, ARGOCD_HELM_REPO_URL) is removed from environment variables and .env and lives exclusively in config.yaml (the exact config.yaml schema changes are defined in a separate ADR).
Environment variables are generically prefixed with GITOPS_ instead of ARGOCD_ and are restricted to repository credentials for initial bootstrap:
- Git repository credentials (optional for public HTTP(S) repositories; mutually exclusive when configured):
Git authentication mode is inferred from the repository URL in
config.yaml. At most one of the following credential sets may be configured duringkubara bootstrap: - SSH key authentication:
GITOPS_GIT_SSH_PRIVATE_KEY(inline) orGITOPS_GIT_SSH_PRIVATE_KEY_PATH(path to private key file). - Username/password authentication:
GITOPS_GIT_USERNAMEandGITOPS_GIT_PASSWORD(both must be set together). - GitHub App authentication:
GITOPS_GIT_GITHUB_APP_ID,GITOPS_GIT_GITHUB_APP_INSTALLATION_ID, andGITOPS_GIT_GITHUB_APP_PRIVATE_KEY(orGITOPS_GIT_GITHUB_APP_PRIVATE_KEY_PATH), with optionalGITOPS_GIT_GITHUB_APP_ENTERPRISE_BASE_URL. - Providing credentials from multiple methods, or providing partial credential sets (e.g. only one of username/password, or both inline key and key path), fails validation with an error.
- Omitting credentials for an HTTP(S) repository URL is permitted (for public repositories), but kubara logs a warning in non-
--localmode that unauthenticated access is not recommended for production setups. - Helm repository credentials (optional):
GITOPS_HELM_REPO_USERNAMEandGITOPS_HELM_REPO_PASSWORD(both must be set together when authenticating against a private Helm repository).ARGOCD_WIZARD_ACCOUNT_PASSWORDis removed from environment variables and.env. kubara always autogenerates the initialwizardaccount password duringkubara bootstrapand prints it once in the bootstrap completion output.
Generation boundary
kubara generate stops reading .env and environment variables entirely:
- The
.envkey is removed from the template rendering context to ensure NO secrets can leak into Git manifests. - Templates must source all cluster and service values from
config.yaml. - Templates attempting to reference
.envwill fail at render time. This is a BREAKING CHANGE!
Streamlined initialization
kubara init replaces the multi-step flow and no longer creates or reads .env:
- The
--prepflag is removed. - The
--overwriteflag is removed. - Running
kubara initscaffoldsconfig.yaml,env.example(if not already existing, documenting available bootstrap credentials), andrenovate.json(if enabled). Both.envandenv.exampleare added to the generated.gitignore. - If
config.yamlalready exists,kubara initfails rather than overwriting existing configuration. kubara init --localgeneratesconfig.yamlpre-filled with local evaluation settings in one step without creating a.envfile.
Secret resolution during bootstrap
During kubara bootstrap <cluster-name>, kubara resolves GITOPS_* credentials from OS environment variables first and an optional .env file in the working directory second, applying them to the targeted cluster. If no .env file exists, kubara expects credentials to be supplied via OS environment variables.
Consequences
- Good, because
config.yamlbecomes the single source of truth for all cluster and repository configuration. - Good, because
kubarano longer requires a.envfile on disk and works natively with OS environment variables in CI/CD and local shells. - Good, because
kubara generatecannot leak secrets into git-tracked manifests. - Good, because
ARGOCD_WIZARD_ACCOUNT_PASSWORDis autogenerated during bootstrap instead of requiring manual management. - Good, because
kubara initis a single step that only creates declarative configuration and a staticenv.examplereference. - Good, because
internal/envconfigand custom store layers are removed in favor of a clean, isolated bootstrap loader using standardgodotenv.Read. - Bad, because any custom templates expecting
.envin their rendering context will break.
Non-Goals
- Defining the
config.yamlschema changes (covered in a separate ADR). - Replacing environment variables /
.envwith a built-in secret manager or vault client. - Encrypting secrets within git-tracked files.