Product

Three primitives. One slice axis per layer.

Customer → Product → Tenant. The Customer is your workspace — billing, users, allowed domains. The Product is what your SDK authenticates as — its own apiKey, its own flag namespace, its own audit stream. The Tenant is the slice your flag value resolves for — a B2B customer organisation, a brand variant of one codebase, a region, a cohort. Same data shape, same override semantics, same audit boundary regardless of what you're slicing by. Every flag, every rule, every audit row is scoped at the storage layer — bypass is impossible because the row can't be written without all three.

Architecture

The whole platform is built around three data layers.

MVP runs on Firebase. A custom data plane is a post-PMF decision, not day one.

Layer 04SDK
evaluate() subscribe() audit()
Layer 03Rules
flag tenant override rollout approval
Layer 02Tenant
tenant_id env scope region
Layer 01Storage
firestore onSnapshot · change log cloud functions
SDK

Per-Product apiKey. Per-tenant evaluation.

Each Product has its own apiKey — the SDK uses it to identify which Product's flags to fetch. For multi-tenant Products, the evaluation API also requires a tenantId, enforced server-side. iOS, Android, and Web SDKs ship today, pushing flag changes in real time via Firestore listeners (~1s, no polling). Web ships as two packages — @argus/client for the browser (real-time) and @argus/node for server-side pull / SSR. Edge resolution lands in v1.5.

typescript · argus-sdk@v0
// 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.
Web SDK

Drop Argus into the browser and the server.

The Web SDK ships as two packages that share one read-scoped apiKey. @argus/client runs in the browser: it seeds flag values with a single resolveFlags pull, then subscribes to a Firestore listener so changes land in real time (~1s, no polling). @argus/node runs on the server for SSR and request-scoped evaluation, and serialises resolved flags so the browser hydrates without a second round trip. Same shape as the iOS and Android SDKs — one apiKey per Product, an optional tenantId for multi-tenant resolution.

typescript · @argus/client
// browser · real-time via Firestore listener
import { init } from "@argus/client";

const argus = await init({
  apiKey:   import.meta.env.ARGUS_KEY,
  baseUrl:  "https://api.your-argus.cloud",
  tenantId: "acme_retail",   // optional
});

if (argus.getFlag("new_billing_v2", false))
  renderNewBilling();

// re-renders when a flag flips, live
argus.onChange((flags) => paint(flags));

// React: import { useFlag } from "@argus/client/react"
argus.close(); // detach the listener
typescript · @argus/node
// server · request-scoped pull + SSR hydration
import { createClient } from "@argus/node";

const argus = createClient({
  apiKey:  process.env.ARGUS_KEY,   // same key
  baseUrl: "https://api.your-argus.cloud",
});

const ctx = { userId: user.id, tenantId: "acme_retail" };
const on = await argus.getFlag("new_billing_v2", false, ctx);

// hand the resolved set to the browser, no re-fetch
res.locals.argusState = argus.serialize(ctx);
// → @argus/client picks it up to hydrate instantly.

baseUrl is your Cloud Functions origin. One read-scoped apiKey covers both packages — there is no public / secret split. The init and resolution API shown here is shipped today; the npm packages publish with v1 — until then a preview build is available from the SDK repository.

MCP

Manage flags from your AI coding agent.

Argus ships a local MCP server (argus-mcp) so an AI coding agent — Claude Code, Cursor, and the like — can manage feature flags from inside a coding session: list, create, and publish flags, set per-environment values, and toggle them, without leaving the editor.

01 · Governed by default

New flags land as DRAFT — invisible to SDKs until published.

Changing a prod value requires explicit confirmation. The agent gets reach, not a blank cheque.

02 · Every mutation audited

The agent writes to the same audit log as a human.

Each change records actor, timestamp, env, tenant, flag, before, and after — tagged as the agent. Append-only, same as any other change.

03 · Founder / local today

Runs as a local stdio server, authenticated with a local service-account key.

No per-agent tokens yet. A productized, multi-tenant MCP with per-agent revocable tokens is on the roadmap.

Tenant overrides

Resolution order, plainly stated.

Tenant override documents are first-class — not a special case of segments. They have their own audit stream and resolution lane.

Default
flag default value at evaluation time
Flag rule
global rule (env, segment, version target)
Tenant override
tenant-owned override document · audited
Rollout
per-tenant % · deterministic per-user bucket (seed + userId)
Resolved value
flag.on · with source metadata in response
Audit row
append-only · tenant-scoped · reconciled
Approvals & RBAC

Two engineers approve prod. Roles scope to tenant.

01 · Two-engineer approval

Production-impacting changes require a second reviewer.

Approval is a flow, not a checkbox. Requested → assigned → approved → applied. Each step writes an audit row.

approval · requested · by shahin just now
awaiting 1 of 2 · reviewers marco, roberto
02 · Tenant-scoped RBAC

Three roles, each a strict superset of the last.

A contributor changes dev and proposes everything higher. An approver approves changes and sets dev / staging directly. A super_user owns prod and user management.

Roledevstagingprodapproveusers
contributor
approver
super_user
Audit log

Append-only. Product- and tenant-scoped. Source metadata travels.

Every resolution response carries the source of the value (default · rule · override · rollout). Every change writes a row you can query by product and tenant.

argus / audit · tenant=98chimp streaming
flag=new_billing_v2 tenant=98chimp env=prod before=off after=50% actor=shahin just now
approval=applied flag=new_billing_v2 approvers=marco, shahin 2m
override=created flag=kyc_lite tenant=98chimp value=on 14m
rbac=grant role=approver scope=tenant:98chimp subject=roberto@98chimp.com 38m
4 rows · last 1h · exportable to your siem append-only
Capability matrix

Multi-tenancy as the first row, not a checkbox.

Honest comparison against the alternatives most teams already run. We update this page as the tools ship changes.

Capability Argus LaunchDarkly Statsig Flagsmith DIY
Tenant as first-class primitive
Scoped audit log per tenant
Two-engineer prod approval
Deterministic per-tenant rollout (hash)
Self-host parity (control + data plane)
Pricing not coupled to end-customer MAU
● built   ◐ partial   ✓ via add-on   ○ none   ·   source · manus apr 2026, vendor docs apr 2026
Roadmap

Plain text. Honest horizons.

Shipping now

v0 · MVP on Firebase

  • Tenant-scoped evaluation API
  • Per-tenant override documents
  • iOS, Android + Web SDKs (real-time push)
  • Two-engineer prod approval
  • Tenant-scoped RBAC
  • Immutable audit rows
  • Reversible tenant-scoped rollback
Next 60 days

v1 · with design partners

  • Tenant feature matrix export (CSV + API)
  • Audit feed export to customer SIEM
  • Self-host helm chart (control + data parity)
On the roadmap

v1.5+ · with proof

  • Edge resolution
  • Code-reference scanning · dead flag detection
  • SOC 2 audit export packaging
  • Operational AI · tenant rollout suggestions from history
What's next

Start free, or see the pricing.

Free is $0 with no card. Growth is $99/month, with a per-tenant discount curve for multi-tenant portfolios. The full breakdown is on the pricing page.