Security & Compliance
Emban runs three kinds of request through three different auth paths, and applies org + tenant scoping at the storage engine level so a bug in application code can't leak another customer's data. This page documents the primitives — authentication, data isolation, audit, and outbound safety — so you can evaluate the platform against your own compliance requirements.
Authentication
/v1/auth/login. Passwords are hashed with bcrypt at default cost and only the hash is stored. The raw password is never logged or stored in cleartext. Sessions are cookie-based with httpOnly + Secure flags.
admin (full org control) and ingest (events only). Read-only access is modeled through user sessions for viewer/editor roles, not through read-scoped API keys. Keys are SHA-256 hashed before storage; only an 8-char prefix is kept in plaintext for operator identification. Raw keys are shown exactly once at creation.
admin API key. TTL is 1–24 hours (default 1h) and the token encodes the org, tenant, dashboard, and any locked filters. Expired tokens are rejected at the edge.
Authorization (RBAC)
Members of an org hold one of four roles, ordered by privilege. Higher roles inherit everything below them:
| Role | Rank | Can do |
|---|---|---|
owner | 4 | Everything admin can, plus transfer ownership and delete the org. Exactly one per org. |
admin | 3 | Publish dashboards, manage members/keys/billing, run adhoc SQL, read audit log, configure alerts/reports. |
editor | 2 | Create and edit draft dashboards, widgets, and saved queries. Cannot publish, invite members, or manage keys. |
viewer | 1 | Read-only access to the admin console. Can view published dashboards and existing widgets; cannot edit. |
An admin-scoped API key authenticates as admin for machine-to-machine calls. An ingest key can send events only and cannot read data, manage resources, or promote itself.
Data isolation
Every row in Emban carries an org_id and every query is scoped to it. The enforcement sits at the storage layer, not the handler, so a missing WHERE clause in application code cannot leak data.
org_id as part of every lookup. Cross-org references return 404, never 403 or 500, so we don't confirm the existence of another tenant's ID.
additional_table_filters pinning emban.events to the caller's org_id and environment, plus readonly=2 to block all mutations. The filter applies inside subqueries, UNIONs, and CTEs; there is no syntax the user can write to bypass it.
tenant_id at mint time. The dashboard rendered to your customer can only read events with that tenant ID — even if the underlying widget's SQL doesn't explicitly filter on tenant. See Tenants for the full model.
environment=production) and hide specific widgets from the customer-facing surface. See Permissions for the full contract and mode-of-action.
Audit log
The audit_log table records every state change in the control plane, with org scope, actor (email for session auth, key prefix for API keys), action, entity ID, structured metadata, and timestamp. On the Growth plan and above, it's browsable under Admin → Audit and readable via GET /v1/audit. On Free and Starter the table still fills (we never skip audit writes), but the read endpoint returns 402 until the plan is upgraded.
The action taxonomy, as of today:
| Category | Actions |
|---|---|
| Auth | auth.register, auth.login, auth.logout, invite.accept |
| Org & members | org.update, org.delete, member.invite, member.remove, member.role_change |
| API keys | api_key.create, api_key.delete |
| Dashboards | dashboard.create, dashboard.auto_create, dashboard.update, dashboard.publish, dashboard.unpublish, dashboard.restore_published, dashboard.delete |
| Widgets | widget.create, widget.update, widget.publish, widget.delete |
| Queries | query.adhoc.run, saved_query.create, saved_query.delete |
| Embed sessions | embed_session.create |
| Onboarding | onboarding.seed |
Audit rows carry enough metadata to reconstruct the action without exposing secrets — api_key.create records the label and prefix but never the raw key; query.adhoc.run records an SQL excerpt capped at 512 chars; member.role_change records the before/after role.
Outbound safety
localhost, *.local, metadata.google.internal, or any loopback/private/link-local IP are rejected. HTTP(S) only. See Webhooks.
report_runs for reports).
audit_log, and selected server errors are logged with structured context. Raw passwords, API keys, and JWTs are not written to audit rows. Response bodies are not logged by the application.
Transport & storage
- TLS — All inbound traffic terminates at TLS 1.2+. HTTP requests are redirected to HTTPS. Certificates rotate automatically via ACME.
- At-rest encryption — Postgres and ClickHouse volumes are backed by encrypted disks (LUKS + provider-side encryption). Backups are encrypted.
- Secrets — Application secrets (JWT signing key, SMTP credentials, database DSNs) live in environment variables, not in code or config files. Rotating a secret is a deploy, not a code change.
- Password hashing — bcrypt at default cost. Migration path exists to raise cost when server hardware improves.
What we don't do yet
Emban is in alpha. Several security features that larger enterprises may require are not yet implemented. Listing them explicitly so you can plan around them:
- HMAC-signed webhooks — today, receivers authenticate Emban POSTs by IP allowlist or path token. HMAC signing with per-rule secrets is on the roadmap.
- SSO / SAML — user logins are email + password. SSO integration (SAML, OIDC) is scoped for post-GA and is part of the enterprise conversation.
- Audit log retention tuning — audit rows are kept indefinitely by default. Configurable retention and export to S3/GCS are planned but not available self-serve.
- Customer-managed encryption keys (CMEK/BYOK) — infrastructure-level encryption only today. CMEK is an enterprise-tier conversation.
- Formal compliance certifications — SOC 2 Type II, ISO 27001, HIPAA BAAs are not in place. We are structured to support these but the audits have not been completed.
Operational posture
Day-to-day security tasks and playbooks live in the Runbook. That includes how to rotate API keys, how to revoke embed sessions, what to check during an ingestion anomaly, and how to export audit logs for an internal investigation. The Alpha Readiness page tracks which features are considered production-ready for specific customer profiles.