Changelog
This is the user-facing history of what shipped in each ScaiLog release, drawn from the phased delivery plan. Entries describe the capabilities you can rely on, newest first. ScaiLog is licensed under Apache-2.0.
1.0.2 — 2026-08-25#
Python packaging fix. The [agent] extra was missing PyYAML, so
pip install scailog[agent] from 1.0.1 produced an agent that crashed on import
(the policy engine needs it). 1.0.2 completes the extra — this is the first
Python release where a clean pip install "scailog[agent]==1.0.2" yields a
runnable agent that carries the tenant fix below. The agent ships in this same
wheel, via the [agent] extra; there is no separate agent artifact. Python
1.0.1 has been withdrawn from downloads.
1.0.1 — 2026-08-25#
Critical fix, plus the Go package.
-
BUGFIX (critical): the split-topology agent no longer flattens per-entry tenants. In 1.0.0 the SDK made
tenantper-entry and the server honoured it, butscailog-agentignored the frame's tenant and stamped its own configured--tenanton every entry, encrypting PI under that single tenant's key. For a service logging on behalf of many tenants through one agent, that put one customer's PI under another's key — and because erasure and DSAR key on(tenant, subject), the correct tenant's erasure could never reach it. The agent now threadsframe["tenant"]through caching and encryption and enrols each tenant's key on demand; the configured--tenantis only a fallback for a single-tenant agent and never overrides an entry that named its own. Anyone running the split-topology agent must upgrade — the standalone/embedded agent was never affected. (The direct-HTTP ingest path was also never affected.) -
Go SDK packaging. The Go download is now a proper module archive (
scailog-go-1.0.1.tar.gz) usable via areplacedirective, and the import path isscailabs.ai/scailog-go— the previous github path never resolved.
1.0.0 — 2026-08-24#
First stable release. The SDK wire format and the public API are now covered by semantic versioning: no breaking change before 2.0.0. The breaking change below is made deliberately at 1.0.0, before anyone can depend on the old behaviour.
-
A global tenant namespace (
_global). Not every event happens in a tenant's context — bootstrap, a system-wide failure, cross-tenant maintenance do not. Those entries now declare the reserved tenant_globalrather than borrowing a real customer's identity or the single-tenantdefaultsentinel. It must be stated explicitly: an entry with no tenant is still rejected, and a tenant-scoped API key may not write there. -
Per-entry tenancy in all four SDKs.
tenantwas bound once when the logger was constructed, so a process serving many tenants either built a logger per tenant or labelled everything with one static value. It is now resolved per entry — explicit argument, then request context (context(tenant=…),withContext,WithTenant,LogContext.Push), then the logger default.Breaking: the fallback to the reserved
defaulttenant is gone. A logger with no tenant from any source now fails loudly instead of silently mislabelling every entry, which is unrecoverable after the fact. SetSCAILOG_TENANT, bind per request, or pass it per call. -
Call-site manifests are tenant-free. A manifest is derived from a service's source, so the same declaration holds for every tenant it serves. Declarations are stored once per
(service, call_site_id)— 100 sites across 1,000 tenants is 100 rows, not 100,000 — andscailog-ci pushno longer needs a tenant it cannot know.GET /v1/sites/declarationsexposes them directly. -
A provisioning role and suspendable keys.
log_provisionercan declare call sites and read the registry and nothing else, so a CI pipeline no longer needs the key-minting and policy-editing thatlog_admincarries. Any key can be suspended (reversible, unlike revocation) and resumed for a bounded window, and key administration is recorded in an audit trail readable withscailog keys history.
Phase 2#
Phase 2 broadens the SDK languages and adds the point-and-click and identity surfaces on top of the Phase 1 core. Everything here is additive — the CLI and built-in API keys from Phase 1 remain the primary, always-available path.
- TypeScript and Go SDKs (plus .NET). Wire-identical siblings of the Python
reference SDK — same
pi()markers, mandatory validatedcall_site_id, subject-required-for-PI, reserved-name rejection, ULIDs, and socket-NDJSON with stderr fallback. A log emitted from any language encrypts at ingest and decrypts back through DSAR identically. - Admin panel. A thin SolidJS + Tailwind + DaisyUI single-page app over the
server's
/v1API: dashboard, log search (with explain and single-field decrypt), live tail over SSE, sites, subjects (DSAR/erase), policies, keys, and audit. The CLI remains the primary interface; the panel is the complement. It carries no ScaiLog runtime dependency. - OIDC / SSO login. An optional identity plugin: the CLI logs in via the
OAuth 2.0 device flow (
scailog login), and the admin panel offers "Sign in with SSO" (Authorization Code + PKCE). The server validates the ID token and maps thescailog_roleclaim to a role. API keys stay the base mechanism and the system runs fully without OIDC. scailog-cifull validation and manifest push. The zero-dependency build-time validator checks call sites (constant, unique, well-formed ids; no message interpolation;pi()with a subject) and can push a call-site manifest to the server so drift shows up inscailog sites --diff.- Audit-guided targeted redaction.
scailog audit redactscrubs named plaintext fields that an audit flagged as untagged PI to[AUDIT_REDACTED]across a call site — an irreversible,dpo-only fix for PI that escaped tagging. - Signed report-key rotation. The report-signing key becomes a rotating
keyring (active plus retired keys); every DSAR report and erasure receipt embeds
its signing key's public key and
key_id, so documents stay verifiable after a rotation, and retired keys stay published atGET /v1/report-keys. - Prometheus
/metrics. The counters that must never be lost — panic drops, dead-letters, stderr fallbacks — are exposed as a Prometheus-format/metricsendpoint (and on/v1/status), so observability of the logger is metrics-shaped, avoiding a log-about-logging cycle.
Phase 1 — initial release#
The foundational release: the full GDPR-native logging path end to end, from SDK emit through encryption, storage, query, DSAR, and cryptographic erasure. Erasure by key-destruction ships here — it is the point of the product, not a later hardening step.
- Python SDK. The reference emit library: mandatory
call_site_id, field-levelpi()markers, automatic context propagation, and socket-NDJSON emit with a non-silent, PI-redacting stderr fallback. The base install is pure stdlib with zero third-party dependencies. - Per-host agent.
scailog-agentterminates the local socket, encrypts PI immediately with per-subject keys, caches to a local SQLite file, and ships zstd-NDJSON batches to the server with idempotency, backoff, resume-after-restart, and per-entry dead-lettering. Panic mode refuses to cache plaintext PI when the server is unreachable. - Central server. A single FastAPI service that ingests SLWP batches,
validates entries, applies the policy engine, encrypts any PI not already
encrypted by the agent, and writes to
scailog.db. Hosts the built-in key manager and the separatekeymap.db. - Policy engine. Declarative YAML with most-specific resolution and
versioning; four actions —
encrypt,redact,drop,keep— applied per PI type, service, and environment. - Cryptographic erasure and DSAR. Per-subject DEKs under a tenant KEK under the root key; erasure destroys the subject's key (crypto-shredding), leaving a tombstone and a signed erasure receipt. DSAR produces a signed subject report with decrypted PI.
- Operator CLI.
scailogwithquery,tail,sites,explain,dsar,erase,keys, andpolicycommands. - Built-in API-key authentication. Roles and capabilities, a minted-once bootstrap key, tenant/service scoping, expiry, rate limits, and IP allowlists — no external auth service required.
- Retention sweeper. Background enforcement of retention windows, including
the deliberately short backup retention on
keymap.db. - Standalone single-binary mode.
scailog-server --standaloneembeds the agent role — one process, one directory of SQLite files — as a first-class supported deployment. - SLWP test-vector suite. Normative Annex A crypto and wire-format vectors, re-checked by every SDK so the wire format cannot drift across languages.