| Crates.io | quickseal |
| lib.rs | quickseal |
| version | 0.1.4 |
| created_at | 2025-10-22 06:10:28.627778+00 |
| updated_at | 2025-10-22 06:10:28.627778+00 |
| description | Create Kubernetes SealedSecrets with a single secure command |
| homepage | |
| repository | https://github.com/yourusername/seal |
| max_upload_size | |
| id | 1895055 |
| size | 629,719 |
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.
zeroize to clear sensitive data from memory# 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
seal create -n db-creds -N production \
-l username=admin -l password=secret123 | kubectl apply -f -
Benefits:
Kubernetes cluster with sealed-secrets controller installed:
kubectl get pods -n kube-system -l name=sealed-secrets-controller
kubectl configured with active context:
kubectl config current-context
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
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
cargo install quickseal
Note: The package name on crates.io is
quickseal(sincesealwas already taken), but the binary is still calledseal.
# Clone the repository
git clone https://github.com/startappdev/seal.git
cd seal
# Build and install
cargo install --path .
# Verify installation
seal --version
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...
Apply the sealed secret directly:
seal create -n my-secret -N production \
-l username=admin -l password=secret123 \
| kubectl apply -f -
seal create -n my-secret -N production \
-l username=admin -l password=secret123 \
> sealed-secret.yaml
seal create -n my-secret -N production \
-l username=admin -l password=secret123 \
--output json
seal create \
--name my-secret \
--namespace production \
--from-literal token=abc123 \
--label app=myapp \
--label env=prod \
--annotation managed-by=seal
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
-v, --verbose Enable verbose logging
-h, --help Print help information
-V, --version Print version information
seal create CommandCreate 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
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
}
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);
}
}
Seal registers signal handlers to ensure cleanup happens even if the process is interrupted:
All inputs are validated against Kubernetes naming conventions (DNS-1123):
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
# Debug build
cargo build
# Release build
cargo build --release
# Run
cargo run -- create -n test -N default -l key=value
# 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
# Format code
cargo fmt
# Check formatting
cargo fmt --check
# Run clippy
cargo clippy --all-targets --all-features -- -D warnings
# 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
Contributions are welcome! Please see our Contributing Guidelines for details.
This project follows the Rust CLI Development Constitution:
Please use GitHub Issues to report bugs or request features.
--from-file)--dry-run)| Metric | Status |
|---|---|
| Build | ✅ Passing |
| Tests | ✅ 41 tests passing |
| Coverage | ✅ 75.94% |
| Security Audit | ✅ No vulnerabilities |
| License Compliance | ✅ All dependencies checked |
| Platforms | ✅ Linux, macOS, Windows |
This project is licensed under the MIT License - see the LICENSE file for details.
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 featuresfix: → Patch version bump (0.0.x) - Bug fixesBREAKING CHANGE: or !: → Major version bump (x.0.0) - Breaking changesExample:
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:
cargo installNote: Commits with docs:, chore:, style:, refactor:, or test: do NOT trigger releases.
For more details, see Release Process Documentation.
Made with ❤️ by the Seal Contributors