API Keys & Bearer Tokens

Overview

API keys are opaque strings that identify and authenticate a client. Unlike OAuth2, there is no token exchange — the key is sent directly with every request. Unlike Basic Auth, there is no username/password pair — just a single secret.

The term "bearer token" means anyone who possesses the token can use it. There is no cryptographic proof of identity — if the token leaks, anyone can impersonate you.

Header-Based Keys

Authorization: Bearer

The most common pattern. The token goes in the Authorization header:

curl -s \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Accept: application/json" \
  https://api.example.com/v1/resources

Used by: GitHub, GitLab, Cloudflare, Stripe, most modern APIs.

Custom Headers

Some APIs use a vendor-specific header:

# X-API-Key pattern
curl -s \
  -H "X-API-Key: ${API_KEY}" \
  -H "Accept: application/json" \
  https://api.example.com/v1/resources

# X-Auth-Token pattern (OpenStack)
curl -s \
  -H "X-Auth-Token: ${AUTH_TOKEN}" \
  https://api.example.com/v1/resources

The header name varies by vendor. Check the API documentation — there is no universal standard for custom headers.

Query Parameter Keys

Some APIs accept the key as a URL parameter:

curl -s "https://api.example.com/v1/resources?api_key=${API_KEY}"

Query parameter keys appear in:

  • Server access logs

  • Browser history

  • Proxy logs

  • Referrer headers

Avoid this pattern when possible. Use header-based authentication instead. When forced to use query parameters, ensure the key has minimal permissions.

Personal Access Tokens

Personal access tokens (PATs) are API keys scoped to a user account. They replace password-based authentication for API access.

GitHub

# Create a PAT at: https://github.com/settings/tokens

# List repositories
curl -s \
  -H "Authorization: Bearer ${GITHUB_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/user/repos

# With the gh CLI (reads from GITHUB_TOKEN automatically)
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
gh repo list

GitLab

# Create a PAT at: https://gitlab.example.com/-/user_settings/personal_access_tokens

# List projects
curl -s \
  -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
  https://gitlab.example.com/api/v4/projects

Note that GitLab uses PRIVATE-TOKEN as the header name, not Authorization: Bearer.

Cloudflare

# API Token (scoped, preferred)
curl -s \
  -H "Authorization: Bearer ${CF_API_TOKEN}" \
  https://api.cloudflare.com/client/v4/zones

# Global API Key (legacy, full access)
curl -s \
  -H "X-Auth-Email: user@example.com" \
  -H "X-Auth-Key: ${CF_API_KEY}" \
  https://api.cloudflare.com/client/v4/zones

Security Considerations

  • Treat API keys as passwords. They grant access without further authentication.

  • Scope keys minimally. Most platforms allow read-only, repo-specific, or resource-limited tokens.

  • Set expiration dates. A key without expiry is a key waiting to be forgotten and abused.

  • Rotate on schedule. Even unexposed keys should be rotated (90 days is a reasonable cadence).

  • Never commit keys to git. Use dsec, environment variables, or a vault.

Key Rotation Pattern

# 1. Generate new key in the provider's UI or API
# 2. Update dsec
dsec edit d000 dev/network
# Replace the old key value with the new one

# 3. Verify the new key works
dsource d000 dev/network
curl -s -H "Authorization: Bearer ${API_TOKEN}" \
  https://api.example.com/v1/health

# 4. Revoke the old key in the provider's UI

dsec Pattern

Store API keys in an encrypted environment file:

dsec edit d000 dev/network

Inside the encrypted file:

GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
CF_API_TOKEN=xxxxxxxxxxxxxxxxxxxx
STRIPE_API_KEY=sk_test_xxxxxxxxxxxxxxxxxxxx

Load before use:

dsource d000 dev/network

# All tokens are now in environment
gh repo list
netapi github repos list

dsunsource

netapi Pattern

netapi detects the token type from the vendor configuration:

# Bearer token (default for most vendors)
netapi --auth token github repos list

# Custom header name (auto-detected per vendor)
netapi --auth token gitlab projects list

# Explicit flags
netapi --auth token --bearer "${API_TOKEN}" cloudflare zones list

Environment Variables

Variable Purpose

NETAPI_API_TOKEN

Generic bearer token (any vendor)

GITHUB_TOKEN

GitHub personal access token

GITLAB_TOKEN

GitLab personal access token

CF_API_TOKEN

Cloudflare API token

NETAPI_API_KEY_HEADER

Override the header name (default: Authorization)

Vendor-specific variables are resolved first. If GITHUB_TOKEN is set, netapi uses it for GitHub commands without requiring --bearer.