Metadata-Version: 2.4
Name: ign8vault
Version: 1.0.16
Summary: Spin up a production HashiCorp Vault + Consul stack in minutes — Hetzner Cloud, Cloudflare DNS, automated backups to Hetzner StorageBox.
License: MIT
Requires-Python: >=3.9
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Provides-Extra: dev
Requires-Dist: cloudflare (>=3)
Requires-Dist: cryptography (>=42)
Requires-Dist: hcloud (>=2)
Requires-Dist: mypy (>=1.10) ; extra == "dev"
Requires-Dist: paramiko (>=3)
Requires-Dist: pydantic (>=2)
Requires-Dist: pydantic-settings (>=2)
Requires-Dist: pytest (>=8) ; extra == "dev"
Requires-Dist: rich (>=13)
Requires-Dist: ruff (>=0.4) ; extra == "dev"
Requires-Dist: typer (>=0.12)
Description-Content-Type: text/markdown

# ign8vault

Spin up a production **HashiCorp Vault + Consul** stack in minutes — Hetzner Cloud VPS, Cloudflare DNS, Let's Encrypt TLS, and daily restic backups to Hetzner StorageBox.

```
pipx install ign8vault
ign8vault quickstart   # full step-by-step guide
```

---

## Quickstart

### 1. Install

```bash
pipx install ign8vault
```

### 2. Configure

```bash
cp .env.example .env   # fill in your credentials
```

Required variables:

| Variable | Description |
|---|---|
| `IGN8_DOMAIN` | Base domain, e.g. `example.com` |
| `IGN8_ADMIN_EMAIL` | Let's Encrypt contact email |
| `IGN8_HETZNER_TOKEN` | Hetzner Cloud API token |
| `IGN8_CLOUDFLARE_TOKEN` | Cloudflare API token |
| `IGN8_CLOUDFLARE_ZONE_ID` | Cloudflare Zone ID |
| `IGN8_STORAGEBOX_HOST` | e.g. `u310424.your-storagebox.de` |
| `IGN8_STORAGEBOX_PASSWORD` | StorageBox password |

### 3. Provision

```bash
ign8vault up
```

Creates a Hetzner VPS, Cloudflare DNS records (`vault.<domain>` + `consul.<domain>`), installs Consul + Vault + nginx + TLS, and sets up daily backups. Credentials are saved to `.ign8vault/vault-init.json` — keep the unseal keys safe.

### 4. Set shell environment

```bash
ign8vault setenv
```

Writes `VAULT_ADDR` and `VAULT_TOKEN` to your shell profile.

### 5. Create users (optional)

```bash
ign8vault adduser <username>
```

Creates a Vault userpass account and a scoped SSH-signing token. Use the printed token as `VAULT_TOKEN` for `ign8vault sign`.

### 6. Sign your SSH key

```bash
ign8vault sign
```

Generates an ed25519 keypair in `~/.ssh/signedssh/` and signs it via the Vault SSH CA. Re-run any time to renew (8-hour validity by default).

### 7. Configure a target host

```bash
ign8vault setupsshd --host <ip> --user <user> --password <pw>
```

Installs the Vault CA public key on the host, reloads sshd, and adds a `~/.ssh/config` entry. After this, `ssh <alias>` works with your signed cert — no passwords, no per-host `authorized_keys`.

### 8. Connect

```bash
ssh <alias>
```

### Tear down

```bash
ign8vault destroy
```

Deletes the Hetzner server and Cloudflare DNS records.

---

## Commands

| Command | Description |
|---|---|
| `ign8vault up` | Provision the full stack |
| `ign8vault adduser <name>` | Create a Vault user + SSH-signing token |
| `ign8vault sign` | Create/sign the SSH keypair |
| `ign8vault setupsshd` | Configure a host to trust the Vault CA |
| `ign8vault setenv` | Write Vault env vars to shell profile |
| `ign8vault quickstart` | Print this guide in the terminal |
| `ign8vault destroy` | Tear it all down |

## State

All local state is stored in `.ign8vault/`:

- `keys/` — server provisioning SSH keypair
- `vault-init.json` — root token + unseal keys (chmod 600, **keep safe**)
- `state.json` — Hetzner server ID (used by `destroy`)

Signed SSH keys live in `~/.ssh/signedssh/` and are separate from the provisioning state.

## After a reboot

Vault requires 3 of the 5 unseal keys after every restart:

```bash
vault operator unseal   # run 3 times with different keys
```

