# Nushell Plugins for Provisioning Platform\n\nComplete guide to authentication, KMS, and orchestrator plugins.\n\n## Overview\n\nThree native Nushell plugins provide high-performance integration with the provisioning platform:\n\n1. **nu_plugin_auth** - JWT authentication and MFA operations\n2. **nu_plugin_kms** - Key management (RustyVault, Age, Cosmian, AWS, Vault)\n3. **nu_plugin_orchestrator** - Orchestrator operations (status, validate, tasks)\n\n## Why Native Plugins\n\n**Performance Advantages**:\n\n- **10x faster** than HTTP API calls (KMS operations)\n- **Direct access** to Rust libraries (no HTTP overhead)\n- **Native integration** with Nushell pipelines\n- **Type safety** with Nushell's type system\n\n**Developer Experience**:\n\n- **Pipeline friendly** - Use Nushell pipes naturally\n- **Tab completion** - All commands and flags\n- **Consistent interface** - Follows Nushell conventions\n- **Error handling** - Nushell-native error messages\n\n---\n\n## Installation\n\n### Prerequisites\n\n- Nushell 0.107.1+\n- Rust toolchain (for building from source)\n- Access to provisioning platform services\n\n### Build from Source\n\n```\ncd /Users/Akasha/project-provisioning/provisioning/core/plugins/nushell-plugins\n\n# Build all plugins\ncargo build --release -p nu_plugin_auth\ncargo build --release -p nu_plugin_kms\ncargo build --release -p nu_plugin_orchestrator\n\n# Or build individually\ncargo build --release -p nu_plugin_auth\ncargo build --release -p nu_plugin_kms\ncargo build --release -p nu_plugin_orchestrator\n```\n\n### Register with Nushell\n\n```\n# Register all plugins\nplugin add target/release/nu_plugin_auth\nplugin add target/release/nu_plugin_kms\nplugin add target/release/nu_plugin_orchestrator\n\n# Verify registration\nplugin list | where name =~ "provisioning"\n```\n\n### Verify Installation\n\n```\n# Test auth commands\nauth --help\n\n# Test KMS commands\nkms --help\n\n# Test orchestrator commands\norch --help\n```\n\n---\n\n## Plugin: nu_plugin_auth\n\nAuthentication plugin for JWT login, MFA enrollment, and session management.\n\n### Commands\n\n#### `auth login <username> [password]`\n\nLogin to provisioning platform and store JWT tokens securely.\n\n**Arguments**:\n\n- `username` (required): Username for authentication\n- `password` (optional): Password (prompts interactively if not provided)\n\n**Flags**:\n\n- `--url <url>`: Control center URL (default: `http://localhost:9080`)\n- `--password <password>`: Password (alternative to positional argument)\n\n**Examples**:\n\n```\n# Interactive password prompt (recommended)\nauth login admin\n\n# Password in command (not recommended for production)\nauth login admin mypassword\n\n# Custom URL\nauth login admin --url http://control-center:9080\n\n# Pipeline usage\n"admin" | auth login\n```\n\n**Token Storage**:\nTokens are stored securely in OS-native keyring:\n\n- **macOS**: Keychain Access\n- **Linux**: Secret Service (gnome-keyring, kwallet)\n- **Windows**: Credential Manager\n\n**Success Output**:\n\n```\n✓ Login successful\nUser: admin\nRole: Admin\nExpires: 2025-10-09T14:30:00Z\n```\n\n---\n\n#### `auth logout`\n\nLogout from current session and remove stored tokens.\n\n**Examples**:\n\n```\n# Simple logout\nauth logout\n\n# Pipeline usage (conditional logout)\nif (auth verify | get active) { auth logout }\n```\n\n**Success Output**:\n\n```\n✓ Logged out successfully\n```\n\n---\n\n#### `auth verify`\n\nVerify current session and check token validity.\n\n**Examples**:\n\n```\n# Check session status\nauth verify\n\n# Pipeline usage\nauth verify | if $in.active { echo "Session valid" } else { echo "Session expired" }\n```\n\n**Success Output**:\n\n```\n{\n  "active": true,\n  "user": "admin",\n  "role": "Admin",\n  "expires_at": "2025-10-09T14:30:00Z",\n  "mfa_verified": true\n}\n```\n\n---\n\n#### `auth sessions`\n\nList all active sessions for current user.\n\n**Examples**:\n\n```\n# List sessions\nauth sessions\n\n# Filter by date\nauth sessions | where created_at > (date now | date to-timezone UTC | into string)\n```\n\n**Output Format**:\n\n```\n[\n  {\n    "session_id": "sess_abc123",\n    "created_at": "2025-10-09T12:00:00Z",\n    "expires_at": "2025-10-09T14:30:00Z",\n    "ip_address": "192.168.1.100",\n    "user_agent": "nushell/0.107.1"\n  }\n]\n```\n\n---\n\n#### `auth mfa enroll <type>`\n\nEnroll in MFA (TOTP or WebAuthn).\n\n**Arguments**:\n\n- `type` (required): MFA type (`totp` or `webauthn`)\n\n**Examples**:\n\n```\n# Enroll TOTP (Google Authenticator, Authy)\nauth mfa enroll totp\n\n# Enroll WebAuthn (YubiKey, Touch ID, Windows Hello)\nauth mfa enroll webauthn\n```\n\n**TOTP Enrollment Output**:\n\n```\n✓ TOTP enrollment initiated\n\nScan this QR code with your authenticator app:\n\n  ████ ▄▄▄▄▄ █▀█ █▄▀▀▀▄ ▄▄▄▄▄ ████\n  ████ █   █ █▀▀▀█▄ ▀▀█ █   █ ████\n  ████ █▄▄▄█ █ █▀▄ ▀▄▄█ █▄▄▄█ ████\n  ...\n\nOr enter manually:\nSecret: JBSWY3DPEHPK3PXP\nURL: otpauth://totp/Provisioning:admin?secret=JBSWY3DPEHPK3PXP&issuer=Provisioning\n\nBackup codes (save securely):\n1. ABCD-EFGH-IJKL\n2. MNOP-QRST-UVWX\n...\n```\n\n---\n\n#### `auth mfa verify --code <code>`\n\nVerify MFA code (TOTP or backup code).\n\n**Flags**:\n\n- `--code <code>` (required): 6-digit TOTP code or backup code\n\n**Examples**:\n\n```\n# Verify TOTP code\nauth mfa verify --code 123456\n\n# Verify backup code\nauth mfa verify --code ABCD-EFGH-IJKL\n```\n\n**Success Output**:\n\n```\n✓ MFA verification successful\n```\n\n---\n\n### Environment Variables\n\n| Variable | Description | Default |\n| ---------- | ------------- | --------- |\n| `USER` | Default username | Current OS user |\n| `CONTROL_CENTER_URL` | Control center URL | `http://localhost:9080` |\n\n---\n\n### Error Handling\n\n**Common Errors**:\n\n```\n# "No active session"\nError: No active session found\n→ Run: auth login <username>\n\n# "Invalid credentials"\nError: Authentication failed: Invalid username or password\n→ Check username and password\n\n# "Token expired"\nError: Token has expired\n→ Run: auth login <username>\n\n# "MFA required"\nError: MFA verification required\n→ Run: auth mfa verify --code <code>\n\n# "Keyring error" (macOS)\nError: Failed to access keyring\n→ Check Keychain Access permissions\n\n# "Keyring error" (Linux)\nError: Failed to access keyring\n→ Install gnome-keyring or kwallet\n```\n\n---\n\n## Plugin: nu_plugin_kms\n\nKey Management Service plugin supporting multiple backends.\n\n### Supported Backends\n\n| Backend | Description | Use Case |\n| --------- | ------------- | ---------- |\n| `rustyvault` | RustyVault Transit engine | Production KMS |\n| `age` | Age encryption (local) | Development/testing |\n| `cosmian` | Cosmian KMS (HTTP) | Cloud KMS |\n| `aws` | AWS KMS | AWS environments |\n| `vault` | HashiCorp Vault | Enterprise KMS |\n\n### Commands\n\n#### `kms encrypt <data> [--backend <backend>]`\n\nEncrypt data using KMS.\n\n**Arguments**:\n\n- `data` (required): Data to encrypt (string or binary)\n\n**Flags**:\n\n- `--backend <backend>`: KMS backend (`rustyvault`, `age`, `cosmian`, `aws`, `vault`)\n- `--key <key>`: Key ID or recipient (backend-specific)\n- `--context <context>`: Additional authenticated data (AAD)\n\n**Examples**:\n\n```\n# Auto-detect backend from environment\nkms encrypt "secret data"\n\n# RustyVault\nkms encrypt "data" --backend rustyvault --key provisioning-main\n\n# Age (local encryption)\nkms encrypt "data" --backend age --key age1xxxxxxxxx\n\n# AWS KMS\nkms encrypt "data" --backend aws --key alias/provisioning\n\n# With context (AAD)\nkms encrypt "data" --backend rustyvault --key provisioning-main --context "user=admin"\n```\n\n**Output Format**:\n\n```\nvault:v1:abc123def456...\n```\n\n---\n\n#### `kms decrypt <encrypted> [--backend <backend>]`\n\nDecrypt KMS-encrypted data.\n\n**Arguments**:\n\n- `encrypted` (required): Encrypted data (base64 or KMS format)\n\n**Flags**:\n\n- `--backend <backend>`: KMS backend (auto-detected if not specified)\n- `--context <context>`: Additional authenticated data (AAD, must match encryption)\n\n**Examples**:\n\n```\n# Auto-detect backend\nkms decrypt "vault:v1:abc123def456..."\n\n# RustyVault explicit\nkms decrypt "vault:v1:abc123..." --backend rustyvault\n\n# Age\nkms decrypt "-----BEGIN AGE ENCRYPTED FILE-----..." --backend age\n\n# With context\nkms decrypt "vault:v1:abc123..." --backend rustyvault --context "user=admin"\n```\n\n**Output**:\n\n```\nsecret data\n```\n\n---\n\n#### `kms generate-key [--spec <spec>]`\n\nGenerate data encryption key (DEK) using KMS.\n\n**Flags**:\n\n- `--spec <spec>`: Key specification (`AES128` or `AES256`, default: `AES256`)\n- `--backend <backend>`: KMS backend\n\n**Examples**:\n\n```\n# Generate AES-256 key\nkms generate-key\n\n# Generate AES-128 key\nkms generate-key --spec AES128\n\n# Specific backend\nkms generate-key --backend rustyvault\n```\n\n**Output Format**:\n\n```\n{\n  "plaintext": "base64-encoded-key",\n  "ciphertext": "vault:v1:encrypted-key",\n  "spec": "AES256"\n}\n```\n\n---\n\n#### `kms status`\n\nShow KMS backend status and configuration.\n\n**Examples**:\n\n```\n# Show status\nkms status\n\n# Filter to specific backend\nkms status | where backend == "rustyvault"\n```\n\n**Output Format**:\n\n```\n{\n  "backend": "rustyvault",\n  "status": "healthy",\n  "url": "http://localhost:8200",\n  "mount_point": "transit",\n  "version": "0.1.0"\n}\n```\n\n---\n\n### Environment Variables\n\n**RustyVault Backend**:\n\n```\nexport RUSTYVAULT_ADDR="http://localhost:8200"\nexport RUSTYVAULT_TOKEN="your-token-here"\nexport RUSTYVAULT_MOUNT="transit"\n```\n\n**Age Backend**:\n\n```\nexport AGE_RECIPIENT="age1xxxxxxxxx"\nexport AGE_IDENTITY="/path/to/key.txt"\n```\n\n**HTTP Backend (Cosmian)**:\n\n```\nexport KMS_HTTP_URL="http://localhost:9998"\nexport KMS_HTTP_BACKEND="cosmian"\n```\n\n**AWS KMS**:\n\n```\nexport AWS_REGION="us-east-1"\nexport AWS_ACCESS_KEY_ID="..."\nexport AWS_SECRET_ACCESS_KEY="..."\n```\n\n---\n\n### Performance Comparison\n\n| Operation | HTTP API | Plugin | Improvement |\n| ----------- | ---------- | -------- | ------------- |\n| Encrypt (RustyVault) | ~50 ms | ~5 ms | **10x faster** |\n| Decrypt (RustyVault) | ~50 ms | ~5 ms | **10x faster** |\n| Encrypt (Age) | ~30 ms | ~3 ms | **10x faster** |\n| Decrypt (Age) | ~30 ms | ~3 ms | **10x faster** |\n| Generate Key | ~60 ms | ~8 ms | **7.5x faster** |\n\n---\n\n## Plugin: nu_plugin_orchestrator\n\nOrchestrator operations plugin for status, validation, and task management.\n\n### Commands\n\n#### `orch status [--data-dir <dir>]`\n\nGet orchestrator status from local files (no HTTP).\n\n**Flags**:\n\n- `--data-dir <dir>`: Data directory (default: `provisioning/platform/orchestrator/data`)\n\n**Examples**:\n\n```\n# Default data dir\norch status\n\n# Custom dir\norch status --data-dir ./custom/data\n\n# Pipeline usage\norch status | if $in.active_tasks > 0 { echo "Tasks running" }\n```\n\n**Output Format**:\n\n```\n{\n  "active_tasks": 5,\n  "completed_tasks": 120,\n  "failed_tasks": 2,\n  "pending_tasks": 3,\n  "uptime": "2d 4h 15m",\n  "health": "healthy"\n}\n```\n\n---\n\n#### `orch validate <workflow.ncl> [--strict]`\n\nValidate workflow Nickel file.\n\n**Arguments**:\n\n- `workflow.ncl` (required): Path to Nickel workflow file\n\n**Flags**:\n\n- `--strict`: Enable strict validation (all checks, warnings as errors)\n\n**Examples**:\n\n```\n# Basic validation\norch validate workflows/deploy.ncl\n\n# Strict mode\norch validate workflows/deploy.ncl --strict\n\n# Pipeline usage\nls workflows/*.ncl | each { |file| orch validate $file.name }\n```\n\n**Output Format**:\n\n```\n{\n  "valid": true,\n  "workflow": {\n    "name": "deploy_k8s_cluster",\n    "version": "1.0.0",\n    "operations": 5\n  },\n  "warnings": [],\n  "errors": []\n}\n```\n\n**Validation Checks**:\n\n- KCL syntax errors\n- Required fields present\n- Dependency graph valid (no cycles)\n- Resource limits within bounds\n- Provider configurations valid\n\n---\n\n#### `orch tasks [--status <status>] [--limit <n>]`\n\nList orchestrator tasks.\n\n**Flags**:\n\n- `--status <status>`: Filter by status (`pending`, `running`, `completed`, `failed`)\n- `--limit <n>`: Limit number of results (default: 100)\n- `--data-dir <dir>`: Data directory (default from `ORCHESTRATOR_DATA_DIR`)\n\n**Examples**:\n\n```\n# All tasks\norch tasks\n\n# Pending tasks only\norch tasks --status pending\n\n# Running tasks (limit to 10)\norch tasks --status running --limit 10\n\n# Pipeline usage\norch tasks --status failed | each { |task| echo $"Failed: ($task.name)" }\n```\n\n**Output Format**:\n\n```\n[\n  {\n    "task_id": "task_abc123",\n    "name": "deploy_kubernetes",\n    "status": "running",\n    "priority": 5,\n    "created_at": "2025-10-09T12:00:00Z",\n    "updated_at": "2025-10-09T12:05:00Z",\n    "progress": 45\n  }\n]\n```\n\n---\n\n### Environment Variables\n\n| Variable | Description | Default |\n| ---------- | ------------- | --------- |\n| `ORCHESTRATOR_DATA_DIR` | Data directory | `provisioning/platform/orchestrator/data` |\n\n---\n\n### Performance Comparison\n\n| Operation | HTTP API | Plugin | Improvement |\n| ----------- | ---------- | -------- | ------------- |\n| Status | ~30 ms | ~3 ms | **10x faster** |\n| Validate | ~100 ms | ~10 ms | **10x faster** |\n| Tasks List | ~50 ms | ~5 ms | **10x faster** |\n\n---\n\n## Pipeline Examples\n\n### Authentication Flow\n\n```\n# Login and verify in one pipeline\nauth login admin\n    | if $in.success { auth verify }\n    | if $in.mfa_required { auth mfa verify --code (input "MFA code: ") }\n```\n\n### KMS Operations\n\n```\n# Encrypt multiple secrets\n["secret1", "secret2", "secret3"]\n    | each { |data| kms encrypt $data --backend rustyvault }\n    | save encrypted_secrets.json\n\n# Decrypt and process\nopen encrypted_secrets.json\n    | each { |enc| kms decrypt $enc }\n    | each { |plain| echo $"Decrypted: ($plain)" }\n```\n\n### Orchestrator Monitoring\n\n```\n# Monitor running tasks\nwhile true {\n    orch tasks --status running\n        | each { |task| echo $"($task.name): ($task.progress)%" }\n    sleep 5sec\n}\n```\n\n### Combined Workflow\n\n```\n# Complete deployment workflow\nauth login admin\n    | auth mfa verify --code (input "MFA: ")\n    | orch validate workflows/deploy.ncl\n    | if $in.valid {\n        orch tasks --status pending\n            | where priority > 5\n            | each { |task| echo $"High priority: ($task.name)" }\n      }\n```\n\n---\n\n## Troubleshooting\n\n### Auth Plugin\n\n**"No active session"**:\n\n```\nauth login <username>\n```\n\n**"Keyring error" (macOS)**:\n\n- Check Keychain Access permissions\n- Security & Privacy → Privacy → Full Disk Access → Add Nushell\n\n**"Keyring error" (Linux)**:\n\n```\n# Install keyring service\nsudo apt install gnome-keyring  # Ubuntu/Debian\nsudo dnf install gnome-keyring  # Fedora\n\n# Or use KWallet\nsudo apt install kwalletmanager\n```\n\n**"MFA verification failed"**:\n\n- Check time synchronization (TOTP requires accurate clocks)\n- Use backup codes if TOTP not working\n- Re-enroll MFA if device lost\n\n---\n\n### KMS Plugin\n\n**"RustyVault connection failed"**:\n\n```\n# Check RustyVault running\ncurl http://localhost:8200/v1/sys/health\n\n# Set environment\nexport RUSTYVAULT_ADDR="http://localhost:8200"\nexport RUSTYVAULT_TOKEN="your-token"\n```\n\n**"Age encryption failed"**:\n\n```\n# Check Age keys\nls -la ~/.age/\n\n# Generate new key if needed\nage-keygen -o ~/.age/key.txt\n\n# Set environment\nexport AGE_RECIPIENT="age1xxxxxxxxx"\nexport AGE_IDENTITY="$HOME/.age/key.txt"\n```\n\n**"AWS KMS access denied"**:\n\n```\n# Check AWS credentials\naws sts get-caller-identity\n\n# Check KMS key policy\naws kms describe-key --key-id alias/provisioning\n```\n\n---\n\n### Orchestrator Plugin\n\n**"Failed to read status"**:\n\n```\n# Check data directory exists\nls provisioning/platform/orchestrator/data/\n\n# Create if missing\nmkdir -p provisioning/platform/orchestrator/data\n```\n\n**"Workflow validation failed"**:\n\n```\n# Use strict mode for detailed errors\norch validate workflows/deploy.ncl --strict\n```\n\n**"No tasks found"**:\n\n```\n# Check orchestrator running\nps aux | grep orchestrator\n\n# Start orchestrator\ncd provisioning/platform/orchestrator\n./scripts/start-orchestrator.nu --background\n```\n\n---\n\n## Development\n\n### Building from Source\n\n```\ncd provisioning/core/plugins/nushell-plugins\n\n# Clean build\ncargo clean\n\n# Build with debug info\ncargo build -p nu_plugin_auth\ncargo build -p nu_plugin_kms\ncargo build -p nu_plugin_orchestrator\n\n# Run tests\ncargo test -p nu_plugin_auth\ncargo test -p nu_plugin_kms\ncargo test -p nu_plugin_orchestrator\n\n# Run all tests\ncargo test --all\n```\n\n### Adding to CI/CD\n\n```\nname: Build Nushell Plugins\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: Install Rust\n        uses: actions-rs/toolchain@v1\n        with:\n          toolchain: stable\n\n      - name: Build Plugins\n        run: |\n          cd provisioning/core/plugins/nushell-plugins\n          cargo build --release --all\n\n      - name: Test Plugins\n        run: |\n          cd provisioning/core/plugins/nushell-plugins\n          cargo test --all\n\n      - name: Upload Artifacts\n        uses: actions/upload-artifact@v3\n        with:\n          name: plugins\n          path: provisioning/core/plugins/nushell-plugins/target/release/nu_plugin_*\n```\n\n---\n\n## Advanced Usage\n\n### Custom Plugin Configuration\n\nCreate `~/.config/nushell/plugin_config.nu`:\n\n```\n# Auth plugin defaults\n$env.CONTROL_CENTER_URL = "https://control-center.example.com"\n\n# KMS plugin defaults\n$env.RUSTYVAULT_ADDR = "https://vault.example.com:8200"\n$env.RUSTYVAULT_MOUNT = "transit"\n\n# Orchestrator plugin defaults\n$env.ORCHESTRATOR_DATA_DIR = "/opt/orchestrator/data"\n```\n\n### Plugin Aliases\n\nAdd to `~/.config/nushell/config.nu`:\n\n```\n# Auth shortcuts\nalias login = auth login\nalias logout = auth logout\n\n# KMS shortcuts\nalias encrypt = kms encrypt\nalias decrypt = kms decrypt\n\n# Orchestrator shortcuts\nalias status = orch status\nalias validate = orch validate\nalias tasks = orch tasks\n```\n\n---\n\n## Security Best Practices\n\n### Authentication\n\n✅ **DO**: Use interactive password prompts\n✅ **DO**: Enable MFA for production environments\n✅ **DO**: Verify session before sensitive operations\n❌ **DON'T**: Pass passwords in command line (visible in history)\n❌ **DON'T**: Store tokens in plain text files\n\n### KMS Operations\n\n✅ **DO**: Use context (AAD) for encryption when available\n✅ **DO**: Rotate KMS keys regularly\n✅ **DO**: Use hardware-backed keys (WebAuthn, YubiKey) when possible\n❌ **DON'T**: Share Age private keys\n❌ **DON'T**: Log decrypted data\n\n### Orchestrator\n\n✅ **DO**: Validate workflows in strict mode before production\n✅ **DO**: Monitor task status regularly\n✅ **DO**: Use appropriate data directory permissions (700)\n❌ **DON'T**: Run orchestrator as root\n❌ **DON'T**: Expose data directory over network shares\n\n---\n\n## FAQ\n\n**Q: Why use plugins instead of HTTP API?**\nA: Plugins are 10x faster, have better Nushell integration, and eliminate HTTP overhead.\n\n**Q: Can I use plugins without orchestrator running?**\nA: `auth` and `kms` work independently. `orch` requires access to orchestrator data directory.\n\n**Q: How do I update plugins?**\nA: Rebuild and re-register: `cargo build --release --all && plugin add target/release/nu_plugin_*`\n\n**Q: Are plugins cross-platform?**\nA: Yes, plugins work on macOS, Linux, and Windows (with appropriate keyring services).\n\n**Q: Can I use multiple KMS backends simultaneously?**\nA: Yes, specify `--backend` flag for each operation.\n\n**Q: How do I backup MFA enrollment?**\nA: Save backup codes securely (password manager, encrypted file). QR code can be re-scanned.\n\n---\n\n## Related Documentation\n\n- **Security System**: `docs/architecture/adr-009-security-system-complete.md`\n- **JWT Auth**: `docs/architecture/JWT_AUTH_IMPLEMENTATION.md`\n- **Config Encryption**: `docs/user/CONFIG_ENCRYPTION_GUIDE.md`\n- **RustyVault Integration**: `RUSTYVAULT_INTEGRATION_SUMMARY.md`\n- **MFA Implementation**: `docs/architecture/MFA_IMPLEMENTATION_SUMMARY.md`\n\n---\n\n**Version**: 1.0.0\n**Last Updated**: 2025-10-09\n**Maintained By**: Platform Team
