apsig
apsig is collection of signature implemention used in ActivityPub.
This library implements the creation/verification of signatures for HTTP Signatures (draft-cavage-http-signatures-12), Linked Data Signatures 1.0, and Object Integrity Proofs (FEP-8b32).
RFC9421 implementation is progress.
Installation
# pip
pip install apsig
# uv
uv add apsig
# pdm
pdm add apsig
Example
First, prepare the keys for signing and verification. apsig uses the cryptography library.
from cryptography.hazmat.primitives.asymmetric import rsa, ed25519
from cryptography.hazmat.primitives import serialization
# For HTTP Signatures (RSA)
private_key_rsa = rsa.generate_private_key(public_exponent=65537, key_size=3092)
public_key_rsa_pem = private_key_rsa.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
# For Object Integrity Proofs (Ed25519)
private_key_ed = ed25519.Ed25519PrivateKey.generate()
public_key_ed = private_key_ed.public_key()
HTTP Signature (draft)
This is used for signing HTTP requests.
import email.utils
from apsig.draft import Signer, Verifier
# === Signing ===
method = "POST"
url = "https://example.com/api/resource"
headers = {
"Content-Type": "application/json",
"Date": email.utils.formatdate(usegmt=True),
}
body = '{"key": "value"}'
key_id = "https://example.com/users/johndoe#main-key"
signer = Signer(
headers=headers,
private_key=private_key_rsa,
method=method,
url=url,
key_id=key_id,
body=body.encode("utf-8"),
)
signed_headers = signer.sign()
print(signed_headers)
# === Verifying ===
verifier = Verifier(
public_pem=public_key_rsa_pem.decode("utf-8"),
method=method,
url=url,
headers=signed_headers,
body=body.encode("utf-8"),
)
verified_key_id = verifier.verify(raise_on_fail=True)
print(f"Verified with key: {verified_key_id}")
Object Integrity Proofs (proof)
This is used for signing JSON objects (like ActivityStreams objects).
from apsig import ProofSigner, ProofVerifier
# === Signing ===
json_object = {
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/data-integrity/v1",
],
"id": "https://server.example/objects/1",
"type": "Note",
"content": "Hello world",
}
proof_options = {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "https://example.com/keys/1",
"created": "2024-01-01T09:00:00Z",
}
signer = ProofSigner(private_key_ed)
signed_object = signer.sign(json_object, proof_options)
print(signed_object)
# === Verifying ===
verifier = ProofVerifier(public_key_ed)
verified_key_id = verifier.verify(signed_object, raise_on_fail=True)
print(f"Verified with key: {verified_key_id}")
Linked Data Signature (LD-Signature)
This is another method for signing JSON-LD objects, often used in older ActivityPub implementations.
from apsig import LDSignature
# === Signing ===
ld_signer = LDSignature()
json_ld_object = {
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
],
"type": "Note",
"content": "Hello, Linked Data!",
}
creator = "https://example.com/users/johndoe#main-key"
signed_ld_object = ld_signer.sign(
doc=json_ld_object,
creator=creator,
private_key=private_key_rsa
)
print(signed_ld_object)
# === Verifying ===
# The public key can be passed directly.
public_key_rsa = private_key_rsa.public_key()
verified_creator = ld_signer.verify(
doc=signed_ld_object,
public_key=public_key_rsa,
raise_on_fail=True
)
print(f"Verified with creator: {verified_creator}")
Documents
The document can be viewed here.
Thanks
- Hong Minhee (Fedify Author)
- Takahē Authors (apsig.LDSignature was ported from Takahē)
- And All Contributor/Users
License
MIT License
Metadata
Release files for apsig 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| apsig-0.6.0.tar.gz | 151.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apsig-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 171.6 kB
Release files / apsig-0.6.0.tar.gz
| Download URL | apsig-0.6.0.tar.gz |
|---|---|
| Size | 151.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bf17c7978ff45f21313a40f0255dd1fae35cca61ef7e613fb70274ca64ec823
|
|
BLAKE2b-256 checksum How to use checksums |
9f9968ed305078b58b2f79539f9e4fce210b2b63318cf6ea56821490a259a7c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 28, 2025.
Transparency logRelease files / apsig-0.6.0-py3-none-any.whl
| Download URL | apsig-0.6.0-py3-none-any.whl |
|---|---|
| Size | 20.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1a4d742f13deb0b3a344ee69e3edbdc3c091a03d0b47a40ce70966b2e637ceb5
|
|
BLAKE2b-256 checksum How to use checksums |
bf6f7f4293cdfc39a2869bd95402ae4d680ea42e3578c6064e32700c918e7647
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 28, 2025.
Transparency log