Skip to content

ConfigStore::get is envelope-only on Fastly but a plain passthrough on Axum/Cloudflare #324

Description

@aram356

Problem

ConfigStore::get behaves differently across adapters for the same logical call:

  • Fastly (crates/edgezero-adapter-fastly/src/config_store.rs): get pipes every value through resolve_fastly_config_value, which requires the value to be a BlobEnvelope or a chunk pointer. A root value that is neither is rejected as an error.
  • Axum (crates/edgezero-adapter-axum/src/config_store.rs): get is a plain passthrough (Ok(self.data.get(key).cloned())).
  • Cloudflare: also a plain passthrough.

So the same ConfigStore::get(key) against the same logical store id succeeds on Axum/Cloudflare and errors on Fastly, purely because the stored value is a plain string rather than an envelope.

Why this bites

The app-config blob store legitimately holds a BlobEnvelope (and chunk pointers), so envelope resolution makes sense there. But apps also use other config stores that hold plain values — key material, ID lists, CIDR lists, feature flags. Binding those store ids to the Fastly ConfigStore makes every read fail, while the identical code path works on the other adapters.

The practical effect is that ConfigStore is only usable on Fastly for envelope-shaped stores, which is not obvious from the trait or its docs — the asymmetry is discovered at runtime, per adapter.

Ask

Make the behavior consistent, e.g. one of:

  1. Preferred: keep ConfigStore::get a plain passthrough on every adapter, and expose envelope/chunk resolution as an explicit, opt-in layer (a wrapper store or a separate method) that callers apply to the store that actually holds an envelope.
  2. Have Fastly's get fall back to returning the raw value when it is neither an envelope nor a chunk pointer, rather than erroring.
  3. At minimum, document the asymmetry prominently on the trait and adapter impls, so callers know a Fastly ConfigStore is envelope-only.

Workaround (downstream)

We bind only the app-config (envelope) store id to the chunk-aware Fastly ConfigStore, and bind every other config store id to a local plain ConfigStore over fastly::ConfigStore::try_get. It works, but it means we cannot use the provided store uniformly across our declared config ids.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions