Metadata-Version: 2.4
Name: pcaff
Version: 0.2.1
Summary: CAFF replacement for an offline-key OpenPGP certification workflow
License-Expression: GPL-2.0-or-later
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=41.0
Requires-Dist: jinja2>=3.1
Requires-Dist: pyyaml>=6.0
Dynamic: license-file

# pcaff

`pcaff` is a replacement for the CAFF (CA Fire and Forget) OpenPGP
key-certification workflow. It supports both local certification and a
two-machine workflow in which the certification key remains on a permanently
offline keyholder machine.

## Installation

Create the project environment and install the package with:

```console
uv sync
```

This installs the `pcaff-control` and `pcaff-sign` commands. The online control
command has two Python dependencies, Jinja2 and PyYAML. The complete workflow
also requires the external `sq` and `gpg` executables. All private-key
operations (certifying, signing a transaction tarball, decrypting) go through
`sq` directly, using its own passphrase prompting; `gpg` is used only for
public, non-secret-key operations (per-user-ID certificate export). The offline
keyholder machine in particular never needs `gpg` at all, and never needs a
persistent `sq` certificate or key store either.  The `gpg` dependency is
expected to go away once `sq` grows the ability to redact specific UIDs out of
a certificate export on its own.

See `pcaff(1)`, `pcaff-control(1)`, and `pcaff-sign(1)` for configuration and
usage details.

## Testing

The test suite (`pytest`) runs two ways:

```console
pytest
```

Straight out of a checkout, with the package *not* installed: `src/` is put
on `sys.path` automatically (`pythonpath` in `pyproject.toml`), and the two
CLI-level fixtures (`run_control`, `run_sign`) fall back to `python3 -m
pcaff.control`/`pcaff.sign` when no installed `pcaff-control`/`pcaff-sign`
binary is found on `PATH`.

Against an installed package (e.g. the built Debian package, or any other
installation not laid out like the source tree), point these environment
variables at the installed copies; each falls back to the build-tree
location and fails loudly, naming the checked path, if neither resolves:

| Variable                      | What it points at                                  |
|--------------------------------|-----------------------------------------------------|
| `PCAFF_TEST_CONTROL_BIN`      | the `pcaff-control` binary                          |
| `PCAFF_TEST_SIGN_BIN`         | the `pcaff-sign` binary                             |
| `PCAFF_TEST_MAIL_TEMPLATE`    | the shipped `mail_template.txt.j2`                  |
| `PCAFF_TEST_BASH_COMPLETION`  | the `pcaff-control.bash` completion data            |
| `PCAFF_TEST_OPENSSL`          | the `openssl` binary used to generate test TLS certs |

For example, against the paths a Debian install uses:

```console
PCAFF_TEST_CONTROL_BIN=/usr/bin/pcaff-control \
PCAFF_TEST_SIGN_BIN=/usr/bin/pcaff-sign \
PCAFF_TEST_MAIL_TEMPLATE=/etc/pcaff/mail_template.txt.j2 \
PCAFF_TEST_BASH_COMPLETION=/usr/share/bash-completion/completions/pcaff-control.bash \
pytest
```

A separate, opt-in `real_crypto` marker exercises the real `sq` and `gpg`
binaries instead of the fixture-provided fakes; it's skipped by default and
needs both tools on `PATH`:

```console
PCAFF_REAL_CRYPTO=1 pytest
```

## License

Copyright 2026 Marc Haber <mh+debian-packages@zugschlus.de>

`pcaff` is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 2 of the License, or (at your option) any later
version. See the `LICENSE` file for the full license text.

## Acknowledgments

Created with assistance of OpenAI and Anthropic AI models. Kristian Köhntopp
helped a lot with the prompting.
