Official SDK for HAP (Human Attestation Protocol) - cryptographic proof of verified human effort
Project description
human-attestation
Official HAP (Human Attestation Protocol) SDK for Python.
HAP is an open standard for verified human effort. It enables Verification Authorities (VAs) to cryptographically attest that a sender took deliberate, costly action when communicating with a recipient.
Installation
pip install human-attestation
Quick Start
Verifying a Claim (For Recipients)
import asyncio
from hap import verify_hap_claim, is_claim_expired, is_claim_for_recipient
async def main():
# Verify a claim from a HAP ID
claim = await verify_hap_claim("hap_abc123xyz456", "ballista.jobs")
if claim:
# Check if not expired
if is_claim_expired(claim):
print("Claim has expired")
return
# Verify it's for your organization
if not is_claim_for_recipient(claim, "yourcompany.com"):
print("Claim is for a different recipient")
return
print(f"Verified {claim['method']} application to {claim['to']['name']}")
asyncio.run(main())
Verifying from a URL
from hap import extract_hap_id_from_url, verify_hap_claim
async def verify_from_url(url: str):
# Extract HAP ID from a verification URL
hap_id = extract_hap_id_from_url(url)
if hap_id:
claim = await verify_hap_claim(hap_id, "ballista.jobs")
return claim
return None
Verifying Signature Manually
from hap import fetch_claim, verify_signature
async def verify_with_signature(hap_id: str):
# Fetch the claim
response = await fetch_claim(hap_id, "ballista.jobs")
if response.get("valid") and "jws" in response:
# Verify the cryptographic signature
result = await verify_signature(response["jws"], "ballista.jobs")
if result["valid"]:
print("Signature verified!", result["claim"])
else:
print("Signature invalid:", result["error"])
Signing Claims (For Verification Authorities)
import json
from hap import (
generate_key_pair,
export_public_key_jwk,
create_human_effort_claim,
sign_claim,
)
# Generate a key pair (do this once, store securely)
private_key, public_key = generate_key_pair()
# Export public key for /.well-known/hap.json
jwk = export_public_key_jwk(public_key, "my_key_001")
well_known = {"issuer": "my-va.com", "keys": [jwk]}
print(json.dumps(well_known, indent=2))
# Create and sign a claim
claim = create_human_effort_claim(
method="physical_mail",
recipient_name="Acme Corp",
domain="acme.com",
tier="standard",
issuer="my-va.com",
expires_in_days=730, # 2 years
)
jws = sign_claim(claim, private_key, kid="my_key_001")
print("Signed JWS:", jws)
Creating Recipient Commitment Claims
from hap import create_recipient_commitment_claim, sign_claim
claim = create_recipient_commitment_claim(
recipient_name="Acme Corp",
recipient_domain="acme.com",
commitment="review_verified",
issuer="my-va.com",
expires_in_days=365,
)
jws = sign_claim(claim, private_key, kid="my_key_001")
API Reference
Verification Functions
| Function | Description |
|---|---|
verify_hap_claim(hap_id, issuer) |
Fetch and verify a claim, returns claim or None |
fetch_claim(hap_id, issuer) |
Fetch raw verification response from VA |
verify_signature(jws, issuer) |
Verify JWS signature against VA's public keys |
fetch_public_keys(issuer) |
Fetch VA's public keys from well-known endpoint |
is_valid_hap_id(id) |
Check if string matches HAP ID format |
extract_hap_id_from_url(url) |
Extract HAP ID from verification URL |
is_claim_expired(claim) |
Check if claim has passed expiration |
is_claim_for_recipient(claim, domain) |
Check if claim targets specific recipient |
Signing Functions (For VAs)
| Function | Description |
|---|---|
generate_key_pair() |
Generate Ed25519 key pair |
export_public_key_jwk(key, kid) |
Export public key as JWK |
sign_claim(claim, private_key, kid) |
Sign a claim, returns JWS |
generate_hap_id() |
Generate cryptographically secure HAP ID |
create_human_effort_claim(...) |
Create human_effort claim with defaults |
create_recipient_commitment_claim(...) |
Create recipient_commitment claim |
Types
from hap import (
HapClaim,
HumanEffortClaim,
RecipientCommitmentClaim,
VerificationResponse,
HapWellKnown,
HapJwk,
)
Requirements
- Python 3.9+
- httpx (for async HTTP)
- PyJWT with cryptography
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file human_attestation-0.3.7.tar.gz.
File metadata
- Download URL: human_attestation-0.3.7.tar.gz
- Upload date:
- Size: 7.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53ede1aa4b00447b6ce356e105d683af76044ba503cc03b865a2c579085ba82b
|
|
| MD5 |
851cf7b7203dcc3b0818bb9b0f0cdfb2
|
|
| BLAKE2b-256 |
65cdb17ff9ff9326a77f279179c950b01e0e78fa789741022ad18293b609aa55
|
File details
Details for the file human_attestation-0.3.7-py3-none-any.whl.
File metadata
- Download URL: human_attestation-0.3.7-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5325f8a96558dbad3066424f8c4666fbb4fe9bf968912ba9520d8526d7f4eba5
|
|
| MD5 |
d8a3cec4673a7bb1e5566f8500360c55
|
|
| BLAKE2b-256 |
7e78cf7e8ec1554c46144fe1da080fbaee5fc4c40d78d9bbc64991d4ff3b0117
|