# Troubleshooting gcloud Authentication for kcmd CLI Operations

> Troubleshoot gcloud authentication errors for kcmd CLI operations. Learn how to ensure correct project, region, and ADC configurations for seamless Knowledge Catalog API access.

- Repository: [Google Cloud Platform/knowledge-catalog](https://github.com/GoogleCloudPlatform/knowledge-catalog)
- Tags: how-to-guide
- Published: 2026-07-14

---

**The kcmd CLI delegates all authentication to the Google Cloud SDK, requiring valid output from three specific gcloud commands—project configuration, region configuration, and application-default credentials—before executing any Knowledge Catalog API operations.**

The `kcmd` tool in the [GoogleCloudPlatform/knowledge-catalog](https://github.com/GoogleCloudPlatform/knowledge-catalog) repository implements a "Metadata as Code" workflow that does not embed credential handling. Instead, it shells out to `gcloud` to obtain the project ID, compute region, and OAuth access token required for every API request. When troubleshooting gcloud authentication for kcmd CLI operations, verifying these three configuration values resolves the majority of connectivity issues.

## How kcmd Retrieves Credentials from gcloud

The authentication flow centers on the `ApiContext` class defined in [`toolbox/mdcode/src/libts/gcp/context.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/toolbox/mdcode/src/libts/gcp/context.ts). The static `ApiContext.default()` method (lines 34-44) implements a synchronous validation pipeline:

1. **Project ID**: `child_process.execSync('gcloud -q config get-value project')` (line 34)
2. **Region**: `child_process.execSync('gcloud -q config get-value compute/region')` (line 35)
3. **Access Token**: `child_process.execSync('gcloud -q auth application-default print-access-token')` (line 36)

These values instantiate the `ApiContext` constructor (line 15), which stores them for subsequent API calls. If any command returns an empty string or fails, `default()` throws:

```ts
if (!project || !location || !token) {
  throw new Error('Unable to retrieve project, location, or token. Ensure gcloud is configured.');
}

```

Every kcmd sub-command—`init`, `pull`, `push`, and `status`—invokes this validation via `ApiContext.default()` in [`toolbox/mdcode/src/tool/commands.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/toolbox/mdcode/src/tool/commands.ts) before executing business logic.

## Common Authentication Failure Modes

**Missing gcloud binary** — If `gcloud` is not installed or not on `$PATH`, all three commands fail immediately. Verify installation with `gcloud version`.

**Unset project configuration** — Running `gcloud config get-value project` returns an empty string if no default project is set. Without this value, kcmd cannot construct API request URLs.

**Missing compute region** — The command `gcloud config get-value compute/region` must return a valid region (e.g., `us-central1`). This value maps to the `location` parameter in Knowledge Catalog API calls.

**Expired or missing Application Default Credentials** — The token command `gcloud auth application-default print-access-token` fails if you have not run `gcloud auth application-default login` or if the credentials have expired (default lifetime is approximately one hour).

**Insufficient IAM permissions** — Even with a valid token, the service account associated with your Application Default Credentials requires **Knowledge Catalog Viewer** or **Knowledge Catalog Editor** roles to read or modify catalog entries.

## Step-by-Step Troubleshooting Guide

Follow these validation steps to identify and resolve authentication errors:

1. **Verify the Cloud SDK installation**

   ```bash
   gcloud version
   ```

   Expected output: `Google Cloud SDK 447.0.0` (or similar).

2. **Authenticate with Application Default Credentials**

   ```bash
   gcloud auth application-default login
   ```

   Complete the browser authentication flow. Confirm the message *"Credentials saved to [path]"* appears.

3. **Configure the active project**

   Replace `<PROJECT_ID>` with your Google Cloud project:

   ```bash
   gcloud config set project <PROJECT_ID>
   ```

4. **Set the default compute region**

   Replace `<REGION>` with your target location (e.g., `us-central1`):

   ```bash
   gcloud config set compute/region <REGION>
   ```

5. **Validate the three required values**

   Run each command individually to ensure they return non-empty strings:

   ```bash
   gcloud -q config get-value project
   gcloud -q config get-value compute/region
   gcloud -q auth application-default print-access-token
   ```

6. **Execute a basic kcmd command**

   ```bash
   kcmd status
   ```

   If this succeeds, the `ApiContext` has acquired valid credentials.

7. **Debug persistent failures**

   - Check for environment variable overrides (`GCLOUD_PROJECT`, `GCLOUD_REGION`) that might conflict with SDK configuration.
   - Ensure corporate proxies or firewalls are not blocking the token endpoint.
   - Enable verbose logging if available to surface the exact `gcloud` stderr output.

## Advanced Authentication Patterns

In CI/CD environments where interactive `gcloud` login is unavailable, or for long-running batch operations, use these programmatic approaches.

### Manual Token Injection

Construct an `ApiContext` directly when you have an access token from an environment variable or secret manager:

```typescript
import { ApiContext } from 'kcmd/gcp/context';

const ctx = new ApiContext(
  'my-project',
  'us-central1',
  process.env.GCLOUD_ACCESS_TOKEN!
);

// Use the context with CatalogManifest or other APIs
const manifest = await CatalogManifest.initWithBigQuery(
  ['my-project.my_dataset'],
  ctx
);

```

This bypasses the `gcloud` command execution in `ApiContext.default()`, allowing kcmd to run in environments without the Cloud SDK installed.

### Programmatic Token Refresh

For operations exceeding the token's one-hour lifetime, explicitly call the `refresh()` method (line 44 in [`context.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/context.ts)) to re-execute the token command:

```typescript
import * as kcmd from 'kcmd';

async function longRunningSync(ctx: kcmd.gcp.ApiContext) {
  for (let i = 0; i < 10; i++) {
    // Refresh token every 45 minutes to prevent expiration
    if (i > 0 && i % 9 === 0) {
      ctx.refresh();
    }

    const snapshot = await kcmd.CatalogSnapshot.fromPath('.', ctx);
    const sync = new kcmd.CatalogSync(catalog, snapshot);
    await sync.pull();

    await new Promise(r => setTimeout(r, 5 * 60 * 1000));
  }
}

```

### Shell Verification Script

Automate pre-flight checks in deployment pipelines:

```bash
#!/usr/bin/env bash
set -euo pipefail

command -v gcloud >/dev/null || { echo "gcloud not found"; exit 1; }

PROJECT=$(gcloud -q config get-value project)
REGION=$(gcloud -q config get-value compute/region)
TOKEN=$(gcloud -q auth application-default print-access-token)

if [[ -z "$PROJECT" || -z "$REGION" || -z "$TOKEN" ]]; then
  echo "Authentication configuration incomplete"
  exit 1
fi

echo "Authenticated to project $PROJECT in region $REGION"

```

## Summary

- **kcmd** relies entirely on `gcloud` for authentication and does not support standalone service account key files.
- The `ApiContext.default()` method in [`toolbox/mdcode/src/libts/gcp/context.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/toolbox/mdcode/src/libts/gcp/context.ts) requires three valid outputs: project ID, compute region, and application-default access token.
- Authentication errors surface when any of the three `gcloud` commands return empty values or exit with errors.
- Resolve issues by verifying the Cloud SDK installation, running `gcloud auth application-default login`, and setting the active project and region.
- For CI/CD pipelines, instantiate `ApiContext` directly with a pre-fetched token to avoid interactive login requirements.

## Frequently Asked Questions

### Why does kcmd require gcloud instead of using service account keys directly?

The kcmd architecture delegates credential management to the Google Cloud SDK to support multiple authentication flows (user accounts, service accounts via impersonation, and Workload Identity) without hardcoding credential file paths. By invoking `gcloud auth application-default print-access-token`, kcmd accepts any credential source that the gcloud CLI recognizes, including temporary tokens from `gcloud auth print-access-token` when running under a service account.

### How long does the authentication token remain valid?

Access tokens obtained via `gcloud auth application-default print-access-token` typically expire after **60 minutes**. Long-running kcmd operations may fail with authentication errors if the execution time exceeds this window. Call `ApiContext.refresh()` (implemented in [`toolbox/mdcode/src/libts/gcp/context.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/toolbox/mdcode/src/libts/gcp/context.ts) line 44) to re-execute the token command and update the context with a new valid token.

### Can I use kcmd in a CI/CD pipeline without interactive login?

Yes, but you must provide the access token through alternative means. In [`toolbox/mdcode/src/libts/gcp/context.ts`](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/toolbox/mdcode/src/libts/gcp/context.ts), the `ApiContext` constructor accepts raw string values for project, location, and token. In CI environments, export the token from your secret manager or Workload Identity provider as an environment variable, then instantiate the context directly: `new ApiContext(project, region, process.env.TOKEN)`. This bypasses the `gcloud` command requirement entirely.

### What IAM roles are required for kcmd operations?

The service account associated with your Application Default Credentials requires **Knowledge Catalog Viewer** (`roles/datacatalog.viewer`) for read-only operations like `pull` and `status`, or **Knowledge Catalog Editor** (`roles/datacatalog.editor`) for write operations like `push`. Verify these roles in the Google Cloud Console IAM section if you receive "permission denied" errors despite having a valid token.