Skip to content

Add native AWS store providers - #414

Draft
ChristianPavilonis wants to merge 8 commits into
docs/outbound-http-specfrom
issue-410-native-store-providers
Draft

ChristianPavilonis wants to merge 8 commits into
docs/outbound-http-specfrom
issue-410-native-store-providers

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Select local, supplied or built-in native stores independently per logical ID, without changing portable store traits or requiring Send setup futures.
  • Add default-off AppConfig Agent and Secrets Manager immutable startup snapshots, plus independently selected live DynamoDB ordinary KV.
  • Preserve shared config/secret preparation quotas/deadlines and complete registries before the application initializer/listener. Wire generated features, SDK-free structural CLI validation and AWS-bound config-push refusal.

Design and boundaries

This adds native store providers, not a new HTTP runtime. edgezero-store-aws implements the existing core store traits and does not depend on Axum. Axum owns provider selection and startup composition; core owns portable handles, per-ID registries and typed configuration resolution.

The portable edgezero.toml declares logical store IDs and defaults. AWS resource references belong in a separate versioned native bindings document, selected through an absolute file path in EDGEZERO__STORE_BINDINGS_FILE or through explicit AxumRunOptions. Applications can also supply ready handles or non-Send deferred setup, without a plugin registry.

Each declared ID selects one supplied, explicitly bound or implicit local source. Supplied/file collisions and undeclared IDs are rejected. The runner validates all sources before opening runner-owned local stores or polling deferred setup. CONFIG_DIR/DATA_DIR are required only for remaining local bindings. An unavailable selected provider fails startup; it never falls back to local data.

Provider Store contract Runtime behavior
AppConfig Agent Whole-document ConfigStore reads Immutable startup snapshot; restart to adopt changes
Secrets Manager Whole-value SecretStore reads Immutable startup snapshot; restart to adopt changes
DynamoDB Ordinary KvStore operations Live storage with fresh per-operation budgets
flowchart TD
    Bindings[Bindings and supplied inputs] --> Validate[Validate sources and compiled providers]
    Validate --> Prepare[Assemble app and prepare stores in the native runtime]
    Prepare --> Registries[Complete per-ID registries]
    Registries --> Initialize[Run app-owned initializer when supplied]
    Initialize --> Serve[Bind listener and serve requests]
Loading

One shared AWS preparation session owns startup budgets, client reuse and snapshot deduplication. The initializer receives the same registries used by requests. The application chooses its required config keys, schemas, secret checks and retained startup state; the framework does not infer those requirements or promise an atomic revision across remote resources.

AWS features are default-off and native-only. Existing entrypoints retain their local defaults; newly generated entrypoints select strict startup only when the bindings-file locator is present. Trusted Server adoption is separate work, and this does not claim a source-compatible upgrade from older EdgeZero versions across the #275/#406 prerequisites.

Diagnostic limitation: EdgeZero-owned errors/debug output discard or redact provider details. AWS SDK/dependency DEBUG/TRACE is not suppressed and can expose resource names and credential-source metadata. DynamoDB model Debug can also expose item keys and values, including binary hex, without enabling sensitive-body logging. LOG_SENSITIVE_BODIES=true can expose further response details. Operators must review dependency logging filters. No scoped/global subscriber suppression or application-wide logging policy is installed.

Stack and scope

Existing draft stack member based on docs/outbound-http-spec / #275 at ea66eff045512cccc60646d6ec339e83ff44fed7, with the compatible #406 production lifecycle bridge. Neither prerequisite PR was rewritten or merged. The user approved adding DynamoDB on this same branch/PR and committing/pushing it after checks.

Real AWS/IAM/capacity/deployment/image acceptance remains explicitly excluded. No real AWS service calls, infrastructure changes, image pulls or deployments were performed. SDK fixtures use dummy credentials, isolated or bypassed profile discovery, and literal-loopback endpoints.

DynamoDB KV

  • Independent default-off dynamodb-kv provider / generated aws-dynamodb feature; existing aws-stores remains AppConfig Agent + Secrets Manager only.
  • Strict v1 [kv.<id>] binding with explicit region/table/physical namespace, no credential or endpoint fields. Normal operator-owned SDK credential/endpoint policy remains supported.
  • Operator-owned ACTIVE, single-region, unindexed String pk/sk table; bounded DescribeTable preflight, exact table-name/schema checking, no provisioning or local fallback. All-remote KV needs no DATA_DIR.
  • Exact UTF-8 keys and arbitrary/empty binary values; 384 KiB payload cap. Millisecond logical expiry plus rounded-up service TTL; ordinary Put clears expiry and expired reads never delete renewed rows.
  • Strong Get/ascending base-table Query, one Query per page, scoped/versioned bounded cursors. Short/empty pages with continuation are valid. No CAS, atomic read-modify-write, snapshot pages or distributed identity-graph guarantee.
  • Fresh bounded runtime deadlines; one SDK attempt, no retry loop. Put/Delete can commit before returning an error. DescribeTable does not certify deployed IAM/write permissions/capacity.

