quickseal

Crates.ioquickseal
lib.rsquickseal
version0.1.4
created_at2025-10-22 06:10:28.627778+00
updated_at2025-10-22 06:10:28.627778+00
descriptionCreate Kubernetes SealedSecrets with a single secure command
homepage
repositoryhttps://github.com/yourusername/seal
max_upload_size
id1895055
size629,719
Haim Ari (haimari)

documentation

README

Seal 🔐

CI Security Audit codecov Crates.io License: MIT

Create Kubernetes SealedSecrets with a single secure command.

Seal is a CLI tool that simplifies creating Kubernetes SealedSecrets. Instead of manually running multiple commands and worrying about plaintext secret cleanup, Seal does it all in one secure, atomic operation.


✨ Features

  • 🚀 Single Command: Create sealed secrets without manual multi-step workflows
  • 🔒 Secure by Default: Automatic cleanup of plaintext secrets and temp files
  • 🎯 Context Aware: Displays cluster context before sealing to prevent mistakes
  • 🔄 Signal Handling: Graceful cleanup on interruption (Ctrl+C, SIGTERM, SIGHUP)
  • 💾 Memory Safety: Uses zeroize to clear sensitive data from memory
  • ✅ Input Validation: Validates Kubernetes naming conventions (DNS-1123)
  • 📤 Multiple Formats: Outputs YAML or JSON
  • 🌐 Cross-Platform: Works on Linux, macOS, and Windows

🤔 Why Seal?

Without Seal (4+ manual steps)

# Step 1: Create plaintext secret YAML
kubectl create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password=secret123 \
  --dry-run=client -o yaml > secret.yaml

# Step 2: Seal the secret
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

# Step 3: Delete plaintext file (CRITICAL - often forgotten!)
rm secret.yaml

# Step 4: Apply sealed secret
kubectl apply -f sealed-secret.yaml

With Seal (1 command)

seal create -n db-creds -N production \
  -l username=admin -l password=secret123 | kubectl apply -f -

Benefits:

  • ✅ No plaintext files left on disk
  • ✅ No manual cleanup needed
  • ✅ Cluster context displayed before sealing
  • ✅ Automatic error handling and cleanup
  • ✅ Memory-safe secret handling

📋 Prerequisites

Required

  1. Kubernetes cluster with sealed-secrets controller installed:

    kubectl get pods -n kube-system -l name=sealed-secrets-controller
    
  2. kubectl configured with active context:

    kubectl config current-context
    
  3. kubeseal binary installed:

    # macOS
    brew install kubeseal
    
    # Linux (example for v0.24.0)
    KUBESEAL_VERSION=0.24.0
    wget "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz"
    tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal
    sudo install -m 755 kubeseal /usr/local/bin/kubeseal
    
    # Windows
    choco install kubeseal
    
    # Verify installation
    kubeseal --version
    

🚀 Installation

From Releases (Recommended)

Download the latest binary for your platform from GitHub Releases:

# Linux (x86_64)
curl -LO https://github.com/startappdev/seal/releases/latest/download/seal-linux-amd64
chmod +x seal-linux-amd64
sudo mv seal-linux-amd64 /usr/local/bin/seal

# macOS (Apple Silicon)
curl -LO https://github.com/startappdev/seal/releases/latest/download/seal-darwin-arm64
chmod +x seal-darwin-arm64
sudo mv seal-darwin-arm64 /usr/local/bin/seal

# macOS (Intel)
curl -LO https://github.com/startappdev/seal/releases/latest/download/seal-darwin-amd64
chmod +x seal-darwin-amd64
sudo mv seal-darwin-amd64 /usr/local/bin/seal

# Windows (PowerShell)
Invoke-WebRequest -Uri "https://github.com/startappdev/seal/releases/latest/download/seal-windows-amd64.exe" -OutFile "seal.exe"
# Move to a directory in your PATH

From Crates.io (Rust Users)

cargo install quickseal

Note: The package name on crates.io is quickseal (since seal was already taken), but the binary is still called seal.

From Source

