Metadata-Version: 2.4
Name: ign8vault
Version: 1.0.17
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
ign8vault setenv
```

Walks you through every credential interactively with hints on where to find each value. Writes a `.env` file in the current directory. Run it again after provisioning to fill in `VAULT_ADDR` and `VAULT_TOKEN`.

| Variable | Where to get it |
|---|---|
| `IGN8_DOMAIN` | Your base domain, e.g. `example.com` |
| `IGN8_ADMIN_EMAIL` | Your email — used for Let's Encrypt notifications |
| `IGN8_HETZNER_TOKEN` | console.hetzner.cloud → Project → Security → API Tokens |
| `IGN8_CLOUDFLARE_TOKEN` | dash.cloudflare.com → Profile → API Tokens (Zone:DNS:Edit) |
| `IGN8_CLOUDFLARE_ZONE_ID` | Cloudflare dashboard → select domain → Overview → right sidebar |
| `IGN8_STORAGEBOX_HOST` | Hetzner StorageBox hostname — optional, skip for no backups |
| `IGN8_STORAGEBOX_PASSWORD` | Hetzner account → StorageBox details |

### 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. Finish configuration

```bash
ign8vault setenv
```

Re-run `setenv` to fill in `VAULT_ADDR` and `VAULT_TOKEN` from `.ign8vault/vault-init.json`. Existing values are preserved.

### 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
```

