Skip to main content

pineward (Python)

Stateless anti-bot form shield — server-side validation in pure Python (standard library + Pillow for the captcha renderer).

This is the Python reference implementation of Pineward's server validation: it verifies the HMAC tokens, Wesolowski VDF proofs, honeypots, behavior metrics, and instrumentation fingerprints produced by the JavaScript client. It is byte-compatible with @pineward/server — verified against the shared golden vectors in tests/vectors/v0-vectors.json (generated by the JS core).

Install

pip install pineward

Requires Python 3.10+. One runtime dependency — Pillow (renders the last-resort captcha); everything else is standard library. So pip install pineward ships the captcha out of the box.

Usage

from pineward import validate, ValidateOptions, MemoryNonceStore

opts = ValidateOptions(
    secret=b"my-secret-minimum-32-characters-long!!",
    expected_origin="https://yoursite.com",
    nonce_store=MemoryNonceStore(),   # use Redis/DB in serverless/multi-instance
)

# `submission` is the parsed form body: the __pw_* fields + formData.
submission = {
    "token": form["__pw_token"],
    "vdfProof": json.loads(form["__pw_vdf"]),
    "behavior": json.loads(form["__pw_behavior"]),
    "instrFingerprint": form["__pw_instr"],
    "formData": form,
}

result = validate(submission, opts)
if not result.ok:
    abort(403, f"pineward: {result.reason}")
# result.payload is the verified token payload

result.reason is one of: bad-token, expired, wrong-origin, replay, honeypot-tripped, bad-vdf, bad-instrumentation, bad-behavior.

For lightweight integrations, set skip_vdf=True and/or skip_instrumentation=True.

Last-resort captcha

Every layer above is invisible. The one visible layer is a server-rendered, adversarial-text captcha — the escalation target when a request looks automated. It verifies an answer (not forgeable client-reported motion): the challenge is rendered server-side with secret randomness, so the answer lives in the pixels and can't be precomputed from this open-source code — an agent has to actually read an image tuned to break general OCR/VLMs while staying human-legible. The signed token carries only an HMAC of the answer, never the text.

from pineward import issue_captcha, verify_captcha, CaptchaVerifyOptions, MemoryNonceStore

# escalate (e.g. when validate() soft-fails a forgeable signal) instead of hard-blocking:
ch = issue_captcha(secret=SECRET, form_id="contact", origin="https://yoursite.com")
#   -> ch.token (opaque, signed) + ch.png (bytes) / ch.data_url (for <img src>)

res = verify_captcha(
    {"captchaToken": token, "answer": user_typed},
    CaptchaVerifyOptions(secret=SECRET, expected_origin="https://yoursite.com",
                         nonce_store=MemoryNonceStore()),
)
# res.reason: bad-token | expired | wrong-origin | wrong-kind | replay | wrong-answer

Optionally also require the answer to have been typed (a forgeable, naive-bot filter — not a guarantee): pass keystrokes=KeystrokeConfig() to CaptchaVerifyOptions and include typing ({"t": [per-key ms], "paste": bool}) in the submission; a direct POST or pasted answer then fails with bad-keystrokes.

Rendering uses Pillow, which ships with pineward — nothing extra to install.

Bound brute-force with PineGuard (per-IP rate-limit) — see examples/captcha for the full escalation flow.

Public API

  • validate(submission, opts) · ValidateOptions · ValidateResult
  • verify_token / sign_token · verify_vdf / hash_to_prime / miller_rabin
  • score_behavior · check_honeypots / generate_honeypots · is_valid_instr_fingerprint
  • RateTracker / compute_t · MemoryNonceStore / NonceStore
  • PineGuard / GuardRule / GuardDecision
  • issue_captcha / verify_captcha / render_challenge · CaptchaVerifyOptions · check_keystrokes / KeystrokeConfig
  • ScoringConfig · DifficultyConfig · RSA_2048_MODULUS · FIELD_*

Develop

pip install -e '.[dev]'
pytest

The wire format is specified in the JS repo's spec/v0.md; the vectors here are the cross-language contract. If the token/VDF encoding changes, regenerate vectors on the JS side and copy them here.

License

MIT

Metadata

Release files for pineward 0.1.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 pineward 0.1.0
File Size Uploaded Provenance Actions
pineward-0.1.0.tar.gz 25.7 kB Without provenance Details for pineward-0.1.0.tar.gz

Built distribution (wheel)

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

Total release size: 49.7 kB

Release files / pineward-0.1.0.tar.gz

Download URL pineward-0.1.0.tar.gz
Size 25.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2b751ee22c23db6db7e6172f7827f93504063a0df532fff33096d725100f0826
BLAKE2b-256 checksum
How to use checksums
1dde1e570a4d302d4280e6b28ba46779831f9d801275b8cfae5562cefe0a057c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Release files / pineward-0.1.0-py3-none-any.whl

Download URL pineward-0.1.0-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de69c5c8737d7ca7ce756ada81f7b2bf1f5d1bd4fec185fde1ceb2434b4ee888
BLAKE2b-256 checksum
How to use checksums
c8fd2530a05fab2923cf6012c0132f8265b44537c7877f1565dba3d477024c54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Security for pineward 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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