# How Continue Handles Sensitive Configuration Details: Environment-Based Security for AI Credentials

> Safeguard AI credentials and sensitive config details with Continue. Discover how environment variables and secure loading prevent secrets from entering source control.

- Repository: [Continue/continue](https://github.com/continuedev/continue)
- Tags: best-practices
- Published: 2026-06-18

---

**Continue keeps all secrets out of source control by loading sensitive configuration details exclusively from environment variables at runtime, using `dotenv` for local development and merging values into YAML configurations while enforcing git ignore rules to prevent accidental commits.**

The open-source AI coding assistant Continue (continuedev/continue) manages API keys, tokens, and proxy credentials through a robust environment-based system. Understanding how sensitive configuration details are handled in this repository is essential for developers deploying the tool across local, CI, and production environments. The codebase implements a defense-in-depth strategy that separates secrets from version-controlled files while maintaining flexibility for different deployment scenarios.

## Environment Variable Architecture

### Dotenv Integration for Local Development

The application entry points initialize `dotenv` to enable local `.env` file usage without requiring those files to be checked into the repository. In [`packages/openai-adapters/src/index.ts`](https://github.com/continuedev/continue/blob/main/packages/openai-adapters/src/index.ts), the module loads environment configuration immediately upon import:

```typescript
// packages/openai-adapters/src/index.ts
import dotenv from "dotenv";
dotenv.config();                     // Load .env in development

if (process.env.CONTINUE_USE_AI_SDK) {
  // Use the SDK only when the flag is present
}

// Example of reading an API key
export const openaiClient = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY!,   // ‘!’ asserts the key is present
});

```

Similarly, the CLI extension centralizes its environment handling in [`extensions/cli/src/env.ts`](https://github.com/continuedev/continue/blob/main/extensions/cli/src/env.ts), ensuring consistent access patterns across the monorepo:

```typescript
// extensions/cli/src/env.ts
import * as dotenv from "dotenv";
dotenv.config();                     // Load .env for the CLI

export const getProxy = () => ({
  http: process.env.HTTP_PROXY || process.env.http_proxy,
  https: process.env.HTTPS_PROXY || process.env.https_proxy,
});

```

### Runtime Environment Access

Throughout the codebase, sensitive values are accessed exclusively via `process.env.VAR_NAME`. This pattern ensures that secrets are never hardcoded and can be injected by the host environment in production. Key variables include:

- `process.env.CONTINUE_API_KEY`
- `process.env.OPENAI_API_KEY`
- `process.env.ANTHROPIC_API_KEY`
- `process.env.NODE_EXTRA_CA_CERTS`
- `HTTP_PROXY` / `HTTPS_PROXY` (and lowercase variants)

## Configuration Merging Strategy

### Overlaying Secrets onto YAML Configs

Continue supports YAML-based configuration files (e.g., [`continue.yaml`](https://github.com/continuedev/continue/blob/main/continue.yaml)) while keeping secrets separate. The system parses the YAML structure, then overlays environment variables loaded from `.env` files using `dotenv.parse`. This approach allows version-controlled YAML to contain non-sensitive settings while secrets reside in environment-specific files.

The utility helper in [`core/util/paths.ts`](https://github.com/continuedev/continue/blob/main/core/util/paths.ts) provides the parsing mechanism:

```typescript
// core/util/paths.ts – parsing a .env file manually
import * as fs from "fs";
import dotenv from "dotenv";

export const readEnvFile = (filepath: string) => {
  const envContent = fs.readFileSync(filepath, "utf‑8");
  return dotenv.parse(envContent);   // Returns a plain object { VAR: value }
};

```

The configuration loader in [`core/config/yaml/LocalPlatformClient.ts`](https://github.com/continuedev/continue/blob/main/core/config/yaml/LocalPlatformClient.ts) then merges these values:

```typescript
// core/config/yaml/LocalPlatformClient.ts – merging env vars into YAML
import * as yaml from "js-yaml";
import * as fs from "fs";
import * as dotenv from "dotenv";

const yamlContent = fs.readFileSync("continue.yaml", "utf‑8");
const config = yaml.load(yamlContent);
const envVars = dotenv.parse(fs.readFileSync(".env", "utf‑8"));
const merged = { ...config, ...envVars };   // Secrets are now part of the config

```

## Security Safeguards and Access Controls

### Template Documentation with .env.example

The repository ships `.env.example` files in both `packages/continue-sdk/typescript/` and `extensions/cli/` that document the required variables without containing real values. These templates serve as living documentation for developers setting up their local environments.

### Git Ignore Protections

To prevent accidental commits of sensitive files, the repository maintains strict ignore rules. Both `.gitignore` and the dedicated `.continueignore` files explicitly exclude any `.env*` patterns, ensuring that local environment files never enter the version control history.

### Test Isolation Patterns

The test suite implements defensive checks that skip execution when sensitive configuration details are unavailable. Tests verify the presence of `process.env.<KEY>` before running, allowing CI pipelines to pass safely without exposing production secrets in test logs or requiring dummy credentials in repository settings.

## Summary

- **dotenv loading**: Entry points in [`packages/openai-adapters/src/index.ts`](https://github.com/continuedev/continue/blob/main/packages/openai-adapters/src/index.ts) and [`extensions/cli/src/env.ts`](https://github.com/continuedev/continue/blob/main/extensions/cli/src/env.ts) call `dotenv.config()` to enable local `.env` file usage during development.
- **Environment-based access**: All secrets are retrieved via `process.env.VAR_NAME`, including API keys for OpenAI, Anthropic, and Continue-specific services, plus proxy configurations.
- **Configuration merging**: The system parses YAML configs and overlays them with `.env` values using `dotenv.parse`, keeping secrets out of version-controlled configuration files.
- **Repository safety**: `.env.example` templates document required variables, while `.gitignore` and `.continueignore` rules prevent accidental commits of sensitive files.
- **CI compatibility**: Tests check for environment variable presence and skip when secrets are missing, ensuring builds succeed without requiring credential injection in public pipelines.

## Frequently Asked Questions

### Where does Continue load environment variables from?

Continue loads environment variables from the process environment at runtime. During local development, entry points in [`packages/openai-adapters/src/index.ts`](https://github.com/continuedev/continue/blob/main/packages/openai-adapters/src/index.ts) and [`extensions/cli/src/env.ts`](https://github.com/continuedev/continue/blob/main/extensions/cli/src/env.ts) invoke `dotenv.config()` to load values from a local `.env` file into `process.env`. In production deployments, the application expects these variables to be supplied directly by the host environment or container orchestration platform.

### How does Continue prevent API keys from being committed to git?

The repository enforces multiple layers of protection. First, `.env.example` files provide documentation without real values. Second, `.gitignore` and `.continueignore` explicitly exclude all `.env*` files from version control. Finally, the codebase never hardcodes secrets, instead accessing them via `process.env`, ensuring that even if a developer mistakenly tries to commit a key, the standard ignore rules will block the file.

### Can I use a .env file with Continue?

Yes. Continue fully supports `.env` files for local development. The `dotenv` package is integrated into the primary entry points, automatically loading environment variables when the file is present. For custom parsing needs, utilities like `readEnvFile` in [`core/util/paths.ts`](https://github.com/continuedev/continue/blob/main/core/util/paths.ts) provide manual parsing capabilities to merge `.env` values with YAML configurations.

### How does Continue handle missing sensitive configuration in tests?

Tests that require sensitive configuration details check for the presence of the relevant `process.env` variable before executing. If the variable is undefined, the test skips itself gracefully rather than failing. This pattern ensures that continuous integration builds succeed without requiring secret injection, while still allowing developers to run comprehensive test suites locally when they provide their own credentials.