GC-301f · Module 1

API Key Management

3 min read

API credentials in Gemini CLI tools follow one rule: never in code, always in environment. Every key, token, and secret flows through environment variables that the MCP server process inherits from the shell. The settings.json env block maps variable names to ${VAR} references that resolve at server startup. If a variable is missing, the tool should fail fast with a clear message naming the missing variable — not make an unauthenticated request that returns a cryptic 401.

Credential storage splits by context. Local development uses .env files loaded by direnv or dotenv — never committed to version control. CI/CD pipelines use encrypted secrets from GitHub Actions, GitLab CI, or your platform's secrets manager. Production MCP servers pull credentials from vault services like HashiCorp Vault, AWS Secrets Manager, or 1Password CLI. The storage mechanism changes. The access pattern — environment variable at process start — stays constant.

Key rotation requires zero-downtime transitions. When rotating an API key, support both old and new keys simultaneously during a transition window. Set the new key in your secrets manager, deploy the updated environment, verify the new key works, then revoke the old one. For MCP servers, this means restarting the Gemini CLI session to pick up new environment values. Automate rotation reminders — a key that has not been rotated in 90 days is a key waiting to be compromised.

function requireEnv(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(
      `Missing required environment variable: ${name}. ` +
      `Set it in your shell or .env file before starting the MCP server.`
    );
  }
  return value;
}

// Validate all credentials at server startup, not first use
function validateCredentials() {
  const creds = {
    apiKey: requireEnv("API_KEY"),
    dbUrl: requireEnv("DATABASE_URL"),
    ghToken: requireEnv("GITHUB_TOKEN"),
  };

  // Optional: verify credentials are valid with a lightweight call
  // e.g., GET /api/me to confirm the API key works
  return creds;
}