Metadata-Version: 2.5
Name: feldstecher
Version: 0.1.1
Summary: Observe and record the behaviour of black-box systems through their HTTP API - without holding their credentials
Project-URL: Changelog, https://github.com/Hochfrequenz/feldstecher/releases
Project-URL: Homepage, https://github.com/Hochfrequenz/feldstecher
Author-email: Hochfrequenz Unternehmensberatung GmbH <info+github@hochfrequenz.de>
License: MIT
License-File: LICENSE
Keywords: api-testing,http,mitmproxy,proxy,recording,reverse-engineering
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# feldstecher

![Unittests status badge](https://github.com/Hochfrequenz/feldstecher/workflows/Unittests/badge.svg)
![Coverage status badge](https://github.com/Hochfrequenz/feldstecher/workflows/Coverage/badge.svg)
![Linting status badge](https://github.com/Hochfrequenz/feldstecher/workflows/Linting/badge.svg)
![Ruff status badge](https://github.com/Hochfrequenz/feldstecher/workflows/Formatting/badge.svg)

**Observe and record the behaviour of black-box systems through their HTTP API - without holding their credentials.**

A *Feldstecher* is a pair of binoculars: you use it to watch something closely without disturbing it,
and without getting close enough to be bitten. This one is meant to sit between you and an API you do not
control - injecting credentials you never see, refusing to talk to any host you did not allowlist, scrubbing
and recording every exchange, and tagging the test data you create so you can always tell your own tracks
from the wild population.

> [!WARNING]
> Early work in progress. Of the capabilities described above, only the host allowlist
> (`feldstecher.egress`) exists today, and it is not yet wired to a proxy. Everything else is planned.

## Why

Sometimes the only documentation of an API is the API itself. Working it out means sending real requests to a
real system, which raises three problems that the usual recording proxies do not solve:

- **The credentials must not leak to whoever is driving the requests.** That is especially true when the driver
  is an AI agent, but it is just as true for a shared debugging session or a CI job.
- **The recordings are the deliverable, not a debug artifact.** They need full bodies, query strings and timing,
  in a form you can reprocess offline months later.
- **Writes to somebody else's system are permanent.** Test data created while exploring stays there. You need it
  to be unique, recognisable, and written down.

feldstecher is built as a [mitmproxy](https://mitmproxy.org/) addon, so the proxying, TLS interception and flow
persistence are handled by a mature and well-maintained tool, and feldstecher only adds the parts specific to
careful observation.

## What it is not

- Not a general-purpose secrets manager. It brokers credentials for observation sessions, nothing more.
- Not a mock server. It records what a system does; replaying that is a separate concern.
- Not a security boundary against a hostile process on the same machine. If the driver of the requests runs as
  the same user on the same host, it can read feldstecher's configuration. Isolation between the two is your job.

## Development

This project uses [uv](https://docs.astral.sh/uv/) and a `src` layout.

```bash
uv sync --group dev
uv run pytest unittests
```

Contributions are welcome via pull request against `main`.

## Releases

Publishing to PyPI runs from `.github/workflows/python-publish.yml` on a GitHub release, using a
[trusted publisher](https://docs.pypi.org/trusted-publishers/) rather than a token. It needs a repository
environment named `release`, and the publisher registered on the PyPI side must name this repository and
this workflow file.
