CIPH4 Python SDK — zero-knowledge secret sharing, compliance, orgs, threats, audit, and webhooks
Project description
CIPH4 Python SDK
Zero-knowledge secret sharing, plus the full CIPH4 platform API: drops, orgs, compliance, reports, threats, webhooks, and audit. All drop creation encrypts locally with AES-256-GCM — the CIPH4 server never sees your plaintext.
Install
pip install ciph4
Quick start
import ciph4
client = ciph4.Client("ck_your_api_key")
print(client.drops.create_text("postgres://prod:s3cret@db:5432/app"))
That prints a https://ciph4.com/dd/.../#key=... link. Send it to your
recipient and it self-destructs after one view.
Sub-module overview
| Namespace | Purpose |
|---|---|
client.drops |
Create, list, revoke, archive, clone, bulk, receipt |
client.user |
Profile, plan, password, notifications |
client.user.mfa |
TOTP enrollment, backup codes |
client.user.account |
GDPR deletion lifecycle |
client.user.api_keys_* |
API key management (session-only auth) |
client.user.sessions_* |
Active session list / revoke |
client.file_requests |
Public file-request landing pages (uploads in) |
client.orgs |
Orgs CRUD, drops, storage, enforcement |
client.orgs.members |
Member list / invite / role / remove / bulk |
client.orgs.invites |
Link invites, email invites, accept |
client.orgs.security_policies |
Consolidated Security & Policies (P-Feat-1/3/4) |
client.orgs.mfa_policy |
Org MFA policy |
client.orgs.branding |
Branding (logo, colors, disclaimer) |
client.orgs.byok |
BYOK key configuration |
client.threats |
Threat alerts, bulk actions, CSV export |
client.threats.ip_rules |
Allow / deny IP rules |
client.compliance |
Controls, policies, risks, vendors, evidence |
client.reports |
Generate / list / poll / download reports |
client.audit |
Audit feed + hash-chain verification |
client.receipts |
Public Proof-of-Deletion receipt verifier + JWKS |
client.webhooks |
Webhook endpoints + deliveries |
client.billing |
Stripe checkout & customer portal |
client.analytics |
Usage analytics |
Zero-knowledge architecture
All drop encryption happens locally using AES-256-GCM. The CIPH4 server
only stores ciphertext. The encryption key is embedded in the URL
fragment (#key=...) which browsers never send to the server.
Your machine CIPH4 server Recipient
───────────── ──────────── ─────────
Generate AES key
Encrypt locally
Send ciphertext ────→ Store ciphertext
Key in URL fragment Never sees the key
Share link ──────────────────────────────→ Open link
Decrypt in browser
Delete ciphertext ←─ Link self-destructs
Examples
Drops
# Text drop with 24h expiry, 1 view
url = client.drops.create_text("db-pass-here", expires="24h", max_views=1)
# File drop with DRM (Enterprise)
url = client.drops.create_file(
"q2-report.pdf",
expires="7d",
max_views=3,
drm_enabled=True,
drm_watermark=True,
drm_no_print=True,
)
# List, revoke, archive
for d in client.drops.list():
print(d["id"], d.get("fileName") or "Text", d["maxViews"])
client.drops.revoke("clx_abc123")
client.drops.archive("clx_abc123")
# Bulk archive
client.drops.bulk(["clx_a", "clx_b"], action="archive")
# Proof-of-Deletion receipt (Enterprise)
receipt = client.drops.receipt("clx_abc123")
User & MFA
profile = client.user.profile_get()
client.user.profile_update(name="New Name")
client.user.plan()
# TOTP MFA (session-only auth)
enroll = client.user.mfa.enroll() # {qrCodeDataUrl, otpauthUrl, secret}
client.user.mfa.enroll_confirm("123456") # returns 10 backup codes
client.user.mfa.status()
# API keys (session-only auth, Enterprise)
keys = client.user.api_keys_list()
new = client.user.api_keys_create("CI runner") # plaintext returned once
client.user.api_keys_delete(new["id"])
Organizations
orgs = client.orgs.list()
org = client.orgs.create(name="Acme Corp")
# Members
client.orgs.members.add(org["id"], "bob@acme.com", role="USER")
client.orgs.members.bulk(org["id"], ["a@acme.com", "b@acme.com"], role="USER")
# Invites (link invites)
inv = client.orgs.invites.create(org["id"], role="USER", expires_in_days=7)
print(inv["acceptUrl"])
# Security & Policies (P-Feat-1/3/4)
client.orgs.security_policies.update(
org["id"],
mfa_required=True,
mfa_grace_days=7,
domain_allowlist=["acme.com", "subsidiary.com"],
max_expiry_hours=168,
default_drm_enabled=True,
default_drm_watermark=True,
)
Threats
client.threats.list(range="30d")
client.threats.bulk("resolve", ["alert_1", "alert_2"])
# IP rules
client.threats.ip_rules.create("203.0.113.5", type="deny", reason="brute force")
client.threats.ip_rules.list()
# CSV export (returns raw bytes)
csv_bytes = client.threats.export(range="30d")
open("threats.csv", "wb").write(csv_bytes)
Compliance (Enterprise)
dash = client.compliance.dashboard()
print(dash["score"], dash["kpis"])
# Update controls
client.compliance.control_update("ctrl_abc", status="passing", owner_id="clx_user")
# Policies
pol = client.compliance.policies_create(
name="Acceptable Use",
body_markdown="# Policy\n\n...",
requires_ack=True,
)
client.compliance.policies_acknowledge(pol["id"])
# Risks
client.compliance.risks_create(
title="Phishing exposure",
severity="high",
likelihood=3,
impact=4,
)
Reports
# Async generation — poll until ready
job = client.reports.generate("soc2-trust-services", format="PDF")
while True:
r = client.reports.get(job["id"])
if r["status"] == "ready":
break
time.sleep(5)
pdf_bytes = client.reports.download(job["id"])
open("soc2.pdf", "wb").write(pdf_bytes)
# Scheduled (recurring) reports
client.reports.scheduled_create("soc2-trust-services", cadence="weekly",
format="PDF", deliver_emails=["auditor@acme.com"])
Audit
feed = client.audit.list(range="30d", limit=500)
verdict = client.audit.verify()
assert verdict["intact"]
Receipts
# Fetch JWKS for offline verification
jwks = client.receipts.jwks()
# Hosted verifier
receipt = client.drops.receipt("clx_abc123") # signed deletion receipt
result = client.receipts.verify(receipt)
assert result["valid"]
Webhooks
client.webhooks.create(
url="https://example.com/ciph4-webhook",
events=["drop.viewed", "drop.burned", "drop.revoked"],
)
# The signing secret is in the response — store it now, it's only returned once.
client.webhooks.list()
client.webhooks.deliveries(take=50)
Error handling
from ciph4 import Client, CiphError, CiphAuthError
client = Client("ck_...")
try:
client.drops.revoke("clx_nonexistent")
except CiphAuthError as e:
print("Auth / permissions:", e.status_code, e.message)
except CiphError as e:
print("API error:", e.status_code, e.message)
CiphAuthError is a subclass of CiphError raised specifically on 401
and 403 responses, so you can catch either with except CiphError.
CLI
export CIPH4_API_KEY=ck_...
ciph4 share "my-database-password" # share text, 24h, 1 view
ciph4 share ./report.pdf --expires 7d # share file, 7 days
ciph4 list # list your drops
ciph4 revoke clx_abc123 # revoke a link
ciph4 audit # verify the audit hash chain
The CLI wraps client.drops.* and client.audit.* and uses the same
zero-knowledge encryption path as the Python API.
Legacy v1.0 compatibility
The v1.0 top-level methods still work as thin proxies to the new namespaces — no code changes required to upgrade:
| v1.0 method | v1.1 equivalent |
|---|---|
client.share_text(...) |
client.drops.create_text(...) |
client.share_file(...) |
client.drops.create_file(...) |
client.list_drops() |
client.drops.list() |
client.revoke(id) |
client.drops.revoke(id) |
client.get_drop(id) |
client.drops.get(id) |
client.get_plan() |
client.user.plan() |
client.get_analytics(range) |
client.analytics.get(range) |
client.get_threats(range) |
client.threats.list(range) |
client.verify_audit_chain() |
client.audit.verify() |
Version compatibility
| SDK version | CIPH4 API version | Notes |
|---|---|---|
| 1.1.0 | v1.0+ | Full 108-route wrapper, nested namespaces |
| 1.0.0 | v1.0+ | 10-method minimal wrapper |
Further reading
The authoritative API reference is API.md at the repo root. It
documents all 108 routes including request/response shapes, error
codes, rate limits, and plan gating.
License
MIT
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 ciph4-1.1.0.tar.gz.
File metadata
- Download URL: ciph4-1.1.0.tar.gz
- Upload date:
- Size: 27.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c2cfa4cefb589719e388208ab3831efa1ec0d47c130796544c8648d9044972d
|
|
| MD5 |
995bcbc75d1fc93f83b4ea0b1e0c2026
|
|
| BLAKE2b-256 |
706422330c87bf1462e92ed68fb80270a5309551a90e41d6644f3740a862eb81
|
File details
Details for the file ciph4-1.1.0-py3-none-any.whl.
File metadata
- Download URL: ciph4-1.1.0-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca10f47cecd85675076ff4003b20a3efa9f0bbe0a4341c6c48e2d32b5f0c80b2
|
|
| MD5 |
fca5763caca8073ca4d243487bf88aa9
|
|
| BLAKE2b-256 |
e76c31ace31e20c3876bdcdc68a9b1bbd7a1047e261f9f8f8d670fcbe31b6a69
|