Skip to main content

Configuration Management

The scm CLI uses Dynaconf for flexible configuration management, supporting multiple configuration sources with clear precedence rules. The CLI also supports multi-tenant authentication through context management, allowing you to switch between different SCM environments.

Overview

This guide explains how to configure the CLI for your environment:

  • Manage multiple SCM tenants with context-based authentication
  • Configure environment variables for CI/CD pipelines
  • Understand configuration precedence across sources
  • Debug and troubleshoot configuration issues

Prerequisites

Before configuring the CLI, ensure you have:

  • The scm CLI installed (see Getting Started)
  • Service account credentials for at least one SCM tenant
  • Access to create files in ~/.scm-cli/ (for context storage)

Core Concepts

Configuration Precedence

When multiple sources define the same setting, the CLI follows this precedence (highest to lowest):

  1. Environment variables (when set, they override everything)
  2. Current context configuration (~/.scm-cli/contexts/<current>.yaml)
  3. settings.yaml defaults
info

The CLI prioritizes contexts to support multi-tenant workflows. Environment variables can still override specific settings when needed for automation or CI/CD.

Authentication Credentials

The CLI requires three credentials for SCM API authentication:

SettingEnvironment VariableDescription
client_idSCM_CLIENT_IDService account client ID
client_secretSCM_CLIENT_SECRETService account client secret
tsg_idSCM_TSG_IDTenant Service Group ID

API Endpoint Overrides

By default the SDK talks to the production SCM endpoints. Both can be overridden per context or via environment variables (env wins over context; when unset, the SDK defaults apply):

SettingEnvironment VariableDescription
api_base_urlSCM_API_BASE_URLOverride the SCM API base URL
token_urlSCM_TOKEN_URLOverride the OAuth2 token URL
# Persist per context
$ scm context create fedramp \
--client-id "fed@333333333.iam.panserviceaccount.com" \
--client-secret "fed-secret" \
--tsg-id "333333333" \
--api-base-url "https://api.example.paloaltonetworks.com" \
--token-url "https://auth.example.paloaltonetworks.com/am/oauth2/access_token"

# Or override for a one-off command
SCM_API_BASE_URL="https://api.example.paloaltonetworks.com" scm context test

Missing Credentials

If no credentials are configured, commands fail with a clear error (exit code 1) and remediation steps — the CLI never silently falls back to mock data:

$ scm show object address --folder Shared

❌ Authentication not configured: Missing required authentication parameters: client_id, client_secret, tsg_id

To fix this issue:
1. Create a context: scm context create <name> --client-id <id> --client-secret <secret> --tsg-id <tsg>
2. Switch context: scm context use <name>
3. Or use environment variables: SCM_CLIENT_ID, SCM_CLIENT_SECRET, SCM_TSG_ID

Mock Mode

To test commands without credentials or API calls, opt in explicitly with the SCM_MOCK environment variable (or the --mock flag on scm context test):

$ SCM_MOCK=1 scm show object address --folder Shared

Examples

Multi-Tenant Setup with Contexts

Creating Contexts

$ scm context create prod-us \
--client-id "us-prod@111111111.iam.panserviceaccount.com" \
--client-secret "us-prod-secret" \
--tsg-id "111111111" \
--log-level WARNING
---> 100%
✓ Context 'prod-us' created successfully
$ scm context create prod-eu \
--client-id "eu-prod@222222222.iam.panserviceaccount.com" \
--client-secret "eu-prod-secret" \
--tsg-id "222222222" \
--log-level WARNING
---> 100%
✓ Context 'prod-eu' created successfully
$ scm context create dev \
--client-id "dev@333333333.iam.panserviceaccount.com" \
--client-secret "dev-secret" \
--tsg-id "333333333" \
--log-level DEBUG
---> 100%
✓ Context 'dev' created successfully

Listing and Inspecting Contexts

$ scm context list
SCM Authentication Contexts
┏━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Context ┃ Current ┃ Client ID ┃
┡━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ prod-us │ ✓ │ us-prod@11...@111111111.iam.panserviceaccount.com │
│ prod-eu │ │ eu-prod@22...@222222222.iam.panserviceaccount.com │
│ dev │ │ dev@333333...@333333333.iam.panserviceaccount.com │
└──────────┴─────────┴────────────────────────────────────────────────────┘
$ scm context show prod-eu
Context: prod-eu

