Clean up 404 KCL references (99.75% complete): - Rename kcl_* variables to schema_*/nickel_* (kcl_path→schema_path, etc.) - Update functions: parse_kcl_file→parse_nickel_file - Update env vars: KCL_MOD_PATH→NICKEL_IMPORT_PATH - Fix cli/providers-install: add has_nickel and nickel_version variables - Correct import syntax: .nickel.→.ncl. - Update 57 files across core, CLI, config, and utilities Configure pre-commit hooks: - Activate: nushell-check, nickel-typecheck, markdownlint - Comment out: Rust hooks (fmt, clippy, test), check-yaml Testing: - Module discovery: 9 modules (6 providers, 1 taskserv, 2 clusters) ✅ - Syntax validation: 15 core files ✅ - Pre-commit hooks: all passing ✅
459 lines
15 KiB
Plaintext
459 lines
15 KiB
Plaintext
# SecretumVault Command Handlers
|
|
# Handles: kms encrypt, kms decrypt, kms generate-key, kms health, kms version, kms rotate-key
|
|
|
|
use ../flags.nu *
|
|
use ../../lib_provisioning/plugins/secretumvault.nu *
|
|
|
|
# Main SecretumVault command dispatcher
|
|
export def handle_secretumvault_command [
|
|
command: string
|
|
ops: string
|
|
flags: record
|
|
] {
|
|
match $command {
|
|
"secretumvault" | "sv" | "vault" => {
|
|
let subcommand = if ($ops | is-not-empty) {
|
|
($ops | split row " " | get 0)
|
|
} else {
|
|
"help"
|
|
}
|
|
|
|
let remaining_ops = if ($ops | is-not-empty) {
|
|
($ops | split row " " | skip 1 | str join " ")
|
|
} else {
|
|
""
|
|
}
|
|
|
|
match $subcommand {
|
|
"encrypt" => { handle_sv_encrypt $remaining_ops $flags }
|
|
"decrypt" => { handle_sv_decrypt $remaining_ops $flags }
|
|
"generate-key" | "generate" | "gen-key" => { handle_sv_generate_key $remaining_ops $flags }
|
|
"encrypt-file" | "enc-file" => { handle_sv_encrypt_file $remaining_ops $flags }
|
|
"decrypt-file" | "dec-file" => { handle_sv_decrypt_file $remaining_ops $flags }
|
|
"rotate-key" | "rotate" => { handle_sv_rotate_key $remaining_ops $flags }
|
|
"health" | "check" => { handle_sv_health $flags }
|
|
"version" | "ver" => { handle_sv_version $flags }
|
|
"status" | "info" => { handle_sv_status $flags }
|
|
"help" => { show_sv_help }
|
|
_ => {
|
|
print $"❌ Unknown SecretumVault subcommand: ($subcommand)"
|
|
print ""
|
|
print "Available SecretumVault subcommands:"
|
|
print " encrypt - Encrypt data"
|
|
print " decrypt - Decrypt data"
|
|
print " generate-key - Generate new encryption key"
|
|
print " encrypt-file - Encrypt configuration file"
|
|
print " decrypt-file - Decrypt configuration file"
|
|
print " rotate-key - Rotate encryption key"
|
|
print " health - Check service health"
|
|
print " version - Get version information"
|
|
print " status - Show plugin status and configuration"
|
|
print " help - Show this help message"
|
|
print ""
|
|
print "Use 'provisioning secretumvault help' for more details"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
print $"❌ Unknown SecretumVault command: ($command)"
|
|
print "Use 'provisioning secretumvault help' for available commands"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
# Encrypt plaintext data
|
|
def handle_sv_encrypt [ops: string, flags: record] {
|
|
let plaintext = if ($flags.data? | is-not-empty) {
|
|
$flags.data
|
|
} else if ($flags.plaintext? | is-not-empty) {
|
|
$flags.plaintext
|
|
} else if ($ops | is-not-empty) {
|
|
$ops
|
|
} else {
|
|
print $"❌ Error: plaintext data required"
|
|
print "Usage: provisioning secretumvault encrypt <plaintext> [--key-id <key>]"
|
|
exit 1
|
|
}
|
|
|
|
let key_id = if ($flags.key_id? | is-not-empty) { $flags.key_id } else { "" }
|
|
|
|
print $"Encrypting data..."
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
plugin-secretumvault-encrypt $plaintext
|
|
} else {
|
|
plugin-secretumvault-encrypt $plaintext --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Encryption successful\n"
|
|
|
|
if ($result | type) == "record" {
|
|
print $"Key ID: ($result.key_id? | default 'N/A')"
|
|
print $"Algorithm: ($result.algorithm? | default 'AES-256-GCM')"
|
|
print $"Ciphertext:"
|
|
print $result.ciphertext
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $"❌ Encryption failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Decrypt ciphertext data
|
|
def handle_sv_decrypt [ops: string, flags: record] {
|
|
let ciphertext = if ($flags.ciphertext? | is-not-empty) {
|
|
$flags.ciphertext
|
|
} else if ($ops | is-not-empty) {
|
|
$ops
|
|
} else {
|
|
print $"❌ Error: ciphertext required"
|
|
print "Usage: provisioning secretumvault decrypt <ciphertext> [--key-id <key>]"
|
|
exit 1
|
|
}
|
|
|
|
let key_id = if ($flags.key_id? | is-not-empty) { $flags.key_id } else { "" }
|
|
|
|
print $"Decrypting data..."
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
plugin-secretumvault-decrypt $ciphertext
|
|
} else {
|
|
plugin-secretumvault-decrypt $ciphertext --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Decryption successful\n"
|
|
|
|
if ($result | type) == "record" {
|
|
if ($result.plaintext? | is-not-empty) {
|
|
print $"Plaintext:"
|
|
print $result.plaintext
|
|
print $"Key ID: ($result.key_id? | default 'N/A')"
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $"❌ Decryption failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Generate new data key
|
|
def handle_sv_generate_key [ops: string, flags: record] {
|
|
let bits_input = if ($flags.bits? | is-not-empty) { $flags.bits } else { "" }
|
|
let bits = if ($bits_input | is-empty) {
|
|
256
|
|
} else {
|
|
let conversion = (do { $bits_input | into int } | complete)
|
|
if $conversion.exit_code == 0 { $conversion.stdout } else { 256 }
|
|
}
|
|
|
|
let key_id = if ($flags.key_id? | is-not-empty) { $flags.key_id } else { "" }
|
|
|
|
print $"Generating data key ($bits) bits..."
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
plugin-secretumvault-generate-key --bits $bits
|
|
} else {
|
|
plugin-secretumvault-generate-key --bits $bits --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Key generation successful\n"
|
|
|
|
if ($result | type) == "record" {
|
|
print $"Key Size: ($result.bits? | default $bits) bits"
|
|
print $"Algorithm: ($result.algorithm? | default 'AES')"
|
|
print $"Key ID: ($result.key_id? | default 'N/A')"
|
|
print $"Plaintext Key:"
|
|
print $result.plaintext
|
|
print ""
|
|
print $"Encrypted Key:"
|
|
print $result.ciphertext
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $"❌ Key generation failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Encrypt configuration file
|
|
def handle_sv_encrypt_file [ops: string, flags: record] {
|
|
let file = if ($flags.file? | is-not-empty) {
|
|
$flags.file
|
|
} else if ($ops | is-not-empty) {
|
|
($ops | split row " " | get 0)
|
|
} else {
|
|
print $"❌ Error: file path required"
|
|
print "Usage: provisioning secretumvault encrypt-file <file> [--output <path>] [--key-id <key>]"
|
|
exit 1
|
|
}
|
|
|
|
if not ($file | path exists) {
|
|
print $"❌ Error: file not found: ($file)"
|
|
exit 1
|
|
}
|
|
|
|
let output = if ($flags.output? | is-not-empty) {
|
|
$flags.output
|
|
} else {
|
|
$"($file).enc"
|
|
}
|
|
|
|
let key_id = if ($flags.key_id? | is-not-empty) { $flags.key_id } else { "" }
|
|
|
|
print $"Encrypting file: ($file)"
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
encrypt-config-file $file --output $output
|
|
} else {
|
|
encrypt-config-file $file --output $output --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
if ($result.success? | default false) {
|
|
print $"✓ File encrypted successfully\n"
|
|
print $"Input: ($result.input_file? | default $file)"
|
|
print $"Output: ($result.output_file? | default $output)"
|
|
print $"Key ID: ($result.key_id? | default 'N/A')"
|
|
} else {
|
|
print $"❌ File encryption failed"
|
|
exit 1
|
|
}
|
|
} else {
|
|
print $"❌ File encryption failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Decrypt configuration file
|
|
def handle_sv_decrypt_file [ops: string, flags: record] {
|
|
let file = if ($flags.file? | is-not-empty) {
|
|
$flags.file
|
|
} else if ($ops | is-not-empty) {
|
|
($ops | split row " " | get 0)
|
|
} else {
|
|
print $"❌ Error: file path required"
|
|
print "Usage: provisioning secretumvault decrypt-file <file> [--output <path>] [--key-id <key>]"
|
|
exit 1
|
|
}
|
|
|
|
if not ($file | path exists) {
|
|
print $"❌ Error: file not found: ($file)"
|
|
exit 1
|
|
}
|
|
|
|
let output = if ($flags.output? | is-not-empty) {
|
|
$flags.output
|
|
} else {
|
|
let base_name = ($file | str replace '.enc' '')
|
|
$"($base_name).dec"
|
|
}
|
|
|
|
let key_id = if ($flags.key_id? | is-not-empty) { $flags.key_id } else { "" }
|
|
|
|
print $"Decrypting file: ($file)"
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
decrypt-config-file $file --output $output
|
|
} else {
|
|
decrypt-config-file $file --output $output --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
if ($result.success? | default false) {
|
|
print $"✓ File decrypted successfully\n"
|
|
print $"Input: ($result.input_file? | default $file)"
|
|
print $"Output: ($result.output_file? | default $output)"
|
|
print $"Key ID: ($result.key_id? | default 'N/A')"
|
|
} else {
|
|
print $"❌ File decryption failed"
|
|
exit 1
|
|
}
|
|
} else {
|
|
print $"❌ File decryption failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Rotate encryption key
|
|
def handle_sv_rotate_key [ops: string, flags: record] {
|
|
let key_id = if ($flags.key_id? | is-not-empty) {
|
|
$flags.key_id
|
|
} else if ($ops | is-not-empty) {
|
|
$ops
|
|
} else {
|
|
""
|
|
}
|
|
|
|
print $"Rotating encryption key..."
|
|
|
|
let result = (do -i {
|
|
if ($key_id | is-empty) {
|
|
plugin-secretumvault-rotate-key
|
|
} else {
|
|
plugin-secretumvault-rotate-key --key-id $key_id
|
|
}
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Key rotation successful\n"
|
|
|
|
if ($result | type) == "record" {
|
|
print $"Status: ($result.status? | default 'Success')"
|
|
print $"Message: ($result.message? | default 'Key rotated successfully')"
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $"❌ Key rotation failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Check service health
|
|
def handle_sv_health [flags: record] {
|
|
print $"Checking SecretumVault health..."
|
|
|
|
let result = (do -i {
|
|
plugin-secretumvault-health
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Health check complete\n"
|
|
|
|
if ($result | type) == "record" {
|
|
let healthy = ($result.healthy? | default false)
|
|
let health_status = if $healthy { $"✓ Healthy" } else { $"✗ Unhealthy" }
|
|
|
|
print $"Status: $health_status"
|
|
print $"Status Code: ($result.status_code? | default 'N/A')"
|
|
print $"Version: ($result.version? | default 'unknown')"
|
|
print $"Initialized: ($result.initialized? | default false)"
|
|
print $"Sealed: ($result.sealed? | default true)"
|
|
} else {
|
|
print $result
|
|
}
|
|
} else {
|
|
print $"❌ Health check failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Get version information
|
|
def handle_sv_version [flags: record] {
|
|
print $"Getting SecretumVault version..."
|
|
|
|
let result = (do -i {
|
|
plugin-secretumvault-version
|
|
})
|
|
|
|
if $result != null {
|
|
print $"✓ Version information\n"
|
|
print $"SecretumVault Version: ($result)"
|
|
} else {
|
|
print $"❌ Version check failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Show plugin status and configuration
|
|
def handle_sv_status [flags: record] {
|
|
print $"SecretumVault Plugin Status\n"
|
|
|
|
let info = (do -i {
|
|
plugin-secretumvault-info
|
|
})
|
|
|
|
if $info != null {
|
|
print $"Plugin Available: ($info.plugin_available)"
|
|
print $"Plugin Enabled: ($info.plugin_enabled)"
|
|
print $"Service URL: ($info.service_url)"
|
|
print $"Mount Point: ($info.mount_point)"
|
|
print $"Default Key: ($info.default_key)"
|
|
print $"Authenticated: ($info.authenticated)"
|
|
print $"Mode: ($info.mode)"
|
|
} else {
|
|
print $"❌ Status check failed"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Show SecretumVault help
|
|
def show_sv_help [] {
|
|
print "╔════════════════════════════════════════════════════════╗"
|
|
print "║ 🔐 SECRETUMVAULT KMS OPERATIONS ║"
|
|
print "╚════════════════════════════════════════════════════════╝"
|
|
print ""
|
|
print "DESCRIPTION"
|
|
print " SecretumVault is a post-quantum ready KMS system"
|
|
print " for secure encryption, decryption, and key management"
|
|
print ""
|
|
print "COMMANDS"
|
|
print " encrypt <plaintext> [--key-id <key>]"
|
|
print " Encrypt plaintext data"
|
|
print ""
|
|
print " decrypt <ciphertext> [--key-id <key>]"
|
|
print " Decrypt ciphertext"
|
|
print ""
|
|
print " generate-key [--bits <int>] [--key-id <key>]"
|
|
print " Generate new encryption key, 256 bits default"
|
|
print ""
|
|
print " encrypt-file <file> [--output <path>] [--key-id <key>]"
|
|
print " Encrypt configuration file to .enc format"
|
|
print ""
|
|
print " decrypt-file <file> [--output <path>] [--key-id <key>]"
|
|
print " Decrypt encrypted configuration file"
|
|
print ""
|
|
print " rotate-key [--key-id <key>]"
|
|
print " Rotate encryption key"
|
|
print ""
|
|
print " health"
|
|
print " Check SecretumVault service health"
|
|
print ""
|
|
print " version"
|
|
print " Display SecretumVault version"
|
|
print ""
|
|
print " status"
|
|
print " Show plugin configuration and mode"
|
|
print ""
|
|
print "ENVIRONMENT VARIABLES"
|
|
print " SECRETUMVAULT_URL Service URL, http://localhost:8200 default"
|
|
print " SECRETUMVAULT_TOKEN Authentication token, required"
|
|
print " SECRETUMVAULT_MOUNT_POINT Vault mount path, transit default"
|
|
print " SECRETUMVAULT_KEY_NAME Key name, provisioning-master default"
|
|
print " SECRETUMVAULT_TLS_VERIFY Enable TLS verification, false default"
|
|
print ""
|
|
print "EXAMPLES"
|
|
print " provisioning secretumvault encrypt 'my-secret' --key-id master-key"
|
|
print " provisioning secretumvault decrypt 'vault:v1:...' --key-id master-key"
|
|
print " provisioning secretumvault health"
|
|
print " provisioning secretumvault version"
|
|
print ""
|
|
print "SHORTCUTS"
|
|
print " sv → secretumvault, vault → secretumvault, enc → encrypt"
|
|
print " dec → decrypt, health → check, version → ver, status → info"
|
|
print ""
|
|
print "For more info: docs/user/SECRETUMVAULT_KMS_GUIDE.md"
|
|
}
|