Jesús Pérez 85ce530733
feat: update provisioning core CLI, libraries, and plugins
Update core components including CLI, Nushell libraries, plugins system,
and utility scripts for the provisioning system.

CLI Updates:
- Command implementations
- CLI utilities and dispatching
- Help system improvements
- Command validation

Library Updates:
- Configuration management system
- Infrastructure validation
- Extension system improvements
- Secrets management
- Workspace operations
- Cache management system

Plugin System:
- Interactive form plugin (inquire)
- KCL integration plugin
- Performance optimization plugins
- Plugin registration system

Utilities:
- Build and distribution scripts
- Installation procedures
- Testing utilities
- Development tools

Documentation:
- Library module documentation
- Extension API guides
- Plugin usage guides
- Service management documentation

All changes are backward compatible. No breaking changes.
2025-12-11 21:57:05 +00:00
..

KMS (Key Management Service) Configuration

Version: 1.0.0 Status: Independent configuration system for local and remote KMS Location: /provisioning/core/services/kms/

Overview

The KMS configuration system provides a comprehensive, independent configuration for managing encryption keys and secrets. It supports three operational modes:

  1. Local Mode - Uses local encryption tools (age, SOPS, Vault)
  2. Remote Mode - Connects to external KMS servers (Cosmian KMS, AWS KMS, etc.)
  3. Hybrid Mode - Combines both with automatic fallback

Directory Structure

provisioning/core/services/kms/
├── config.defaults.toml       # System defaults for all KMS settings
├── config.schema.toml          # Validation rules and constraints
├── config.remote.example.toml  # Production remote KMS examples
├── config.local.example.toml   # Local encryption examples
├── lib.nu                      # KMS library functions (existing)
└── README.md                   # This file

Configuration Files

1. config.defaults.toml

Primary configuration file containing all KMS settings with sensible defaults.

Key Sections:

  • [kms] - Core settings (enabled, mode, version)
  • [kms.paths] - Path configuration with interpolation support
  • [kms.local] - Local encryption provider settings
  • [kms.remote] - Remote KMS server configuration
  • [kms.hybrid] - Hybrid mode settings
  • [kms.policies] - Key rotation and backup policies
  • [kms.encryption] - Encryption algorithms and KDF settings
  • [kms.security] - Security enforcement rules

2. config.schema.toml

Validation schema defining:

  • Type constraints for all fields
  • Value ranges and patterns
  • Cross-field validation rules
  • Security requirements

3. Example Configurations

  • config.remote.example.toml - Remote KMS deployment scenarios
  • config.local.example.toml - Local encryption configurations (age, SOPS, Vault)

Path Interpolation

All paths support interpolation variables for flexibility and portability:

Available Interpolation Variables

Variable Description Example
{{workspace.path}} Current workspace root /workspace/my-project
{{kms.paths.base}} KMS base directory {{workspace.path}}/.kms
{{env.HOME}} User home directory /home/user
{{env.VAR}} Any environment variable {{env.CONFIG_DIR}}
{{now.date}} Current date 2025-10-06
{{git.branch}} Current git branch main

Path Examples

# Workspace-relative paths (recommended)
[kms.paths]
base = "{{workspace.path}}/.kms"
keys_dir = "{{kms.paths.base}}/keys"

# Absolute paths
[kms.local]
key_path = "/etc/provisioning/kms/age.txt"

# Home directory paths
[kms.remote.auth]
token_path = "{{env.HOME}}/.config/provisioning/kms-token"

# Environment variable paths
[kms.local.vault]
token_path = "{{env.VAULT_TOKEN_PATH}}"

Security Considerations

1. Key File Permissions

CRITICAL: Key files MUST have restricted permissions (0600 or 0400).

[kms.local.age]
key_permissions = "0600"  # Read/write for owner only

[kms.security]
enforce_key_permissions = true  # Enforces permission checks

Best Practice:

  • Production keys: 0400 (read-only)
  • Development keys: 0600 (read/write for owner)
  • Never use: 0644, 0755, or world-readable permissions

2. Secret References (NOT Plaintext!)

NEVER store secrets directly in configuration files.

Use secret references instead:

# ✅ CORRECT - Secret reference
[kms.remote.auth]
password_secret = "sops://kms/remote/password"
api_key = "vault://kms/api/key"

# ❌ WRONG - Plaintext secret
[kms.remote.auth]
password = "my-secret-password"  # NEVER DO THIS!

Supported Secret References:

  • sops://path/to/secret - SOPS encrypted secret
  • vault://path/to/secret - HashiCorp Vault secret
  • kms://path/to/secret - KMS-encrypted secret
  • age://path/to/secret - Age-encrypted secret

3. TLS/mTLS Configuration

Always use TLS 1.3 for remote KMS connections:

[kms.remote.tls]
enabled = true
verify = true                    # Always verify certificates
min_version = "1.3"              # TLS 1.3 minimum
ca_cert_path = "/etc/kms/ca.crt"

# For mTLS authentication
[kms.remote.auth]
method = "mtls"
client_cert_path = "/etc/kms/client.crt"
client_key_path = "/etc/kms/client.key"

