Configuration Management with Dynaconf¶
The pan-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 easily switch between different SCM environments.
Multi-Tenant Context Management (Recommended)¶
The CLI supports managing multiple SCM tenant configurations through contexts. This is the recommended approach for users who work with multiple SCM environments.
Context Commands¶
# List all contexts
scm context list
# Create a new context (interactive)
scm context create production
# 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
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
.
Example: Managing Multiple Tenants¶
Let me demonstrate a real workflow with multiple tenants:
# Create context for US production environment
$ scm context create prod-us \
--client-id "us-prod@111111111.iam.panserviceaccount.com" \
--client-secret "us-prod-secret" \
--tsg-id "111111111" \
--log-level WARNING
✓ Context 'prod-us' created successfully
# Create context for EU production environment
$ scm context create prod-eu \
--client-id "eu-prod@222222222.iam.panserviceaccount.com" \
--client-secret "eu-prod-secret" \
--tsg-id "222222222" \
--log-level WARNING
✓ Context 'prod-eu' created successfully
# Create development context with debug logging
$ scm context create dev \
--client-id "dev@333333333.iam.panserviceaccount.com" \
--client-secret "dev-secret" \
--tsg-id "333333333" \
--log-level DEBUG
✓ Context 'dev' created successfully
# List all available 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 │
└──────────┴─────────┴────────────────────────────────────────────────────┘
# Show details of a specific context
$ 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)
# Test authentication without switching 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)
# Current context remains unchanged
$ scm context current
Current context: prod-us
Client ID: us-prod@111111111.iam.panserviceaccount.com
TSG ID: 111111111
# Switch to development context
$ scm context use dev
✓ Switched to context 'dev'
Client ID: dev@333333333.iam.panserviceaccount.com
TSG ID: 333333333
# Now all commands use the dev context with DEBUG logging
$ 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':
...
# Switch to EU production for operations
$ scm context use prod-eu
✓ Switched to context 'prod-eu'
# Delete a context that's no longer needed
$ scm context delete old-tenant
Are you sure you want to delete context 'old-tenant'? [y/N]: y
✓ Context 'old-tenant' deleted
Configuration Sources¶
The CLI uses the following configuration sources in order of precedence:
1. Current Context (Highest Priority for File-based Config)¶
When you use scm context use <name>
, that context's configuration takes precedence:
# ~/.scm-cli/contexts/production.yaml
client_id: "prod-app@987654321.iam.panserviceaccount.com"
client_secret: "production-secret-key"
tsg_id: "987654321"
log_level: "WARNING"
2. Environment Variables (Override Contexts for CI/CD)¶
Environment variables can override context settings, useful for CI/CD pipelines:
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"
Backward Compatibility
The CLI supports both new and legacy environment variable patterns:
- New:
SCM_CLIENT_ID
,SCM_CLIENT_SECRET
,SCM_TSG_ID
- Legacy:
SCM_SCM_CLIENT_ID
,SCM_SCM_CLIENT_SECRET
,SCM_SCM_TSG_ID
3. Default Settings (Lowest Priority)¶
The settings.yaml
file contains default application settings:
---
default:
# Logging configuration
log_level: "INFO"
production:
# Production-specific settings
log_level: "WARNING"
Legacy Configuration Files No Longer Supported
The following configuration methods are no longer supported as of version 0.4.0:
~/.scm-cli/config.yaml
- Migrate to contexts usingscm context create
.secrets.yaml
- Use contexts for development credentials
These files will be ignored if present. Please migrate to the context system for better multi-tenant support.
Configuration Precedence¶
When multiple sources define the same setting, the CLI follows this precedence (highest to lowest):
- Current context configuration (
~/.scm-cli/contexts/<current>.yaml
) - Environment variables (when set, they override context values)
settings.yaml
(defaults)
Context-First Design
The CLI prioritizes contexts to support multi-tenant workflows. Environment variables can still override specific settings when needed for automation or CI/CD.
Authentication Configuration¶
The CLI requires three credentials for SCM API authentication:
Setting | Environment Variable | Description |
---|---|---|
client_id | SCM_CLIENT_ID | Service account client ID |
client_secret | SCM_CLIENT_SECRET | Service account client secret |
tsg_id | SCM_TSG_ID | Tenant Service Group ID |
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
Authentication Fallback¶
If no credentials are configured, the CLI automatically enters mock mode:
Available Settings¶
Used Settings¶
Setting | Default | Environment Variable | Usage |
---|---|---|---|
log_level | "INFO" | SCM_LOG_LEVEL | Controls SDK client logging verbosity |
client_id | None | SCM_CLIENT_ID | SCM API authentication |
client_secret | None | SCM_CLIENT_SECRET | SCM API authentication |
tsg_id | None | SCM_TSG_ID | SCM API tenant identification |
Unused Settings¶
The following settings are defined in settings.yaml
but not currently used by the CLI:
Setting | Default | Purpose |
---|---|---|
app_name | "pan-scm-cli" | Application identifier (reserved for future use) |
environment | "development" | Environment mode (reserved for future use) |
debug | true /false | Debug mode flag (reserved for future use) |
Configuration Examples¶
Example 1: Multi-Tenant Setup with Contexts¶
# Create contexts for different environments
scm context create production \
--client-id "prod-app@987654321.iam.panserviceaccount.com" \
--client-secret "production-secret-key" \
--tsg-id "987654321" \
--log-level WARNING
scm context create development \
--client-id "dev-app@123456789.iam.panserviceaccount.com" \
--client-secret "dev-secret-key" \
--tsg-id "123456789" \
--log-level DEBUG
# Switch between environments
scm context use production
scm show object address --folder Texas
scm context use development
scm show object address --folder DevFolder
Example 2: 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
Example 3: 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
Debugging Configuration¶
To see which configuration values are being loaded:
# In Python
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."""
# Start with only the base settings file
settings_files = ["settings.yaml"]
# Add current context file FIRST so it has priority
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."""
# Check settings (includes env vars and config files)
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¶
- Use contexts for managing multiple SCM tenants - this is the recommended approach
- Use environment variables only for CI/CD pipelines and automation
- Never commit secrets to version control
- Set appropriate log levels for different environments (INFO for general use, WARNING for production)
- Test with mock mode before using real credentials
- Use context test to verify authentication without switching contexts
- Name contexts meaningfully (e.g., production, staging, dev-tenant1)
Troubleshooting¶
Configuration Not Loading¶
- Check environment variable names (must start with
SCM_
) - Verify file paths and permissions
- Ensure YAML syntax is correct
- Use
settings.reload()
to force reload configuration
Credential Issues¶
- Verify all three credentials are set (client_id, client_secret, tsg_id)
- Check for typos in environment variable names
- Ensure credentials have proper SCM permissions
- Test with mock mode to isolate authentication issues