refactor: centralize and validate environment configuration#54
Merged
Conversation
leonkenneth
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Environment-variable handling was distributed across authentication, profiles, endpoint resolution, OAuth, HTTP test hooks, updater behavior, shell completion, terminal styling, and filesystem configuration.
Each caller accessed
process.envindependently and interpreted values locally. This created several risks:process.envreads could bypass validation and redaction conventions.ALTERTABLE_*variables were silently ignored, potentially causing the CLI to use stored credentials or default endpoints unexpectedly.Proposed solution
Introduce a single typed environment schema in
cli/src/lib/env.tsand route all production environment access through it.The schema uses canonical environment-variable names directly as typed keys:
This avoids an additional alias vocabulary and makes code search, autocomplete, error messages, and public documentation use the same names.
The centralized API provides:
readEnv()for live, typed reads fromprocess.envreadEnvFrom()for typed reads from injected environmentssetEnv()andunsetEnv()for validated mutationscopyProcessEnv()for callers that must pass through the complete environmentvalidateEnvironment()for startup validationisSecretEnv()for safe diagnostic renderingReads remain lazy so existing tests and commands that mutate the environment during a process continue to behave correctly.
Validation behavior
The schema defines parsers for each supported value shape:
true,false,1, or0.ALTERTABLE_OAUTH_REDIRECT_PORTmust be an integer between0and65535.ConfigurationErrorand retain the CLI’s stable configuration exit code,10.The CLI now validates every configured
ALTERTABLE_*value during startup. Unknown names are rejected as well, so a typo such asALTERTABLE_API_KEIcannot silently fall back to another credential source.Repository and CI passthrough variables, including mock-server and Docker credentials, are explicitly registered so shared execution environments remain supported.
Secret safety
Secret metadata now lives alongside each schema definition.
Variables whose names end in credential-bearing suffixes such as
_KEY,_TOKEN,_PASSWORD, or_SECRETmust explicitly declaresecret: true. A schema assertion runs when the module loads and throws if a credential-looking variable is added without secret metadata.This prevents future environment variables from accidentally appearing unmasked in profile diagnostics.
Migration scope
This branch migrates environment access across:
Architectural guardrails
A new test scans production modules and fails if direct
process.envaccess is introduced outsideenv.ts.Additional tests cover:
ALTERTABLE_*namesCompatibility and behavior changes
Valid existing configurations retain their precedence and behavior.
Intentional changes:
ALTERTABLE_*names now fail with a configuration error.