Engineers paste tenant_id into segmentation rules.
User segments become a parking lot for org IDs. Audits can't tell tenant scope from cohort experiment from kill switch.
Argus is per-tenant feature flags with an audit log nothing escapes — for the SaaS that ships once and serves many.
User segments become a parking lot for org IDs. Audits can't tell tenant scope from cohort experiment from kill switch.
"Disable for tenant B" requires deploying a config that touches A, C, D too. Reversibility is theatre.
When a regulated customer asks what changed in their environment last quarter, the answer is grep plus apologies.
Customer-facing teams have no live, tenant-scoped view of who has what. Eng becomes a support escalation queue.
Tenant is required at evaluation time. Tenant changes write tenant-scoped audit rows. Bypass is impossible — not because the SDK asks nicely, but because the row can't be written without one.
Tenant matrix as a first-class object — not a flag-by-flag spreadsheet rebuilt in Notion.
Actor, timestamp, env, tenant, flag, before, after. Required — not configurable.
Deterministic percentage rollouts hashed by tenant_id and flag_key. Same input, same outcome, every time.
Once tenant scoping is mandatory, every downstream property — audit, isolation, blast radius, pricing — falls out for free.
// scoped, deterministic, reversible const flag = await argus.evaluate({ key: "new_billing_v2", tenant: ctx.tenantId, // required env: "prod", }); if (flag.on) renderNewBilling(); // → audit row written, scoped to tenant. // → reversible from the dashboard in one click. // → impossible to evaluate without a tenant.
Argus comes out of years running multi-tenant SaaS where every "roll out for tenant B" was a custom rule, a Slack thread, and a held breath. We're shipping the layer we wished we had — and we're picking three design partners to ship it with.