ampbase

OPAMP CONTROL PLANE

Documentation

Feature flags

A feature flag in Ampbase decides "which configuration version does this agent receive?" — and that decision can be conditional. The simplest deploy bypasses flags entirely (the configuration's deployed-version pointer is what every agent gets). Flags layer on top of that, replacing the direct pointer with a routing decision per agent.

Use flags whenever you need to roll a config change out gradually: canary one fleet, ramp by region, A/B two variants, or emergency-rollback in one edit.

Flag definitions sync to each channel every few seconds and evaluate in-process — there's no extra hop in the agent connection path.

Variants

A flag holds one or more variants. Each variant has:

  • A variant key (a label like stable, canary, v3.5-beta).
  • A weight between 0 and 100. Weights across variants must sum to 100.
  • A target: either a configuration version or a bundle version.
flag: collector-rollout
├── variant "stable":  weight 90  →  config "otelcol"   version 01HJK...
└── variant "canary":  weight 10  →  config "otelcol"   version 01HJL...

Weight bucketing is deterministic per agent (hash of the agent ID), so an agent stays in the same bucket across reconnects. You won't see an agent oscillate between v3 and v4 every poll.

Targeting rules

On top of weighted bucketing, each variant can carry a targeting rule. Rules are written in JSONLogic over the agent's attributes — anything you set under agent.attributes in supervisor.yaml, plus implicit channel_id and agent_id.

A region-canary rule:

{ "==": [{ "var": "region" }, "us-east-1"] }

Agents whose region attribute matches us-east-1 evaluate that variant; everyone else falls through to the next variant or the default.

Rules can compose freely with the full JSONLogic operator set (and, or, in, regex via match, numeric comparisons), so combinations like "agents in us-east-1 running collector version ≥ 0.95" are one expression.

Targets: configs and bundles

A variant points at either a single configuration version or a bundle version.

  • Config targetconfig_id plus an optional version_ulid. Omit the version to track the configuration's latest version — a new save reaches flagged agents on their next check-in, no separate deploy step.
  • Bundle targetbundle_id plus an optional version_ulid. Same semantics, but targets a bundle: re-saving the bundle rolls the new version to flagged agents.

Pinning is useful for ramps where you want the canary to stay on an exact build even as stable advances.

Build eligibility

Targeting rules are the condition you write. There is a second condition you don't: a variant reaches an agent only if that agent's build can actually run the configuration the variant targets.

You don't configure this. There's no component matcher and no picker to fill in. The requirement is derived from the config version a variant points at — every component that configuration names, whether it wires it into a pipeline or only defines it — and compared against the inventory each agent reports about its own build (see Supervisor reference, under Component inventory). Because it's derived rather than authored, it can't drift from the config it describes, and there's nothing to forget to add.

When an agent's build lacks something the variant's target needs, the variant is withheld from that agent, and the agent receives the channel default — the same config it would get if no rule had matched it. The default is never gated: an ineligible agent keeps running your stable config rather than being left without one. Withheld is not re-routed. Weight bucketing's choice still stands; it simply isn't delivered.

   an agent checks in
        │
        ▼
   do this flag's rules and weights pick a variant?
        │
        ├─ no  ─▶ the channel default
        │
        └─ yes ─▶ can this agent's build run what that
                  variant targets?
                       │
                       ├─ yes ─▶ the variant's target
                       │
                       └─ no  ─▶ variant withheld;
                                 the channel default

Where you see every decision it makes

  • The flag editor, on each variant row. What that variant's target needs and how much of the channel can run it, while you're authoring and before you save: needs exporter/kafka · 480 of 500 agents eligible · 12 missing exporter/kafka. It names the version it assessed, which matters for an unpinned target — that tracks its config's latest, so the readout tells you which version the numbers are about.
  • The flag page, under Component eligibility. The decisions actually recorded at the last check-in, not a prediction: Of 500 targeted agents at last heartbeat: 460 eligible · 40 withheld. Withheld agents are grouped by reason, and each group names its remedy — add the component to the agent build, upgrade the supervisor so the build reports its inventory, review the target version's config.
  • The agent's flag trace. Open an agent, go to Flag evaluation, and the gate is its own step in the trace for that flag — variant "canary" withheld, then build missing exporter/kafka · serving the channel default, naming the version it was judged against.

What counts as eligible

  • A build that has never reported an inventory is unchecked, not fine. If the variant's target requires any components, the variant is withheld from that agent until its supervisor is upgraded to a release that reports an inventory and the first one arrives. Failing to prove a component is missing isn't evidence that it's there. On the rollout panel these agents appear as No manifest reported.
  • A target that requires no components runs on any build, so nothing is withheld from anyone — including agents that have never reported.
  • Agent types with no build-time components are always eligible. Refinery, Tetragon and AI coding agents have nothing a build of them could be missing.
  • If the target version's requirements can't be derived, the variant is withheld from everyone until you target a version whose requirements can be. An unreadable requirement is never treated as "requires nothing" — the editor readout says so in place, so you find out while authoring rather than from a stalled rollout.

None of this blocks you from saving a flag or pointing a variant anywhere. An all-ineligible variant is simply inert: every agent it would have reached falls to the channel default, so there's nothing to acknowledge — only something to read. The one action that does carry friction is setting a channel default, which is ungated by design; see Configurations, under Build requirements and fleet coverage.

Renamed components are recognized

Eligibility is judged against what a build reports, and components are sometimes renamed upstream — a collector that used to list otlphttp may list otlp_http instead. Ampbase recognizes those as the same component: builds report the module each component comes from, and when the name your config uses and the name the build reports resolve to the same module, the build counts as having it.

You do not have to rewrite your config after an agent upgrade, and you do not have to keep two spellings in flight while a fleet upgrades — a config using either name is eligible on builds reporting either name.

Where a rename decided an outcome, it is stated rather than folded away. The coverage readouts count it separately (480 supported · 12 via a renamed component), the flag trace names the pair on the agent that received the variant, and the components card marks the row with the spelling that build reports.

A component that is genuinely absent is still missing — the recognition needs a matching module, not a similar name.

Typical rollouts

Pattern How
Direct deploy One variant at weight 100.
Canary 10% Two variants: stable 90, canary 10. Bump canary's weight as confidence grows.
Region-by-region A targeted variant per region you've shipped to; default variant for everyone else.
A/B experiment Two equally-weighted variants pointing at different configs. Pair with metrics in your existing observability stack to compare.
Emergency rollback Edit the flag: flip canary to 0%, stable back to 100%. Agents pick up on next message.

Working with flags

  • New flag — UI: Feature flags → New flag, or the FeatureFlagService.CreateFlag RPC.
  • Variant edits propagate within a few seconds to every connected agent.
  • Every flag change is recorded in the channel audit log.

Spotted a problem with these docs? Email support@ampbase.io.