Security Rules:

  • Never disable TLS verification in production
  • Use mTLS when available for mutual authentication
  • Store certificates outside version control
  • Rotate certificates regularly

4. Audit Logging

Enable audit logging for production environments:

[kms.policies]
audit_log_enabled = true
audit_log_path = "{{kms.paths.base}}/audit.log"
audit_log_format = "json"

Logged Operations:

  • Encryption/decryption requests
  • Key rotation events
  • Authentication attempts
  • Configuration changes

5. Debug Mode Warning

NEVER enable debug mode in production!

[kms.operations]
debug = false  # Debug exposes sensitive data in logs!
verbose = false

Debug mode includes:

  • Plaintext key material in logs
  • Full request/response bodies
  • Authentication credentials
  • Decrypted secrets

6. Secret Scanning

Enable secret scanning to prevent accidental exposure:

[kms.security]
secret_scanning_enabled = true
disallow_plaintext_secrets = true

secret_patterns = [
    "(?i)password\\s*=\\s*['\"]?[^'\"\\s]+",
    "(?i)api[_-]?key\\s*=\\s*['\"]?[^'\"\\s]+",
    "(?i)token\\s*=\\s*['\"]?[^'\"\\s]+",
]

7. Key Backup and Rotation

Implement key rotation and backup policies:

[kms.policies]
auto_rotate = true
rotation_days = 90              # Rotate every 90 days
backup_enabled = true
backup_path = "{{kms.paths.base}}/backups"
backup_retention_count = 5      # Keep last 5 backups

Backup Best Practices:

  • Store backups in secure, encrypted storage
  • Test restore procedures regularly
  • Document key recovery process
  • Separate backup storage from primary keys

Configuration Loading

The KMS configuration is loaded via config accessor functions in /provisioning/core/nulib/lib_provisioning/config/accessor.nu.

Available Accessor Functions

Core Settings

  • get-kms-enabled - Check if KMS is enabled
  • get-kms-mode - Get operating mode (local/remote/hybrid)
  • get-kms-version - Get KMS config version

Path Accessors

  • get-kms-base-path - Get base KMS directory
  • get-kms-keys-dir - Get keys directory
  • get-kms-cache-dir - Get cache directory
  • get-kms-config-dir - Get config directory

Local Configuration

  • get-kms-local-enabled - Check if local mode enabled
  • get-kms-local-provider - Get provider (age/sops/vault)
  • get-kms-local-key-path - Get key file path
  • get-kms-age-generate-on-init - Check auto-generate setting

Remote Configuration

  • get-kms-remote-enabled - Check if remote mode enabled
  • get-kms-remote-endpoint - Get KMS server URL
  • get-kms-remote-auth-method - Get auth method
  • get-kms-remote-timeout - Get connection timeout

Full Config Helper

  • get-kms-config-full - Get complete KMS config as record

Usage Examples

# Check if KMS is enabled
let kms_enabled = (get-kms-enabled)

# Get operating mode
let mode = (get-kms-mode)

# Get full configuration
let kms_config = (get-kms-config-full)

# Get local key path with interpolation resolved
let key_path = (get-kms-local-key-path)

Operational Modes

1. Local Mode (Default)

Uses local encryption tools without external dependencies.

Use Cases:

  • Development environments
  • Offline operations
  • Simple encryption needs
  • No cloud KMS access

Supported Providers:

  • age - Simple, modern encryption (recommended)
  • sops - Secret Operations with multiple backends
  • vault - HashiCorp Vault Transit engine

Example:

[kms]
enabled = true
mode = "local"

[kms.local]
enabled = true
provider = "age"
key_path = "{{kms.paths.keys_dir}}/age.txt"

2. Remote Mode

Connects to external KMS server for centralized key management.

Use Cases:

  • Production environments
  • Centralized key management
  • Compliance requirements
  • Multi-region deployments

Supported Integrations:

  • Cosmian KMS
  • AWS KMS
  • HashiCorp Vault (remote)
  • Custom KMS servers

Example:

[kms]
enabled = true
mode = "remote"

[kms.remote]
enabled = true
endpoint = "https://kms.production.example.com"

[kms.remote.auth]
method = "mtls"
client_cert_path = "/etc/kms/client.crt"
client_key_path = "/etc/kms/client.key"

3. Hybrid Mode

Combines local and remote with automatic fallback.

Use Cases:

  • High availability requirements
  • Gradual migration from local to remote
  • Offline operation support
  • Disaster recovery

Example:

[kms]
enabled = true
mode = "hybrid"

[kms.local]
enabled = true
provider = "age"

[kms.remote]
enabled = true
endpoint = "https://kms.example.com"

[kms.hybrid]
enabled = true
fallback_to_local = true
sync_keys = false

Authentication Methods

Token-based Authentication

[kms.remote.auth]
method = "token"
token_path = "{{kms.paths.config_dir}}/token"
refresh_token = true
token_expiry_seconds = 3600

mTLS (Mutual TLS)

[kms.remote.auth]
method = "mtls"
client_cert_path = "/etc/kms/client.crt"
client_key_path = "/etc/kms/client.key"

