OSS WhatsApp connector for the Terrene Delegate substrate (kailash.delegate).
Reason this release was yanked:
re-architect to plugins
Project description
delegate-connector-whatsapp
An OSS Python connector for the Terrene Delegate substrate. Implements the
shipped kailash.delegate.Connector ABC (kailash 2.26.2) for WhatsApp over the
first-party Meta Cloud API:
write— Cloud API outbound send (httpx POST /messages), executed under audit, returns a realSignedActionEnvelope. Every send passes the template / service-window pre-flight gate (below).read— drains verified inbound messages from the webhook ingest buffer, executed under audit, returns(messages, AttestedReadReceipt). Inbound is webhook-only: the connector ships the ingest protocol + buffer, NOT a running HTTP server (owning the public TLS socket is a deploy concern, not a connector-contract concern — WA-ADR-2).authenticate— resolves an E.164 sender to aPrincipalagainst thePrincipalDirectory(exact-match in v0; unknown sender → fail-closedRejectviaConnectorAuthenticationError).invoke— single-method dispatch entry (used by the dispatch hot path); dispatches a send and returns aConnectorInvocationResult.- Trust properties —
auth_verifierreturns the wiredEd25519Verifier;ledger/revocationreturn shipped concretes (framework-first; no custom trust primitives).
It subclasses Connector directly (mirroring email ADR-1) — NOT
LegacyInvokeConnector, whose proxied read/write emit empty, unverifiable
receipts. This connector's read/write produce non-empty receipts that verify
under a real Ed25519Verifier.
Security properties
- PII redaction — the raw E.164 recipient never enters a log, audit-bytes
payload, or ledger record. Persisted identity is a stable salted
HMAC-SHA256 token (
wa:<hex>); a redaction failure surfaces the<unredactable wa identity>sentinel, never the raw number. TheWHATSAPP_PII_HMAC_KEYstartup gate (RedactionConfig.from_env) makes an installation missing the key refuse to start — loud, not fail-soft. - Webhook HMAC boundary — inbound
X-Hub-Signature-256is verified constant-time; a tampered signature is refused and never reaches the buffer or the audit path. Thehub.verify_tokenhandshake echoeshub.challengeonly on an exact token match. - Outbound gating — free-form sends to a recipient outside the open 24h
customer-service window raise a typed
OutsideServiceWindowError; un-approved template names raiseTemplateNotApprovedError. Both are pre-flightRejects — NOT silent send failures — and fire NO Cloud API call. Approved templates are window-exempt (WA-ADR-4). The window tracker is bounded (LRU, default 100 000 entries) so the verified-inbound map cannot grow without limit. - Receipt identity-binding — receipts sign over the FULL identity (signer +
action/observed timestamps + content), not the bare payload; tampering ANY
bound field fails
verify_action_envelope/verify_read_receipt.
Commercial-gateway disposition (stated openly)
Apache-2.0, Foundation-owned. The network endpoint is unavoidably commercial
(Meta Cloud API) — the same shape as the email connector's commercial SMTP host.
The shipped code path couples to no intermediary vendor SDK: the transport is
a generic httpx client against Meta's first-party Graph API, and the endpoint
URL is config, not code (WA-ADR-1, journal 0002). There is no dependency on any
proprietary sibling.
Install
pip install -e connectors/whatsapp
Configure
All credentials come from the environment (see .env.example); nothing is
hardcoded, nothing is logged. .env is git-ignored — only .env.example is
committed. The seven keys:
| Key | Purpose |
|---|---|
WHATSAPP_ACCESS_TOKEN |
Cloud API bearer token (Graph API auth) |
WHATSAPP_PHONE_NUMBER_ID |
the sending phone-number id (Cloud API path) |
WHATSAPP_GRAPH_VERSION |
Graph API version segment (e.g. v21.0) |
WHATSAPP_APP_SECRET |
HMAC key for X-Hub-Signature-256 webhook verify |
WHATSAPP_WEBHOOK_VERIFY_TOKEN |
the hub.verify_token handshake secret |
WHATSAPP_PII_HMAC_KEY |
salt for the wa:-token PII redactor (startup-gated) |
WHATSAPP_APPROVED_TEMPLATES |
comma-separated approved-template allowlist |
Test
Tier-1 (unit, no I/O, no third-party transport lib required):
pip install -e "connectors/whatsapp[test]"
PYTHONPATH=connectors/whatsapp/src python -m pytest connectors/whatsapp/tests/unit -q
Tier-2 (in-process protocol-faithful Cloud API double — no mocks at the boundary, no Docker, no vendor SDK):
PYTHONPATH=connectors/whatsapp/src python -m pytest connectors/whatsapp/tests/integration -q
The Tier-2 double is an httpx.MockTransport-backed deterministic adapter that
speaks the Meta POST /messages request/response shape — a Protocol-satisfying
surrogate, NOT a mock of the connector or the Cloud API client. Tier-3 is a
single opt-in test_live_meta_sandbox that runs against the real Meta sandbox
only when live WHATSAPP_* credentials are present; absent them it skips with a
"cannot execute" reason (never a mock fallback).
Conformance (shared canonical vector set) and the permanent security regression suite:
PYTHONPATH=connectors/whatsapp/src python -m pytest \
connectors/whatsapp/tests/conformance connectors/whatsapp/tests/regression -q
Known limitation — runtime execute() audit gate
compose.py builds a real DelegateRuntime (over a DispatchSurface) around
the connector via build_whatsapp_runtime, driven with await runtime.execute(...)
(the dispatch entry is async — journal 0001). However the shipped
kailash.delegate runtime/dispatch
audit-emit path signs the event payload bytes while AuditChainEngine.emit_event
verifies the signature against the full audit-entry signing bytes — so
runtime.execute() fails at the first audit emission under any real verifier.
This is an SDK bug in kailash.delegate (kailash-py#1182), not in this
connector; the connector's own read/write receipts verify correctly (proven
in the Tier-1 suite). The end-to-end runtime.execute() assertion is gated on
the SDK fix (strict-xfail across the unit / integration / conformance suites);
the connector-level send round-trip and receipt verification are not.
License
Apache 2.0. All open-source IP is owned by the Terrene Foundation.
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 delegate_connector_whatsapp-0.1.0.tar.gz.
File metadata
- Download URL: delegate_connector_whatsapp-0.1.0.tar.gz
- Upload date:
- Size: 73.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4db0984bbef9de64c2c5c6dfe2f93f83059ab77af6e3ef59ef052c2582a0ff6
|
|
| MD5 |
58b9ed56cf96311d23943b6ec5d79600
|
|
| BLAKE2b-256 |
6d665fe65c85321364c52857d9199ce618560cc2c19ae7c549114a661846f638
|
File details
Details for the file delegate_connector_whatsapp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: delegate_connector_whatsapp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1669f4a039869ec239cbdaef52e4f7ba20ea51054cd8c5830e44adf485a1c3bd
|
|
| MD5 |
5180253cf9f10e18405be115da3c0b20
|
|
| BLAKE2b-256 |
70c0825c4038c2e88474d336add9d8362a079e11ff5f66cb84234efc687f19a6
|