Metacrypt is a cryptographic service for the Metacircular platform. It provides an encrypted storage barrier, engine-based cryptographic operations, and MCIAS-backed authentication. The service uses a seal/unseal model: it starts sealed after every restart and must be unsealed with a password before it can serve requests.
### Service States
| State | Description |
|---|---|
| **Uninitialized** | Fresh install. Must run `metacrypt init` or use the web UI. |
| **Sealed** | Initialized but locked. No cryptographic operations available. |
| **Initializing** | Transient state during first-time setup. |
| **Unsealed** | Fully operational. All APIs and engines available. |
This prompts for a seal password, generates the master encryption key, and stores the encrypted MEK in the database. The service is left in the unsealed state.
### Option B: Web UI
Start the server and navigate to `https://<host>:8443/`. If the service is uninitialized, you will be redirected to the init page.
### Seal Password Requirements
- The seal password is the root of all security. If lost, the data is unrecoverable.
- Store it in a secure location (password manager, HSM, sealed envelope in a safe).
- The password is never stored — only a salt and encrypted MEK are persisted.
- Argon2id parameters (time=3, memory=128 MiB, threads=4) are stored in the database at init time.
---
## Daily Operations
### Starting the Service
```bash
# systemd
sudo systemctl start metacrypt
# Docker
docker compose -f deploy/docker/docker-compose.yml up -d
The backup is a consistent SQLite snapshot created with `VACUUM INTO`. The backup file contains the same encrypted data as the live database — the seal password is still required to access it.
**The seal password does not change between backups.** A backup restored from any point in time uses the same seal password that was set during `metacrypt init`.
---
## Monitoring
### Health Check
```bash
curl -sk https://localhost:8443/v1/status
```
Returns HTTP 200 in all states. Check the `state` field:
-`unsealed` — healthy, fully operational
-`sealed` — needs unseal, no crypto operations available
-`uninitialized` — needs init
### Log Output
Metacrypt logs structured JSON to stdout. When running under systemd, logs go to the journal:
| `server: tls: failed to find any PEM data` | Bad cert/key files | Verify PEM format: `openssl x509 -in server.crt -text -noout` |
### Unseal fails
| Symptom | Cause | Fix |
|---|---|---|
| `invalid password` (401) | Wrong seal password | Verify password. There is no recovery if the password is lost. |
| `too many attempts` (429) | Rate limited | Wait 60 seconds, then try again |
| `not initialized` (412) | Database is empty/new | Run `metacrypt init` |
### Authentication fails
| Symptom | Cause | Fix |
|---|---|---|
| `invalid credentials` (401) | Bad username/password or MCIAS down | Verify MCIAS is reachable: `curl -sk https://mcias.metacircular.net:8443/v1/health` |
| `sealed` (503) | Service not unsealed | Unseal the service first |
| Connection refused to MCIAS | Network/TLS issue | Check `mcias.server_url` and `mcias.ca_cert` in config |
The provided service unit applies: `NoNewPrivileges`, `ProtectSystem=strict`, `ProtectHome`, `PrivateTmp`, `PrivateDevices`, `MemoryDenyWriteExecute`, and namespace restrictions. Only `/srv/metacrypt` is writable.
The container runs as a non-root `metacrypt` user. The `/srv/metacrypt` volume should be owned by the container's metacrypt UID (determined at build time). Do not run the container with `--privileged`.