DynamoDB is live storage, not a retained startup snapshot. The existing default 8 MiB retained-payload cap is per shared config/secret preparation session, not process/RSS or live database contents. Config/secrets still adopt remote changes only on restart; no live config/secret refresh or mutation is added.

Bindings validation remains structural-only / provider availability unknown. No offline Cargo resolver or guessed availability verdict is shipped. Custom shell actions remain untouched.

Verification

Original snapshot phase: all 24 post-rebase gates passed at its recorded source checkpoint; historical evidence remains in the original spec/plan and /tmp/native-store-integration/final-checks/. This does not claim those old results prove the later DynamoDB edits.

DynamoDB extension: 20 code gates plus docs lint/full-format/build passed, against an archived exact staged source tree independent of eight pre-existing dirty files. SHA-256 input manifests matched; later publication-record edits are Markdown-only.

  • Workspace default tests: 1,999 passed, 0 failed, 16 ignored; required native/provider feature scopes and generated consumers executed separately, not a claim that every unrelated ignored test ran.
  • Provider library: DynamoDB 44, Agent 26, Secrets 26, combined 74.
  • Native DynamoDB-only library 229; all-feature native test/doc suites 302.
  • Actual CLI-generated DynamoDB consumer: default-off refusal before SDK I/O, enabled put/get/list/TTL-write/read, retained data after restart, and delete.
  • Existing actual CLI-generated AppConfig/Secrets consumer rerun successfully.
  • Strict workspace all-target/all-feature Clippy; isolated provider scopes; native default Clippy; strict provider/native rustdoc; fmt.
  • SDK isolation, unchanged aws-stores membership, Cloudflare/Fastly/Spin WASM checks.
  • Actual SDK wire/shared KV contracts, Unicode NFC/NFD, binary/empty/size/key boundaries, millisecond expiry/renewal/reset, malformed expiry, short/empty continuation pages, cursor/table scope, closed denial/missing/stall errors.
  • Ambiguous Put/Delete fixtures apply the mutation before a scripted 500, then verify Unavailable, one attempt and the retained/removed row. SDK model Debug disclosure is directly asserted.
  • Mixed DynamoDB/local/ready/non-Send deferred source validation without polling/opening another local store; existing generic native staging atomicity/drop tests preserved.
  • Separate end-to-end generated edgezero serve invocation; shared argument/action selection has unit/source proof, generated build and startup are executed.
  • Real AWS acceptance, intentionally excluded; fixtures do not establish deployed IAM/capacity or the service's 1 MiB evaluation boundary.

An inherited Secrets timeout test transiently returned Unavailable instead of Deadline under the combined parallel run. It passed alone, then all 74 provider tests passed serially. The initial failure log is retained; no production/unrelated test was changed to hide it.

Commands/fingerprints: /tmp/dynamodb-baseline/final-checks.sh, /tmp/dynamodb-baseline/final/, snapshot-{before,after}.sha256; checked source tree 2fa76fb26377cf41203c255f924d988d6b657002. Final read-only provider review found no confirmed defects and is separate from executed checks.

Closes

Closes #410

Checklist

  • Portable store traits and handles unchanged; native AWS dependencies feature/target gated
  • Per-ID KV/config/secret registries; non-Send setup preserved
  • Source-free owned errors, no subscriber suppression
  • Deterministic actual-SDK loopback proof; no real credentials committed
  • Unrelated baseline hunks in eight modified files preserved and excluded from the DynamoDB commits

@ChristianPavilonis ChristianPavilonis self-assigned this Oct 8, 2026
@ChristianPavilonis ChristianPavilonis changed the title issue 410 native store providers Add per-ID native AWS store providers Oct 8, 2026
Share platform-aware prefix matching across environment capture, duplicate validation, and generated startup selection. Add isolated casing and non-Unicode regressions, and document the checked-in generated store proofs.
Run generated application contracts against pinned DynamoDB Local, Moto, and AppConfig Agent services in CI. Add fixture administration and runner tests, document coverage and emulator limitations, and type built-in store sources by binding kind.
@ChristianPavilonis ChristianPavilonis changed the title Add per-ID native AWS store providers Add native AWS store providers Oct 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant