dev-worker: Implement AWS SigV4 authentication for the warehouse S3-com… #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev-worker/01KYV61K35407545HQHG4PVKE3"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implement AWS SigV4 authentication for the warehouse S3-compatible server, supporting both the Authorization header and presigned URL (query-string) variants.
Changes:
aws s3 lsworks against a signed request.Assumptions made:
All builds, go vet, and tests pass.
go build ./...
go test ./...
Opened by saga-dev-worker for mission
01KYV61K35407545HQHG4PVKE3.Changes: 1. internal/auth/sigv4.go (new) — SigV4 verification package: Verify() dispatches header vs. presigned variant; ExtractAccessKeyID(); credential-scope parsing; canonical-request reconstruction (S3-style path encoding preserving '/', canonical query string excluding X-Amz-Signature, header canonicalization); string-to-sign; signing-key derivation; HMAC-SHA256 verification. Sentinel errors (ErrMissingAuth, ErrUnsupportedAlgorithm, ErrMalformedAuth, ErrMissingDate, ErrInvalidDateFormat, ErrExpired) and *SignatureError carrying StringToSign/CanonicalRequest/SignatureProvided diagnostics. Also exports SignRequest/SignPresigned helpers. 2. internal/server/middleware.go (new) — Server.WithAuth chi middleware: extracts access key id -> Store.GetAccessKey (-> InvalidAccessKeyId on ErrAccessKeyNotFound) -> rejects disabled keys -> auth.Verify -> forwards. No anonymous path on protected routes. S3 XML error responses (S3Error struct) for SignatureDoesNotMatch, InvalidAccessKeyId, AccessDenied, RequestExpired, AuthorizationHeaderMalformed. 3. internal/server/server.go — router wired so /healthz is the only public route; GET / (ListBuckets) plus bucket HEAD/GET/PUT/DELETE sit inside the auth group. Added ListBuckets/headBucket/createBucket/deleteBucket/listObjects handlers so `aws s3 ls` works against a signed request. 4. Tests: internal/auth/sigv4_test.go (independently re-derives signing key as cross-check; covers valid/invalid header+presigned, missing/invalid date, bad algorithm, malformed credentials, expired vs. not-yet-expired, bad X-Amz-Expires, canonical query string, URI encoding, payload-hash restoration) and internal/server/middleware_test.go (full chi-router integration: missing auth 403, valid header+presigned -> ListBuckets, wrong secret -> SignatureDoesNotMatch, unknown key id -> InvalidAccessKeyId, expired -> RequestExpired, disabled key, public /healthz, bucket routes require auth, bad algorithm, tampered presigned query). Assumptions made: - Updated the pre-existing TestHealthzNotFound (expected 404 for /nope) to expect 403, since enforcing auth on all non-healthz routes is the mission requirement ("no anonymous access path"). /healthz remains intentionally public for liveness probes. - listObjects returns a minimal ListBucketResult envelope; deeper object-storage handlers were left for a later increment since the mission scoped auth. All builds, go vet, and tests pass.