Skip to main content

fiki (Python)

Python

The Python implementation of fiki. Requires Python 3.11 or newer, and depends on cryptography and http-sfv and on nothing else.

From a fresh clone to passing tests

cd py
uv sync
uv run pytest

The suite enforces 100% branch coverage; a gap needs an approved deviation: node in the repo's this.i.

Signing a request

from fiki import Key, sign_request

key = Key.generate()
print(key.aid)            # register this once with whoever you call
print(key.seed.hex())     # 32 bytes; persist them somewhere the cron job can read

url = "https://api.example.com/things?limit=1"
body = b'{"hello": "world"}'
headers = sign_request(key=key, method="POST", url=url, body=body)

By default the signature binds the method, the host, the path, the query string, and a digest of the body. Pass the body wherever you pass the URL: fiki covers a body it is given, or refuses to sign — but it cannot cover one it never sees.

Verifying a request

from fiki import verify_request

verdict = verify_request(
    method=request.method,
    url=request.url,      # a full URL, or a path plus a Host header
    headers=request.headers,
    body=request.body,
    max_age=300,          # seconds, or None to decline the check
)
verdict.aid               # who signed it

max_age has no default and must be given. Both defaults would be wrong: a number guesses at somebody else's clock skew and replay window, and skipping the check silently is the thing the argument exists to prevent. An expires the signer declared is enforced either way.

Responses, resolved keyids, and a minimum covered set

These exist for the KERI profile of RFC 9421 (this.i @7f28p7xk, @6g9zjsv9) and are, for now, in this port only.

from fiki import (REQUEST_MINIMUM, RESPONSE_MINIMUM, Request, sign_request, sign_response,
                  verify_request, verify_response)

# A keyid that is not the key itself, such as a KERI AID, needs a resolver on the verify side.
# The resolver returns the 32 raw bytes of the key, or None; fiki never decodes the keyid itself.
headers = sign_request(key=key, method="POST", url=url, body=body, keyid=aid)
verdict = verify_request(method="POST", url=url, headers=headers, body=body, max_age=300,
                         resolve=current_key_for, minimum=REQUEST_MINIMUM)

# A response binds the request it answers with RFC 9421's req parameter.
asked = Request(method="POST", url=url, headers=request_headers, body=body)
signed = sign_response(key=key, status=200, request=asked, body=reply)
verify_response(status=200, headers=signed, body=reply, request=asked, max_age=300,
                minimum=RESPONSE_MINIMUM)

minimum refuses a signature that covers less than the named components even when it is valid, and refuses a body — Content-Length above zero, any Transfer-Encoding, or one that simply arrived — whose content-digest is not covered. The method is signed exactly as given, with no case change, so pass it as it will go on the wire.

minimum=None, the default, enforces nothing: a body handed to verify_request with no covered content-digest is then accepted, and only the verdict's covered shows it. Pass a minimum whenever you hand over a body. Signers take the same minimum and refuse to cover less. A client checking a response should pass expected_keyid, the AID it is talking to; a server that requires @authority should pass authorities, the set it serves. An unsigned 401 is Unauthenticated, and a resolver raises UnsupportedSigner for a key state with no single effective signer.

Conformance

tests/test_rfc9421_conformance.py signs RFC 9421's own Appendix B.2.6 request with the RFC's own published Ed25519 key and asserts the RFC's own signature, byte for byte. tests/test_vectors.py runs the shared vectors/ at the repository root, which every port runs. tests/test_keri_vectors.py runs vectors/keri/, the KERI profile's set, which only this port runs so far.

Metadata

Release files for fiki 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fiki 0.6.0
File Size Uploaded
fiki-0.6.0.tar.gz 85.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fiki 0.6.0
File Interpreter ABI Platform
fiki-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 112.7 kB

Release files / fiki-0.6.0.tar.gz

Download URL fiki-0.6.0.tar.gz
Size 85.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f0a8d87207e7937391fcfd81df2c89947d7ad74233c8e5c6ee2efb5c3ff08f22
BLAKE2b-256 checksum
How to use checksums
7d364c08b409cebb7db3aaee435c38724673f6e4dfabf554c292c3549c906739
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / fiki-0.6.0-py3-none-any.whl

Download URL fiki-0.6.0-py3-none-any.whl
Size 27.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f215b282b9db092175fe9e5afcd1d21504f2c6e27987e5bbd4eb924aec1b264
BLAKE2b-256 checksum
How to use checksums
cbc93b8118c059742c7d2c67957bc504bd32e8c1bcc0f7b7f1dae2b3f6c52370
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.0

2 release files

0.7.0

2 release files

This release

0.6.0 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page