Configuration Management Tutorial#
This tutorial covers managing scafctl’s application configuration using the config CLI commands.
Overview#
scafctl uses a YAML configuration file to control application behavior including logging, HTTP client settings, resolver timeouts, catalog locations, and more.
| Command | Description |
|---|---|
config init | Create config file |
config view | View current config |
config get/set | Read/write values |
config validate | Validate config |
config schema | View JSON schema |
config paths | Show XDG paths |
Quick Start#
1. Initialize Configuration#
Create a new config file:
# Create minimal config
scafctl config init
# Create with all options documented
scafctl config init --full
# Preview without writing
scafctl config init --dry-run
# Write to custom path
scafctl config init --output ./my-config.yaml# Create minimal config
scafctl config init
# Create with all options documented
scafctl config init --full
# Preview without writing
scafctl config init --dry-run
# Write to custom path
scafctl config init --output ./my-config.yaml2. View Configuration#
See the current effective configuration:
# Full config (YAML format)
scafctl config view
# As JSON
scafctl config view -o json
# Filter with CEL expression
scafctl config view -e '_.settings'
# Interactive TUI explorer
scafctl config view -i# Full config (YAML format)
scafctl config view
# As JSON
scafctl config view -o json
# Filter with CEL expression
scafctl config view -e '_.settings'
# Interactive TUI explorer
scafctl config view -i3. Show Config Sources#
See where each value comes from (file, environment, default):
scafctl config showscafctl config showGetting and Setting Values#
Read Values#
Use dot notation to read specific config values:
# Get logging level
scafctl config get logging.level
# Get default catalog
scafctl config get settings.defaultCatalog
# Get HTTP timeout
scafctl config get httpClient.timeout# Get logging level
scafctl config get logging.level
# Get default catalog
scafctl config get settings.defaultCatalog
# Get HTTP timeout
scafctl config get httpClient.timeoutWrite Values#
# Set logging level
scafctl config set logging.level debug
# Set HTTP timeout
scafctl config set httpClient.timeout 60s
# Set resolver concurrency
scafctl config set resolver.concurrency 8
# Enable a boolean
scafctl config set httpClient.caching.enabled true# Set logging level
scafctl config set logging.level debug
# Set HTTP timeout
scafctl config set httpClient.timeout 60s
# Set resolver concurrency
scafctl config set resolver.concurrency 8
# Enable a boolean
scafctl config set httpClient.caching.enabled trueReset to Default#
# Reset a value to its default
scafctl config unset logging.level
# Reset HTTP configuration
scafctl config unset httpClient.timeout# Reset a value to its default
scafctl config unset logging.level
# Reset HTTP configuration
scafctl config unset httpClient.timeoutManaging Catalogs#
Add a Catalog#
# Add a local filesystem catalog
scafctl catalog remote add my-catalog --type filesystem --path ~/my-solutions
# Add an OCI registry catalog
scafctl catalog remote add company --type oci --url oci://ghcr.io/myorg/scafctl-catalog
# Add and set as default
scafctl catalog remote add primary --type filesystem --path ~/catalogs/main --default
# Add with auth provider for automatic token injection
scafctl catalog remote add corp --type oci --url oci://registry.example.com/artifacts --auth-provider github# Add a local filesystem catalog
scafctl catalog remote add my-catalog --type filesystem --path ~/my-solutions
# Add an OCI registry catalog
scafctl catalog remote add company --type oci --url oci://ghcr.io/myorg/scafctl-catalog
# Add and set as default
scafctl catalog remote add primary --type filesystem --path ~/catalogs/main --default
# Add with auth provider for automatic token injection
scafctl catalog remote add corp --type oci --url oci://registry.example.com/artifacts --auth-provider githubRemove a Catalog#
scafctl catalog remote remove my-catalogscafctl catalog remote remove my-catalogSet Default Catalog#
scafctl catalog remote default my-catalogscafctl catalog remote default my-catalogValidation#
Validate Config File#
# Validate current config
scafctl config validate
# Validate a specific file
scafctl config validate path/to/config.yaml# Validate current config
scafctl config validate
# Validate a specific file
scafctl config validate path/to/config.yamlView Config Schema#
# Pretty-printed JSON Schema
scafctl config schema
# Minified (for piping)
scafctl config schema --compact# Pretty-printed JSON Schema
scafctl config schema
# Minified (for piping)
scafctl config schema --compactView System Paths#
See where scafctl stores files on your system:
# Show all XDG paths
scafctl config paths
# As JSON
scafctl config paths -o json
# Show paths for a different platform
scafctl config paths --platform linux# Show all XDG paths
scafctl config paths
# As JSON
scafctl config paths -o json
# Show paths for a different platform
scafctl config paths --platform linuxTypical output:
💡 scafctl Paths
Platform: darwin/arm64
Config: ~/.config/scafctl/config.yaml
Secrets: ~/.local/share/scafctl/secrets
Data: ~/.local/share/scafctl
Catalog: ~/.local/share/scafctl/catalog
Cache: ~/.cache/scafctl
HTTP Cache: ~/.cache/scafctl/http-cache
State: ~/.local/state/scafctl
Override paths with XDG environment variables or SCAFCTL_SECRETS_DIR.
💡 Config sources (merge order)
1. built-in defaults
2. ~/.config/scafctl/config.d/10-telemetry.yaml
3. ~/.config/scafctl/config.d/50-clusters.yaml
4. ~/.config/scafctl/config.yaml
5. SCAFCTL_* environment variables
Later sources override earlier ones.The Config sources section lists every layer that feeds the merged
configuration, in the order they are applied. Later sources override earlier
ones, so a value in config.d/50-clusters.yaml wins over one in
10-telemetry.yaml, and your config.yaml wins over both. This makes the
config.d/ drop-in directory discoverable – otherwise it is easy to miss where
a value like kube.clusters is actually set. A missing user config file is
shown as (not present).
Configuration Reference#
Key Settings#
| Key | Type | Default | Description |
|---|---|---|---|
logging.level | string | none | Log level: none, error, warn, info, debug, trace, or numeric V-level |
logging.format | string | console | Log format: console (colored), json (structured) |
settings.defaultCatalog | string | local | Default catalog name |
httpClient.timeout | duration | 30s | HTTP request timeout |
httpClient.retry.maxRetries | int | 3 | Max HTTP retries |
httpClient.caching.enabled | bool | true | Enable HTTP response caching |
httpClient.maxResponseBodySize | int | 104857600 | Max HTTP response body size (bytes, default 100 MB) |
httpClient.allowPrivateIPs | bool | false | Allow requests to private/loopback IPs (SSRF protection) |
settings.requireSecureKeyring | bool | false | Fail if OS keyring unavailable instead of insecure fallback |
resolver.timeout | duration | 5m | Overall resolver timeout |
resolver.concurrency | int | 4 | Max parallel resolver execution |
action.timeout | duration | 10m | Overall action timeout |
action.concurrency | int | 4 | Max parallel action execution |
plugins.grpcMaxMessageSize | int | 67108864 | Max gRPC message size in bytes for plugin communication (64 MB default). Increase for very large provider inputs/outputs |
plugins.fetchCooldown | duration | 5m | Cooldown between failed plugin auto-fetch retries |
settings.disableOfficialAuthHandlers | bool | false | Disable auto-resolution of the official auth handlers (entra, github, gcp) |
settings.disableThirdPartyAuthHandlers | bool | false | Disable catalog-by-name resolution of non-official auth handlers (official-only policy) |
auth.entra.* | object | — | Entra (Azure AD) auth handler config |
auth.github.hostname | string | github.com | GitHub hostname (or GHES hostname) |
auth.github.clientId | string | built-in | OAuth App client ID |
auth.github.defaultScopes | []string | [gist, read:org, repo, workflow] | Default OAuth scopes |
auth.handlers.<name>.plugin.ref | string | handler name | Catalog artifact name for a pinned third-party auth handler |
auth.handlers.<name>.plugin.version | string | latest | Version constraint for a pinned third-party auth handler |
auth.handlers.<name>.trustedVerificationDomains | []string | — | Per-handler trusted device-code verification domains (required trust source for third-party handlers) |
Config File Location#
The config file is located at the XDG config path:
| Platform | Default Location |
|---|---|
| macOS | ~/.config/scafctl/config.yaml |
| Linux | ~/.config/scafctl/config.yaml |
| Windows | %APPDATA%\scafctl\config.yaml |
Override with the --config flag on any command:
scafctl run solution my-solution --config ./custom-config.yamlscafctl run solution my-solution --config ./custom-config.yamlExamples#
Minimal Config#
See examples/config/minimal-config.yaml :
version: 1
settings:
defaultCatalog: "local"
logging:
level: "none"
catalogs:
- name: local
type: filesystem
path: ~/scafctl-catalog/Full Config#
See examples/config/full-config.yaml for a complete reference with all options documented.
Common Workflows#
Initial Setup#
# 1. Initialize config
scafctl config init
# 2. Set up a catalog
scafctl catalog remote add local --type filesystem --path ~/scafctl-catalog --default
# 3. Verify
scafctl config view
scafctl config validate# 1. Initialize config
scafctl config init
# 2. Set up a catalog
scafctl catalog remote add local --type filesystem --path ~/scafctl-catalog --default
# 3. Verify
scafctl config view
scafctl config validateSwitch Environments#
# Use staging catalog
scafctl catalog remote default staging
# Increase logging for debugging
scafctl config set logging.level debug
# After debugging, reset
scafctl config unset logging.level# Use staging catalog
scafctl catalog remote default staging
# Increase logging for debugging
scafctl config set logging.level debug
# After debugging, reset
scafctl config unset logging.levelAPI Server: Token Delegation#
The apiServer section includes configuration for token delegation when running in API mode (scafctl serve). These settings control how the server exchanges or forwards tokens to downstream providers.
Server Identity (Entra ID)#
Configure the server’s identity for OBO and client credentials flows:
# Set up Entra identity for token delegation
scafctl config set apiServer.identity.entra.tenantId "your-tenant-id"
scafctl config set apiServer.identity.entra.clientId "your-client-id"
scafctl config set apiServer.identity.entra.credential.type "secret"
scafctl config set apiServer.identity.entra.credential.clientSecret "env://SCAFCTL_API_ENTRA_CLIENT_SECRET"
# Configure allowed delegation flows
scafctl config set apiServer.identity.entra.allowedFlows.flows '["obo", "client_credentials"]'
# View the identity config
scafctl config get apiServer.identity# Set up Entra identity for token delegation
scafctl config set apiServer.identity.entra.tenantId "your-tenant-id"
scafctl config set apiServer.identity.entra.clientId "your-client-id"
scafctl config set apiServer.identity.entra.credential.type "secret"
scafctl config set apiServer.identity.entra.credential.clientSecret "env://SCAFCTL_API_ENTRA_CLIENT_SECRET"
# Configure allowed delegation flows
scafctl config set apiServer.identity.entra.allowedFlows.flows '["obo", "client_credentials"]'
# View the identity config
scafctl config get apiServer.identityThe credential clientSecret field uses SecretRef URI format:
env://VAR_NAME– reads from an environment variablefile:///path/to/secret– reads from a file
Token Pass-Through#
Configure which provider-specific tokens can be forwarded from API request headers:
# Allow GitHub and Artifactory tokens to be passed through
scafctl config set apiServer.tokenPassThrough.allowedHeaders '["Github", "Artifactory"]'
# View the token pass-through config
scafctl config get apiServer.tokenPassThrough# Allow GitHub and Artifactory tokens to be passed through
scafctl config set apiServer.tokenPassThrough.allowedHeaders '["Github", "Artifactory"]'
# View the token pass-through config
scafctl config get apiServer.tokenPassThroughWhen configured, callers send tokens via X-Authorization-<Suffix> headers (e.g., X-Authorization-Github). The server makes these available to providers via the authProvider input field. When tokenPassThrough is omitted entirely, only Github is allowed by default.
For a complete guide, see the Token Delegation Tutorial .
Next Steps#
- Token Delegation Tutorial – Configure OBO, client credentials, and pass-through delegation
- Authentication Tutorial — Set up GitHub and Entra authentication
- Exec Provider Tutorial — Cross-platform shell execution
- Logging & Debugging Tutorial — Control log verbosity, format, and output
- Cache Tutorial — Manage cached data
- Catalog Tutorial — Build and manage solutions in the catalog