Configuration:
Client ID: eu-prod@222222222.iam.panserviceaccount.com
TSG ID: 222222222
Log Level: WARNING
Client Secret: ***** (configured)

Switching and Testing Contexts

$ scm context test prod-eu
Testing authentication for context: prod-eu
✓ Authentication successful!
Client ID: eu-prod@222222222.iam.panserviceaccount.com
TSG ID: 222222222
✓ API connectivity verified (found 187 address objects in Shared folder)
$ scm context use dev
---> 100%
✓ Switched to context 'dev'

Client ID: dev@333333333.iam.panserviceaccount.com
TSG ID: 333333333

Using Commands with Active Context

$ scm show object address --folder Development
[INFO] Using authentication context: dev
DEBUG:scm_cli.utils.sdk_client:Listing addresses in folder='Development'
Addresses in folder 'Development':
...

Deleting a Context

$ scm context delete old-tenant
Are you sure you want to delete context 'old-tenant'? [y/N]: y
✓ Context 'old-tenant' deleted

Context Commands Reference

# List all contexts
scm context list

# Create a new context (non-interactive)
scm context create staging \
--client-id "staging@123456.iam.panserviceaccount.com" \
--client-secret "your-secret" \
--tsg-id "123456" \
--log-level INFO

# Switch to a different context
scm context use production

# Show current context
scm context current

# Show details of a specific context
scm context show staging

# Delete a context
scm context delete old-tenant

# Test authentication for a specific context
scm context test production
scm context test staging --mock

# Test current context
scm context test

Token Cache

OAuth tokens are cached per context in ~/.scm-cli/cache/ (file mode 0600) and reused until shortly before expiry, so consecutive commands skip the token and signing-key roundtrips. The cache is invalidated automatically when the API rejects a cached token or when the cached credentials no longer match the active context.

# Disable the token cache entirely
export SCM_NO_TOKEN_CACHE=1

# Clear it manually
rm -rf ~/.scm-cli/cache

Bulk Load Concurrency

scm load ... commands apply objects concurrently (default 5 workers). Position-sensitive types (security/NAT/PBF/QoS rules) always load sequentially to preserve rule order.

# Tune or serialize bulk loads
export SCM_BULK_WORKERS=1

Context Storage

Contexts are stored in ~/.scm-cli/contexts/ as individual YAML files:

---
# ~/.scm-cli/contexts/production.yaml
client_id: "prod-app@987654321.iam.panserviceaccount.com"
client_secret: "production-secret-key"
tsg_id: "987654321"
log_level: "WARNING"

The current active context is tracked in ~/.scm-cli/current-context.

CI/CD Setup with Environment Variables

# Set credentials for automated workflows
export SCM_CLIENT_ID="ci-app@555555555.iam.panserviceaccount.com"
export SCM_CLIENT_SECRET="ci-secret-key"
export SCM_TSG_ID="555555555"
export SCM_LOG_LEVEL="WARNING"

# Run commands in CI pipeline
scm context test
scm load object address --file addresses.yaml --folder Production
tip

The CLI supports both new and legacy environment variable patterns: new (SCM_CLIENT_ID) and legacy (SCM_SCM_CLIENT_ID).

Context with Environment Variable Override

# Use a context as base configuration
scm context use staging

# Override specific settings for a one-off command
SCM_LOG_LEVEL=DEBUG scm show object address --folder Texas

Switching Between Environments

# Switch between environments
scm context use production
scm show object address --folder Texas

scm context use development
scm show object address --folder DevFolder

Configuration Sources

Current Context

When you use scm context use <name>, that context's configuration takes effect:

---
# ~/.scm-cli/contexts/production.yaml
client_id: "prod-app@987654321.iam.panserviceaccount.com"
client_secret: "production-secret-key"
tsg_id: "987654321"
log_level: "WARNING"

Environment Variables

Environment variables can override context settings:

export SCM_CLIENT_ID="your-client-id@1234567890.iam.panserviceaccount.com"
export SCM_CLIENT_SECRET="your-client-secret"
export SCM_TSG_ID="1234567890"
export SCM_LOG_LEVEL="DEBUG"

Default Settings

The settings.yaml file contains default application settings:

---
default:
log_level: "WARNING"

production:
log_level: "WARNING"
warning

The following legacy configuration methods are no longer supported as of version 0.4.0: ~/.scm-cli/config.yaml and .secrets.yaml. Migrate to contexts using scm context create.

Available Settings

Active Settings