[kms.remote.tls]
ca_cert_path = "/etc/kms/ca.crt"

API Key

[kms.remote.auth]
method = "api_key"
api_key = "sops://kms/api_key"  # Secret reference!

Basic Authentication

[kms.remote.auth]
method = "basic"
username = "provisioning"
password_secret = "vault://kms/password"  # Secret reference!

IAM (AWS)

[kms.remote.auth]
method = "iam"
iam_role_arn = "arn:aws:iam::123456789012:role/kms-role"

Integration with Existing KMS Library

The existing KMS library (lib.nu) can be updated to use the new configuration:

Current Implementation

# Old: Hardcoded config lookup
def get_kms_config [] {
    let server_url = (get-kms-server)
    # ...
}

Updated Implementation

# New: Use new config accessors
def get_kms_config [] {
    let mode = (get-kms-mode)

    match $mode {
        "local" => {
            {
                provider: (get-kms-local-provider)
                key_path: (get-kms-local-key-path)
                # ...
            }
        }
        "remote" => {
            {
                endpoint: (get-kms-remote-endpoint)
                auth_method: (get-kms-remote-auth-method)
                # ...
            }
        }
        "hybrid" => {
            # Both local and remote config
        }
    }
}

Validation

Configuration is validated against the schema:

Validation Rules

  1. Mode Consistency

    • local mode requires kms.local.enabled = true
    • remote mode requires kms.remote.enabled = true
    • hybrid mode requires both enabled
  2. Auth Method Requirements

    • mtls requires client_cert_path and client_key_path
    • token requires token_path
    • api_key requires api_key
    • basic requires username and password_secret
  3. Security Enforcement

    • Password must be secret reference (not plaintext)
    • Key permissions must be 0600 or 0400
    • TLS verification required for production
  4. Resource Constraints

    • Timeout: 1-300 seconds
    • Retry attempts: 0-10
    • Cache TTL: 60-3600 seconds
    • File size: 1-1024 MB

Migration Guide

From Environment Variables to Config

Before (ENV-based):

export PROVISIONING_KMS_SERVER="https://kms.example.com"
export PROVISIONING_KMS_AUTH="certificate"

After (Config-based):

[kms.remote]
endpoint = "https://kms.example.com"

[kms.remote.auth]
method = "mtls"

From SOPS to KMS Config

The new KMS config is independent from SOPS but still supports SOPS as a provider:

[kms.local]
provider = "sops"
sops_config = "{{workspace.path}}/.sops.yaml"

[kms.local.sops]
age_recipients = ["age1xxx...", "age1yyy..."]

Best Practices

1. Development Environment

[kms]
mode = "local"

[kms.local]
provider = "age"
key_path = "/tmp/dev-age.txt"

[kms.operations]
verbose = true
debug = false  # Never true, even in dev!

[kms.policies]
backup_enabled = false
audit_log_enabled = false

2. Production Environment

[kms]
mode = "remote"

[kms.remote]
endpoint = "https://kms.prod.example.com"
timeout_seconds = 30
retry_attempts = 3

[kms.remote.auth]
method = "mtls"
client_cert_path = "/etc/kms/client.crt"
client_key_path = "/etc/kms/client.key"

[kms.remote.tls]
verify = true
min_version = "1.3"

[kms.policies]
auto_rotate = true
rotation_days = 90
backup_enabled = true
audit_log_enabled = true

[kms.security]
enforce_key_permissions = true
disallow_plaintext_secrets = true

[kms.operations]
verbose = false
debug = false

3. Hybrid/HA Environment

[kms]
mode = "hybrid"

[kms.local]
enabled = true
provider = "age"

[kms.remote]
enabled = true
endpoint = "https://kms.example.com"

[kms.hybrid]
enabled = true
fallback_to_local = true
sync_keys = false

Troubleshooting

Issue: Permission Denied on Key File

Error:

Permission denied: /path/to/age.txt

Solution:

chmod 0600 /path/to/age.txt

Or update config:

[kms.local.age]
key_permissions = "0600"

[kms.security]
enforce_key_permissions = true

Issue: Remote KMS Connection Failed

Error:

Connection timeout: https://kms.example.com

Solutions:

  1. Check network connectivity
  2. Verify TLS certificates
  3. Increase timeout:
    [kms.remote]
    timeout_seconds = 60
    retry_attempts = 5
    

Issue: Secret Reference Not Found

Error:

Secret not found: sops://kms/password

Solution:

  1. Verify secret exists in SOPS/Vault
  2. Check secret path format
  3. Ensure SOPS/Vault is properly configured

Version Compatibility

KMS Config Version Nushell Version KCL Version Notes
1.0.0 0.107.1+ 0.11.3+ Initial release
  • Config System: /provisioning/config/README.md
  • SOPS Integration: /provisioning/core/nulib/lib_provisioning/secrets/
  • Environment Setup: /docs/environment-setup.md
  • Security Guide: /docs/security/secrets-management.md

Support

For issues or questions:

  1. Check this README
  2. Review example configurations
  3. Consult validation schema
  4. Check audit logs (if enabled)

License

Part of the provisioning project. See project LICENSE.