Metadata-Version: 2.4
Name: kseal
Version: 2.1.1
Summary: A kubeseal companion CLI - decrypt, edit, export, and encrypt Kubernetes Secrets with automatic binary management
Author-email: Bruno Bernard <contact.brunobernard@gmail.com>
License: MIT
License-File: LICENSE
Keywords: cli,kubernetes,kubeseal,sealed-secrets,secrets
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Requires-Dist: click>=8.0
Requires-Dist: httpx>=0.25
Requires-Dist: kubernetes>=28.0
Requires-Dist: packaging>=23.0
Requires-Dist: pydantic>=2.0
Requires-Dist: rich>=14.2.0
Requires-Dist: ruamel-yaml>=0.18
Description-Content-Type: text/markdown

# kseal

[![PyPI](https://img.shields.io/pypi/v/kseal)](https://pypi.org/project/kseal/)
[![Python](https://img.shields.io/pypi/pyversions/kseal)](https://pypi.org/project/kseal/)
[![License](https://img.shields.io/github/license/eznix86/kseal)](LICENSE)
[![PyPI Monthly Downloads](https://img.shields.io/pypi/dm/kseal.svg)](https://pypi.python.org/pypi/kseal/)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/kseal?period=total&units=INTERNATIONAL_SYSTEM&left_color=GREY&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/kseal)
[![Tests](https://github.com/eznix86/kseal/actions/workflows/test.yml/badge.svg)](https://github.com/eznix86/kseal/actions/workflows/test.yml)



A kubeseal companion CLI for viewing, editing, exporting, encrypting, and **offline decrypting** Kubernetes Secrets.

## Installation

```bash
pipx install kseal
```

<details>
<summary>Other installation methods</summary>

With [uv](https://github.com/astral-sh/uv):

```bash
uv tool install kseal
```

With pip:

```bash
pip install kseal
```

</details>

## Why kseal?

`kubeseal` is excellent at one thing: **encrypting** secrets so they can be safely committed to Git. But day-to-day cluster work involves more than that. For example; inspecting what's inside a sealed secret, swapping secrets across manifests, or recovering secrets without cluster access.

`kseal` is a DX layer on top of `kubeseal` that handles the operational side:

| | kubeseal | kseal |
|---|---|---|
| Encrypt secrets for GitOps | ✅ | ✅ (via kubeseal) |
| View / inspect sealed secrets | ❌ | ✅ `kseal cat` |
| Edit sealed secrets in-place | ❌ | ✅ `kseal edit` |
| Offline decryption | ❌ | ✅ `kseal decrypt` |
| Export secrets to files | ❌ | ✅ `kseal export` |
| Per-project config (no repeated flags) | ❌ | ✅ `.kseal-config.yaml` |
| In-place secret swapping in manifests | ❌ | ✅ `kseal encrypt --in-place` |

If you only ever seal secrets once and push them, `kubeseal` alone is enough. If you work with sealed secrets daily, `kseal` saves the repetition.

### Requirements

- Python 3.12+
- Kubernetes cluster access (not required for offline decryption)
- Sealed Secrets controller installed in cluster

## Quick Start

```bash
# View a decrypted secret (requires cluster access)
kseal cat secrets/app.yaml

# Export all secrets to files
kseal export --all

# Encrypt a plaintext secret
kseal encrypt secret.yaml -o sealed.yaml

# Offline decryption (no cluster access needed)
kseal export-keys                              # Backup keys while you have access
kseal decrypt sealed.yaml                      # Decrypt using local keys
kseal edit sealed.yaml                         # Edit decrypted content, then re-encrypt
kseal decrypt-all --in-place                   # Decrypt all SealedSecrets
```

## Commands

### `kseal cat`

View decrypted secret contents with syntax highlighting.

```bash
kseal cat path/to/sealed-secret.yaml
kseal cat sealed.yaml --no-color
```

### `kseal export`

Export decrypted secrets to files.

```bash
# Single file
kseal export sealed.yaml
kseal export sealed.yaml -o output.yaml

# All local SealedSecrets
kseal export --all

# All secrets from cluster
kseal export --all --from-cluster
```

Default output: `.unsealed/<original-path>` or `.unsealed/<namespace>/<name>.yaml`

### `kseal encrypt`

Encrypt plaintext secrets using kubeseal.

```bash
# To stdout
kseal encrypt secret.yaml

# To file
kseal encrypt secret.yaml -o sealed.yaml

# Replace original file
kseal encrypt secret.yaml --in-place
```

### `kseal export-keys`

Export sealed-secrets private keys from cluster for offline decryption.

```bash
# Export to default location
kseal export-keys                      # → .kseal-keys/

# Custom output directory
kseal export-keys -o ./backup

# From different namespace
kseal export-keys -n kube-system
```

### `kseal decrypt`

Decrypt a SealedSecret using local private keys (no cluster access needed).

```bash
# Using keys from default location
kseal decrypt sealed.yaml

# Using specific key file
kseal decrypt sealed.yaml --private-key ./key.pem

# From stdin
cat sealed.yaml | kseal decrypt

# Filter keys by pattern
kseal decrypt sealed.yaml --private-keys-regex "2025"
```

### `kseal decrypt-all`

Decrypt all SealedSecrets in a directory using local private keys.

```bash
# Search current directory, output to stdout
kseal decrypt-all

# Search specific directory
kseal decrypt-all ./manifests

# Replace files in-place
kseal decrypt-all --in-place

# Custom keys location
kseal decrypt-all --private-keys-path ./backup
```

### `kseal edit`

Edit a SealedSecret safely: decrypt to a temporary editor file, open `$VISUAL` or `$EDITOR`, then re-encrypt the original file only if the plaintext was changed.

```bash
kseal edit sealed.yaml
kseal edit sealed.yaml --private-key ./key.pem
kseal edit sealed.yaml --private-keys-regex "2025"
```

The temporary plaintext file is created with `0600` permissions and removed after the editor exits.

### `kseal init`

Create a configuration file with the latest kubeseal version pinned.

```bash
kseal init
kseal init --force  # Overwrite existing
```

### `kseal version`

Manage kubeseal binary versions.

```bash
# List downloaded versions
kseal version list

# Download the latest version
kseal version update

# Set global default version
kseal version set 0.27.0

# Clear default (use highest downloaded)
kseal version set --clear
```

### `kseal completion`

Generate shell completion scripts.

```bash
# Bash
source <(kseal completion bash)

# Zsh
source <(kseal completion zsh)
```

Add the matching `source <(...)` line to your shell profile to enable completions permanently.

## Configuration

Configuration priority: Environment variables > `.kseal-config.yaml` > Global settings

| Option | Environment Variable | Default |
|--------|---------------------|---------|
| `version` | `KSEAL_VERSION` | Global default or highest downloaded |
| `version: disable` | `KSEAL_VERSION_DISABLE=1` | Use `kubeseal` from PATH without version checks or downloads |
| `controller_name` | `KSEAL_CONTROLLER_NAME` | `sealed-secrets` |
| `controller_namespace` | `KSEAL_CONTROLLER_NAMESPACE` | `sealed-secrets` |
| `unsealed_dir` | `KSEAL_UNSEALED_DIR` | `.unsealed` |

<details>
<summary>Example config file</summary>

```yaml
# .kseal-config.yaml
version: "0.27.0"
controller_name: sealed-secrets
controller_namespace: kube-system
unsealed_dir: .secrets

# To disable automatic kubeseal version management and use PATH:
# version: disable
```

</details>

## Version Management

kseal automatically manages kubeseal binary versions:

- Binaries are stored at `~/.local/share/kseal/kubeseal-<version>`
- Each project can pin a specific version in `.kseal-config.yaml`
- Global settings are stored in `~/.local/share/kseal/settings.yaml`
- Set `KSEAL_VERSION_DISABLE=1` or `version: disable` to use `kubeseal` from `PATH`

**Version resolution order:**
1. Disabled management (`KSEAL_VERSION_DISABLE=1` or `version: disable`) uses `kubeseal` from `PATH`
2. Project config version (`.kseal-config.yaml`)
3. Global default version (`kseal version set`)
4. Highest downloaded version
5. Fetch latest from GitHub (first run only)

## Security

- Add `.unsealed/` and `.kseal-keys/` to your `.gitignore`
- Never commit plaintext secrets or private keys to version control
- Store exported keys securely (e.g., password manager, encrypted backup)
- Offline decryption with `kseal decrypt` requires the private keys - keep them safe

## Contributing

```bash
git clone https://github.com/eznix86/kseal.git
cd kseal
uv sync

# Run tests
make test

# Run linter
make lint
```

## License

[MIT](LICENSE)
