Docs
Security
No vanity claims — these are the practical controls in place today, and the ones teams should verify before sending production events.
The two-key model
| Key | Prefix | Can write | Can read | Where it lives |
|---|---|---|---|---|
| Secret key | stl_sk_… | yes | yes | Server environment variables only |
| Public key | stl_pk_… | yes | no | Safe in browsers and public repos |
Public keys can only submit events — they can never query, list, or read anything. That's what makes auto-capture and the feed component safe to ship client-side. Keys are shown once at creation, stored hashed, and revocable instantly from the dashboard.
Tenant isolation
Every event, actor, and session is scoped to a project at the database level. API keys resolve to exactly one project, and every query filters on that project ID — there is no cross-project read path. Within your own product, you add the second boundary: scope customer-facing feeds by actor_id or target_id so each customer sees only their history.
Rate limiting
Redis-backed sliding window limits protect the ingest path:
- 1,000 requests/min per secret key
- 200 requests/min per public key (auto-capture batches events client-side to stay well under this)
Exceeding a limit returns 429; the SDKs swallow this silently so your app is never affected.
Transport & storage
- All API traffic is TLS-encrypted in transit.
- API keys are stored as hashes — plaintext is shown once at creation and never persisted.
- Auto-capture never reads form field values — only structural metadata (see Auto-Capture).
Your responsibilities
- Keep secret keys in environment variables, not code.
- Don't put secrets, tokens, or raw PII you can't store into event
metadata— it's stored as-is. - Scope customer-facing feed queries so tenants can't see each other's activity.
Evaluating Softechlog for a security-sensitive rollout? Schedule a technical call — we're happy to walk through the architecture.