Cloud vs Self-Hosted Parity Matrix
The design commitment: the self-hostedknoxcall/proxy Docker image is the same binary KnoxCall Cloud runs at *.knoxcall.com. The router logic, the secret-injection engine, the rate limits, the audit log, the alert monitor — identical code. Where behaviour diverges it’s because the underlying resource is only available in one mode, and we document each exception here.
Quick Summary
| Status | Meaning |
|---|---|
| ✅ Full | Same code path, same result — no customer work required. |
| 🔑 Customer-provided | Same code path; you supply the credential (SMTP, Twilio, S3, etc.). |
| ⚠️ Reduced | Works with a downgraded resource (e.g. free MaxMind vs paid); upgradeable with your key. |
| ☁️ Cloud-only | Feature depends on KnoxCall-operated infrastructure that self-hosted doesn’t replicate. |
GET /admin/parity-audit — the admin UI renders it under Settings → Deployment → Feature parity.
Routing & Transformation
| Feature | Status | Notes |
|---|---|---|
| Route matching by subdomain / path | ✅ Full | Same resolver; tenant resolved from Host. |
| Secret injection (headers + body) | ✅ Full | Same Liquid template engine, same placeholder syntax. |
| Response transformation + log obfuscation | ✅ Full | Identical rules. |
| OAuth2 access-token refresh | ✅ Full | Refresh tokens re-encrypted in the session bundle, refreshed locally. |
| Rolling URL / request signing | ✅ Full | Same HMAC verification. |
| mTLS to upstream APIs | ✅ Full | Client certs re-encrypted in bundle, TLS terminated locally. |
| HTTP method restrictions | ✅ Full | Identical allowed-method enforcement per route/environment. |
| Per-route IP allowlist | ✅ Full | Client IP resolution identical (trust-proxy-1 CF headers). |
| Webhook dispatch | ✅ Full | Customer-defined URLs work the same. |
Security
| Feature | Status | Notes |
|---|---|---|
| Per-route rate limiting | ✅ Full | Requires Redis — customer provides locally in self-hosted. |
| Per-tenant rate limiting | ✅ Full | Same. |
| Single-tenant enforcement (self-hosted) | ✅ Full | Self-hosted refuses foreign tenants; cloud serves all. |
| Binary tamper seal | ✅ Full | Same build_sig verified on every session fetch. |
| Machine-fingerprint binding | ✅ Full | Agent bound to its host on first fetch. Details |
| Nonce + timestamp replay protection | ✅ Full | Rejected if the same nonce is seen within the 10-min window. |
| Audit log hash chain | ✅ Full | Same schema + verification. |
Analytics & Alerts
| Feature | Status | Notes |
|---|---|---|
| Per-request API logs | ✅ Full | Written locally on self-hosted; aggregated counts sync to control plane. |
| Alert monitoring + notification queue | ✅ Full | Same evaluator, delivery uses your integrations. |
| AI anomaly detection | 🔑 Customer-provided | BYO Anthropic API key under Settings → Integrations. |
| Real-time geo map | ⚠️ Reduced | Bundled MaxMind free DB; upgrade to your paid license for full accuracy. |
| Per-tenant usage metering | ✅ Full | Usage reported to control plane every 60s for admin-UI display. |
Integrations
| Feature | Status | Notes |
|---|---|---|
| Email (alerts / invites / resets) | 🔑 Customer-provided | Resend / SendGrid / Postmark / Mailgun / SES / SMTP. Required on self-hosted. |
| SMS alerts (Twilio) | 🔑 Customer-provided | Customer Twilio credentials, identical delivery logic. |
| Response-body archival (S3/R2/MinIO) | 🔑 Customer-provided | Any S3-compatible endpoint. |
| Slack alert webhooks | ✅ Full | Configured per-webhook. |
| Stripe billing | ☁️ Cloud-only | Self-hosted plans are billed as a flat Enterprise license. |
| KnoxCall-managed DigitalOcean egress | ☁️ Cloud-only | Run your own egress proxy behind the container if needed. |
Lifecycle
| Feature | Status | Notes |
|---|---|---|
| Migration wizard (cloud ↔ self-hosted) | ✅ Full | Readiness check + shadow test + one-click cutover in both directions. |
| Email branding + template overrides | ✅ Full | Same Settings → Integrations UI. |
| Team invitations + role changes | ✅ Full | Admin auth always flows through the control plane. |
What “Same binary” Actually Means
- We build one Docker image per release:
knoxcall/proxy:{version}. - That image runs on our servers at knoxcall.com AND on your self-hosted infrastructure.
- The only difference is environment configuration:
KNOXCALL_DEPLOYMENT_MODE=cloud | self_hosted, which tenant it serves, and which external credentials it’s given. - No forked codebase, no “Enterprise Edition”, no minus-features stripped out. When we ship a new feature on cloud, it arrives in the next self-hosted image pull.
Self-Hosted is Not a Subset
A common worry: “self-hosted versions of SaaS products are always stripped down.” That’s not our model. Self-hosted has more required configuration (you bring your own SMTP, Redis, Postgres, MaxMind, etc.) but the runtime behaviour is identical. What the customer loses in self-hosted is:- The cloud operator doing ops for you — you back up your own Postgres, rotate your own secrets, watch your own alerts. We still push the control-plane config (routes, secrets, feature flags) but the data plane is yours to operate.
- Cross-tenant features we haven’t yet made portable — Stripe billing, KnoxCall-branded egress IPs, the global AI anomaly model trained across tenants. These stay cloud-only.
How We Enforce Parity
Three mechanisms:- Source identity. Both modes compile from the same
src/. CI rebuilds the image on every merge. - Shadow testing during migration. The migration wizard dual-sends real requests through both sides and diffs responses before letting you cut over.
- This document. Every known divergence is listed. If you find a feature that behaves differently and isn’t in the Cloud-only row, that’s a bug — email us.