SettingDefaultEnvironment VariableDescription
log_level"WARNING"SCM_LOG_LEVELControls logging verbosity (CRITICAL, ERROR, WARNING, INFO, DEBUG)
client_idNoneSCM_CLIENT_IDSCM API authentication
client_secretNoneSCM_CLIENT_SECRETSCM API authentication
tsg_idNoneSCM_TSG_IDSCM API tenant identification
api_base_urlSDK defaultSCM_API_BASE_URLOverride the SCM API base URL
token_urlSDK defaultSCM_TOKEN_URLOverride the OAuth2 token URL

Reserved Settings

SettingDefaultDescription
app_name"pan-scm-cli"Application identifier (reserved for future use)
environment"development"Environment mode (reserved for future use)
debugtrue/falseDebug mode flag (reserved for future use)

Testing Authentication

You can test authentication in several ways:

# Test using current context
scm context test

# Test a specific context without switching
scm context test production

# Test in mock mode (no API calls)
scm context test --mock
scm context test staging --mock

Debugging

The --debug Flag

Pass the global --debug flag to any command for full diagnostics:

scm --debug show object address --folder Texas

--debug enables DEBUG-level logging (including the SDK's OAuth/auth loggers, which are silenced at every other level) and prints full tracebacks on unexpected errors instead of one-line messages.

Log Levels

Logging is configured once at CLI startup with this precedence:

  1. --debug flag (forces DEBUG)
  2. SCM_LOG_LEVEL environment variable
  3. log_level in the active context or settings.yaml
  4. Default: WARNING

Valid levels: CRITICAL, ERROR, WARNING, INFO, DEBUG. An invalid value produces a warning and falls back to WARNING.

Debugging Configuration

To see which configuration values are being loaded:

from scm_cli.utils.config import settings

print(f"Client ID: {settings.get('client_id', 'NOT SET')}")
print(f"Log Level: {settings.get('log_level', 'NOT SET')}")

Technical Implementation

Context-Aware Dynaconf Initialization

The CLI initializes Dynaconf with context awareness in src/scm_cli/utils/context.py:

def get_context_aware_settings() -> Dynaconf:
"""Get Dynaconf settings with context awareness."""
settings_files = ["settings.yaml"]

current_context = get_current_context()
if current_context:
context_file = os.path.join(CONTEXT_DIR, f"{current_context}.yaml")
if os.path.exists(context_file):
settings_files.insert(0, context_file)

return Dynaconf(
envvar_prefix="SCM",
settings_files=settings_files,
load_dotenv=True,
environments=False,
merge_enabled=True,
)

Key configuration options:

  • envvar_prefix="SCM": Environment variables must start with SCM_
  • Context file loaded first for highest file-based priority
  • load_dotenv=True: Loads .env files if present
  • environments=False: Disables Dynaconf's environment switching
  • merge_enabled=True: Merges configurations from all sources

Configuration Access Pattern

The CLI uses a centralized get_auth_config() function to retrieve credentials:

def get_auth_config():
"""Get authentication configuration from various sources."""
client_id = settings.get("client_id") or settings.get("scm_client_id")
client_secret = settings.get("client_secret") or settings.get("scm_client_secret")
tsg_id = settings.get("tsg_id") or settings.get("scm_tsg_id")

return client_id, client_secret, tsg_id

Best Practices

  1. Use contexts for multi-tenant management: Contexts are the recommended approach for managing multiple SCM tenants.
  2. Reserve environment variables for CI/CD: Use environment variables only for automation pipelines.
  3. Never commit secrets to version control: Keep credentials in contexts or environment variables, never in code.
  4. Set appropriate log levels: Use INFO for general use, WARNING for production, DEBUG for troubleshooting.
  5. Test with mock mode first: Use SCM_MOCK=1 (or scm context test --mock) to validate commands before using real credentials.
  6. Use context test to verify authentication: Test connectivity without switching contexts by specifying the context name.
  7. Name contexts meaningfully: Use descriptive names like production, staging, or dev-tenant1.

Troubleshooting

Configuration Not Loading

  1. Check environment variable names (must start with SCM_)
  2. Verify file paths and permissions for context files
  3. Ensure YAML syntax is correct in context files
  4. Use settings.reload() to force reload configuration

Credential Issues

  1. Verify all three credentials are set (client_id, client_secret, tsg_id)
  2. Check for typos in environment variable names
  3. Ensure credentials have proper SCM permissions
  4. Test with mock mode to isolate authentication issues

Next Steps