# Clone the repository
git clone https://github.com/startappdev/seal.git
cd seal

# Build and install
cargo install --path .

# Verify installation
seal --version

📖 Usage

Basic Usage

Create a sealed secret with key-value pairs:

seal create \
  --name my-secret \
  --namespace production \
  --from-literal username=admin \
  --from-literal password=secret123

Output:

Current Kubernetes context: production-cluster (https://k8s.example.com)

Sealing secret...
✓ SealedSecret created successfully!

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: my-secret
  namespace: production
spec:
  encryptedData:
    username: AgB7x...
    password: AgC9y...

Pipe to kubectl

Apply the sealed secret directly:

seal create -n my-secret -N production \
  -l username=admin -l password=secret123 \
  | kubectl apply -f -

Save to File

seal create -n my-secret -N production \
  -l username=admin -l password=secret123 \
  > sealed-secret.yaml

JSON Output

seal create -n my-secret -N production \
  -l username=admin -l password=secret123 \
  --output json

With Labels and Annotations

seal create \
  --name my-secret \
  --namespace production \
  --from-literal token=abc123 \
  --label app=myapp \
  --label env=prod \
  --annotation managed-by=seal

Multiple Key-Value Pairs

seal create -n db-creds -N production \
  -l DB_HOST=postgres.example.com \
  -l DB_PORT=5432 \
  -l DB_USER=admin \
  -l DB_PASSWORD=super-secret \
  -l DB_NAME=myapp

🎮 Command Reference

Global Flags

  -v, --verbose    Enable verbose logging
  -h, --help       Print help information
  -V, --version    Print version information

seal create Command

Create a sealed secret.

Required Flags:

  -n, --name <NAME>              Secret name (DNS-1123 subdomain)
  -N, --namespace <NAMESPACE>    Kubernetes namespace
  -l, --from-literal <KEY=VALUE> Secret key-value pairs (can be used multiple times)

Optional Flags:

  -L, --label <KEY=VALUE>        Labels to add to the sealed secret (can be used multiple times)
  -A, --annotation <KEY=VALUE>   Annotations to add to the sealed secret (can be used multiple times)
  -o, --output <FORMAT>          Output format: yaml (default) or json
  -i, --interactive              Interactive mode with guided prompts

Examples:

# Basic usage
seal create -n my-secret -N production -l key1=value1 -l key2=value2

# With labels
seal create -n my-secret -N production -l token=abc123 -L app=myapp -L env=prod

# JSON output
seal create -n my-secret -N production -l token=abc123 --output json

# Pipe to kubectl
seal create -n my-secret -N production -l token=abc123 | kubectl apply -f -

# Save to file
seal create -n my-secret -N production -l token=abc123 > sealed-secret.yaml

🛡️ Security Features

Memory Safety

Seal uses the zeroize crate to automatically clear sensitive data from memory when it goes out of scope:

pub struct SecretKeyValue {
    pub key: String,
    pub value: Zeroizing<String>, // Automatically zeroed on drop
}

Secure Temporary Files

All temporary files are created with 0600 permissions (owner read/write only) and are automatically overwritten with zeros before deletion:

impl Drop for SecureTempFile {
    fn drop(&mut self) {
        // Overwrite with zeros before deletion
        let zeros = vec![0u8; file_size];
        file.write_all(&zeros);
    }
}

Signal Handling

Seal registers signal handlers to ensure cleanup happens even if the process is interrupted:

  • SIGINT (Ctrl+C): Graceful cleanup and exit
  • SIGTERM: Graceful cleanup and exit
  • SIGHUP (Unix): Graceful cleanup and exit

Input Validation

All inputs are validated against Kubernetes naming conventions (DNS-1123):

  • Secret names: lowercase alphanumeric, hyphens, dots (1-253 chars)
  • Namespaces: lowercase alphanumeric, hyphens (1-63 chars)
  • Keys: alphanumeric, underscores, hyphens, dots

🏗️ Architecture

src/
├── cli/          # Command-line interface (clap v4)
│   ├── args.rs   # CLI argument parsing
│   └── commands.rs # Command implementations
├── error/        # Structured error types (thiserror)
├── k8s/          # Kubernetes integration
│   ├── context.rs  # Kubeconfig loading (kube-rs)
│   ├── kubeseal.rs # kubeseal integration
│   └── secret.rs   # Secret manifest generation
├── models/       # Data structures and validation
│   ├── context.rs     # Cluster context
│   └── secret_data.rs # Secret models
└── security/     # Security utilities
    ├── cleanup.rs   # Signal handlers
    ├── memory.rs    # Secure memory handling
    └── tempfile.rs  # Secure temporary files

🔧 Development

Prerequisites

  • Rust 1.75+ (stable channel)
  • Cargo

Build

# Debug build
cargo build

# Release build
cargo build --release

# Run
cargo run -- create -n test -N default -l key=value

Test

# Run all tests
cargo test

# Run with output
cargo test -- --nocapture

# Run specific test
cargo test test_name

# Check code coverage
cargo install cargo-llvm-cov
cargo llvm-cov --html
# Open target/llvm-cov/html/index.html

Lint

# Format code
cargo fmt

# Check formatting
cargo fmt --check

# Run clippy
cargo clippy --all-targets --all-features -- -D warnings

Local Development Workflow

# 1. Make changes
# 2. Run tests
cargo test

# 3. Check formatting and lints
cargo fmt && cargo clippy

# 4. Build release
cargo build --release

# 5. Test the binary
./target/release/seal create -n test -N default -l foo=bar

🤝 Contributing

Contributions are welcome! Please see our Contributing Guidelines for details.

Development Principles

This project follows the Rust CLI Development Constitution:

  1. Branching: Feature branches with descriptive names
  2. Security-First: Zero plaintext persistence, memory safety
  3. Code Quality: Clippy with strict settings, rustfmt enforcement
  4. Testing: Unit tests, integration tests, 70%+ code coverage
  5. Cross-Platform: Tested on Linux, macOS, Windows

Reporting Issues

Please use GitHub Issues to report bugs or request features.


🗺️ Roadmap

v0.1.0 (Current - MVP)

  • ✅ Quick secret creation with flags
  • ✅ Cluster context awareness
  • ✅ Interactive mode with guided prompts
  • ✅ Enhanced help system with examples
  • ✅ Secure memory handling and cleanup
  • ✅ Multi-platform support
  • ✅ Comprehensive error handling

v0.2.0 (Planned)

  • ⏳ Shell completion (bash, zsh, fish)
  • ⏳ Read secrets from files (--from-file)

v0.3.0 (Future)

  • 📋 Support for secret types (Opaque, TLS, Docker config)
  • 📋 Dry-run mode (--dry-run)
  • 📋 Diff mode (compare with existing secret)

v1.0.0 (Future)

  • 📋 Integration tests with real clusters
  • 📋 Performance benchmarks
  • 📋 Plugin system for custom secret sources

📊 Project Status

Metric Status
Build ✅ Passing
Tests ✅ 41 tests passing
Coverage ✅ 75.94%
Security Audit ✅ No vulnerabilities
License Compliance ✅ All dependencies checked
Platforms ✅ Linux, macOS, Windows

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments


🚀 Contributing & Releases

Automated Releases

This project uses automated semantic versioning based on conventional commits. When you merge to main, a new release is automatically created if your commits include:

  • feat: → Minor version bump (0.x.0) - New features
  • fix: → Patch version bump (0.0.x) - Bug fixes
  • BREAKING CHANGE: or !: → Major version bump (x.0.0) - Breaking changes

Example:

git commit -m "feat(cli): add --output flag for custom file paths"
# When merged to main → triggers release 0.2.0 (if current is 0.1.0)

Releases are automatically published to:

Note: Commits with docs:, chore:, style:, refactor:, or test: do NOT trigger releases.

For more details, see Release Process Documentation.


📚 Documentation


💬 Support


Made with ❤️ by the Seal Contributors

⭐ Star on GitHub🐛 Report Bug💡 Request Feature

Commit count: 0

cargo fmt