mirror of
https://github.com/s2-streamstore/s2.git
synced 2026-09-27 18:19:36 +00:00
**Detail bug report:** [View on Detail](https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/bugs/bug_8cac9425-ce79-4db4-b569-bf59c78d8d81) Closes #778 ## Bug In `lite/src/server.rs`, `s3_builder()` builds the `object_store` AWS S3 client backing SlateDB. It branches on whether static env credentials (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`) are present: - The **static-credentials arm** set credentials but never resolved the region — it relied solely on `AmazonS3Builder::from_env()`, which reads only `AWS_*` env vars and silently falls back to `us-east-1` when `AWS_REGION`/`AWS_DEFAULT_REGION` are unset. - The **sibling `_ =>` arm** resolved region from the full AWS default chain (env → profile → IMDS) via `aws_config::load_defaults` and called `with_region`. The two arms of the same `match` resolved the same field (`region`) by different chains. A deployment that supplied credentials via env but region via `~/.aws/config` hit the static arm, dropped the profile region, and targeted `us-east-1`. Against real AWS S3 for a bucket elsewhere this produces a wrong-region `301`; `object_store` does not disable reqwest's redirect following, and `remove_sensitive_headers` strips the `Authorization` header on the cross-host redirect, so the followed request to the correct-region endpoint is unauthenticated and AWS rejects it with a non-retryable `403`. ## Fix The static arm now resolves region env-first (`AWS_REGION` then `AWS_DEFAULT_REGION`), and only when both env knobs are absent falls back to `aws_config::load_defaults(...).await.region()` — the same standard chain the `_ =>` arm uses — then applies `builder.with_region(region)`. This makes both arms resolve region by the same chain tiers while preserving the env-first fast path for the common static-creds + `AWS_REGION` workflow (`load_defaults` is only reached when env region is absent, i.e. the trigger intersection). The credential wiring (`StaticCredentialProvider` + `AWS_SESSION_TOKEN`) is unchanged; the change is purely additive region resolution. ## Testing Added three hermetic `#[tokio::test]` regression tests in `lite/src/server.rs` (`mod tests`) covering the static arm's new contract: - profile region is applied when env region is absent (the regression — confirmed to fail on the pre-fix code with `left: None, right: Some("eu-west-1")` and pass after the fix) - env region takes precedence over profile (preserves the documented fast path) - no bogus region is synthesized when no region is available anywhere Routine checks all pass: `cargo check --locked -p s2-lite` (default and `--all-features`), `cargo +nightly fmt --all --check`, `cargo clippy --locked -p s2-lite --all-targets -- -D warnings --allow deprecated`, and the full s2-lite nextest suite (331/331). End-to-end smoke (not versioned — ran against a containerized S3-compatible backend during development): built the release `server` binary and ran it against `adobe/s3mock` over HTTP with static env creds and the region supplied only via `AWS_CONFIG_FILE` (the bug-trigger intersection, `AWS_REGION`/`AWS_DEFAULT_REGION` unset). The server logged the resolved `region=us-east-1` from the profile tier (previously silently dropped), SlateDB wrote manifest/WAL/compaction objects to S3, and the full basin/stream/append/tail API lifecycle succeeded (HTTP 201/200), with a clean SIGTERM shutdown and no `403`/`301`/redirect errors. (LocalStack's latest image is license-gated; S3Mock was used as the equivalent HTTP S3-compatible backend.) This confirms the custom-endpoint static-creds path still works and the profile region is now honored; it does not reproduce the live-AWS redirect/auth-strip chain because S3Mock does not issue wrong-region 301s or validate SigV4 region. Not verified: live AWS S3 end-to-end (a real bucket in a non-`us-east-1` region with static keys). The environment has no AWS credentials (`aws sts get-caller-identity` returns `Unable to locate credentials`, no `~/.aws`, no IMDS), so the live-AWS 301 → auth-stripped 403 path could not be captured directly. The hermetic regression test covers the trigger (region misresolution), and the S3Mock smoke covers no-regression plus profile-region resolution; the live-AWS HTTP-chain leg is the only uncovered item. --- _Automatic Fixes PRs can be [configured here](https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/settings/repos/repo_c4bd6a47-9b7d-4b62-9c18-8cf0ac18a8f9/bugs)._ --------- Co-authored-by: detail-app[bot] <180357370+detail-app[bot]@users.noreply.github.com> |
History
|
|
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| CHANGELOG.md | ||