Skip to content

Authentication

!!! warning "The CLI needs an agent-backed key" Every canviq command that talks to your workspace (survey, question, trigger, mcp configure) calls the MCP tools API, which only accepts a key created from the Agent Management page (/admin/settings/agents). An SDK key or a key created through the generic Settings → API Keys wizard (even one where you picked "MCP" as the type) looks identical, starts with the same pk_live_/pk_test_ prefix, and will still fail every CLI command with a 401. See Getting an agent-backed key below.

Commands

canviq auth login

Prompts for your API key and stores it in the OS keychain.

canviq auth login
# Enter your Canviq pk_live_* API key: ...

canviq auth login --env test
# Enter your Canviq pk_test_* API key: ...

Options

Flag Default Description
--env <live\|test> live Environment for the key being stored

Don't have an agent-backed key yet? See Getting an agent-backed key below. The Settings → API Keys page creates REST and SDK keys, not the kind the CLI needs.

Live keys start with pk_live_. Test keys start with pk_test_. The CLI validates the prefix and rejects keys for the wrong environment. The prefix does not tell you whether a key is agent-backed, SDK, or REST; all three key types share it.

Getting an agent-backed key

  1. In your Canviq dashboard, go to Settings → Agents (/admin/settings/agents).
  2. Create an agent (or open one you already created).
  3. On the agent's own page, click Generate key and choose an environment.
  4. Copy the key. It's shown once. This is the value canviq auth login or CANVIQ_API_KEY expects.

A key generated anywhere else, the SDK page, or the "MCP" option in the generic API Keys wizard, is not linked to an agent and will be rejected by every canviq command with a 401, no matter how it was scoped. See AI Agents → Authentication → Key types for why the wizard's "MCP" option doesn't produce a working key.

auth login accepts the global --quiet/--json flags without erroring, but ignores them: it always prompts interactively. There is no non-interactive form of auth login; use CANVIQ_API_KEY instead for CI and containers. See Scripting and CI for the full global-flags contract.

canviq auth logout

Removes stored API keys and clears the session token.

canviq auth logout

canviq auth status

Prints the current authentication state.

canviq auth status
# Environment: live
# API key:     pk_live_abc123...
# Source:      keychain
# Base URL:    https://canviq.app

The Source field shows where the credential came from. See Credential precedence below.

Credential precedence

The CLI resolves credentials in this order. The first match wins.

  1. CANVIQ_API_KEY environment variable
  2. OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
  3. ~/.canviq/config.json (permissions 0600, fallback when no keychain is available)

!!! warning "Plaintext fallback" When no OS keychain backend is available, the CLI falls back to ~/.canviq/config.json. It sets permissions to 0600, but the file is still readable by AI coding agents that scan ~/.config and ~/.*. Use the keychain when available.

Environment variable

CANVIQ_API_KEY overrides any stored credential. Set it in CI, containers, or anywhere interactive login is not practical.

export CANVIQ_API_KEY=pk_live_...
canviq survey list

CANVIQ_BASE_URL overrides the default base URL. Use it when developing against a local instance or a non-production environment.

export CANVIQ_BASE_URL=http://localhost:3000
canviq auth status

CI/CD pattern

Set CANVIQ_API_KEY as a repository secret. No interactive login is needed.

# .github/workflows/pmf-check.yml
env:
  CANVIQ_API_KEY: ${{ secrets.CANVIQ_API_KEY }}

steps:
  - run: canviq survey pmf-score ${{ env.SURVEY_ID }} --json

The CLI auto-detects non-TTY environments and outputs JSON without needing --json. See Scripting for more patterns.

Session token caching

After the first survey, question, or trigger command authenticates with your pk_* API key, the server hands back a short-lived session token. The CLI caches it at ~/.canviq/session.json so the next command can skip full key verification. This is the only authoritative page for this behavior; other pages link back here rather than repeat it.

What's stored:

{
  "token": "mcp_sess_...",
  "keyFingerprint": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde",
  "expiresAt": 1751654321000
}
  • token, the session token itself. Short-lived and scoped to one workspace, not a long-term credential.
  • keyFingerprint, a SHA-256 digest of the pk_* API key that earned the token. The raw key is never written to this file, only its digest.
  • expiresAt, an absolute expiry timestamp.

TTL. Cached tokens are valid for 15 minutes. After that, the next command re-authenticates with your pk_* key and caches a fresh token.

Key-bound. A cached token is only reused when the presented key's fingerprint matches the one that earned it. If you switch CANVIQ_API_KEY on the same machine (a shared CI runner, a different agent, a rotated key), the CLI detects the mismatch and re-authenticates with the new key rather than riding the old session.

Transparent fallback on revocation. If a cached token is ever rejected (401/403, for example after a key rotation or an agent suspension), the CLI clears the stale entry and retries once with your pk_* key automatically. You won't see an error unless the pk_* key itself is no longer valid.

Cleared by auth logout. Running canviq auth logout removes both your stored API keys and this cache in one step.

The cache is a performance optimization only. Deleting ~/.canviq/session.json by hand is safe: the next command simply re-authenticates and writes a new one.