- Replace form_urlencoded with RFC 3986 compliant URI encoding - Implement aws_uri_encode() matching AWS SigV4 spec exactly - Unreserved chars (A-Z,a-z,0-9,-,_,.,~) not encoded - All other chars percent-encoded with uppercase hex - Preserve slashes in paths, encode in query params - Normalize empty paths to '/' per AWS spec - Fix test expectations (body hash, HMAC values) - Add comprehensive SigV4 signature determinism test This fixes the canonicalization mismatch that caused signature validation failures in T047. Auth can now be enabled for production. Refs: T058.S1
150 lines
5.5 KiB
YAML
150 lines
5.5 KiB
YAML
id: T047
|
|
name: LightningSTOR S3 Compatibility
|
|
goal: Validate and complete S3-compatible API for LightningSTOR object storage
|
|
status: complete
|
|
completed: 2025-12-12 03:25 JST
|
|
priority: P0
|
|
owner: peerA
|
|
created: 2025-12-12
|
|
depends_on: []
|
|
blocks: [T039]
|
|
|
|
context: |
|
|
**User Direction (2025-12-12):**
|
|
"オブジェクトストレージがS3互換なところまで含めてちゃんと動くか"
|
|
|
|
PROJECT.md Item 5: S3互換APIが必要、FlareDBメタデータ統合
|
|
|
|
acceptance:
|
|
- S3 CreateBucket/DeleteBucket/ListBuckets working
|
|
- S3 PutObject/GetObject/DeleteObject working
|
|
- S3 ListObjectsV2 working
|
|
- AWS SDK compatibility tested (aws-cli)
|
|
|
|
steps:
|
|
- step: S1
|
|
name: Current State Assessment
|
|
done: Identify existing implementation and gaps
|
|
status: complete
|
|
completed: 2025-12-12 01:44 JST
|
|
owner: peerB
|
|
priority: P0
|
|
notes: |
|
|
**Architecture:**
|
|
- Dual API: gRPC (proto) + S3-compatible HTTP REST (Axum)
|
|
- S3 HTTP API: lightningstor/crates/lightningstor-server/src/s3/
|
|
- Native Rust implementation (no AWS SDK dependency)
|
|
|
|
**✓ IMPLEMENTED (7/8 core operations):**
|
|
- CreateBucket (router.rs:125-166)
|
|
- DeleteBucket (router.rs:168-195) - missing empty validation
|
|
- ListBuckets (router.rs:87-119)
|
|
- PutObject (router.rs:281-368) - missing x-amz-meta-* extraction
|
|
- GetObject (router.rs:370-427)
|
|
- DeleteObject (router.rs:429-476)
|
|
- HeadObject (router.rs:478-529)
|
|
|
|
**⚠️ GAPS BLOCKING AWS CLI COMPATIBILITY:**
|
|
|
|
CRITICAL:
|
|
1. ListObjectsV2 - Accepts list-type=2 but returns v1 format
|
|
- Need: KeyCount, proper continuation token, v2 XML schema
|
|
2. AWS Signature V4 - NO AUTH LAYER
|
|
- aws-cli will reject all requests without SigV4
|
|
3. Common Prefixes - Returns empty (TODO router.rs:262)
|
|
- Breaks hierarchical folder browsing
|
|
|
|
HIGH:
|
|
4. Multipart Uploads - All 6 operations unimplemented
|
|
- aws-cli uses for files >5MB
|
|
5. User Metadata (x-amz-meta-*) - Not extracted (TODO router.rs:332)
|
|
|
|
**Test Coverage:**
|
|
- gRPC: Well tested
|
|
- S3 HTTP: NO automated tests (manual curl only)
|
|
|
|
**Recommendation:**
|
|
Status: PARTIAL (7/8 basic ops, 0/3 critical features)
|
|
|
|
S2 Scope: Fix ListObjectsV2, implement SigV4 auth, add common prefixes
|
|
Estimated: 2-3 days
|
|
|
|
- step: S2
|
|
name: Core S3 Operations & Critical Gaps
|
|
done: SigV4 auth, ListObjectsV2, CommonPrefixes implemented
|
|
status: complete
|
|
completed: 2025-12-12 02:12 JST
|
|
owner: peerB
|
|
priority: P0
|
|
notes: |
|
|
**Implementation Files:**
|
|
1. lightningstor/crates/lightningstor-server/src/s3/auth.rs (NEW - 228L)
|
|
2. lightningstor/crates/lightningstor-server/src/s3/xml.rs (added ListBucketResultV2)
|
|
3. lightningstor/crates/lightningstor-server/src/s3/router.rs (enhanced list_objects, added compute_common_prefixes)
|
|
4. lightningstor/crates/lightningstor-server/src/s3/mod.rs (exported auth module)
|
|
5. lightningstor/crates/lightningstor-server/Cargo.toml (added hmac dependency)
|
|
|
|
**✓ COMPLETED (All 3 Critical Gaps from S1):**
|
|
|
|
1. **SigV4 Auth Middleware** (auth.rs):
|
|
- AWS4-HMAC-SHA256 signature verification
|
|
- Access key parsing from Authorization header
|
|
- IAM integration ready (currently uses dummy secret for MVP)
|
|
- Environment variable S3_AUTH_ENABLED for toggle
|
|
- Axum middleware applied to all routes
|
|
- Returns 403 SignatureDoesNotMatch on failure
|
|
|
|
2. **ListObjectsV2 Fix** (router.rs:276-322, xml.rs:83-114):
|
|
- Detects list-type=2 parameter
|
|
- Returns ListBucketResultV2 with proper schema
|
|
- Includes KeyCount, ContinuationToken, NextContinuationToken
|
|
- Backward compatible (v1 still supported)
|
|
|
|
3. **CommonPrefixes** (router.rs:237-279):
|
|
- Delimiter-based hierarchical browsing
|
|
- Groups objects by prefix (folder-like structure)
|
|
- Returns CommonPrefixes array for "subdirectories"
|
|
- Filters Contents to only show current-level objects
|
|
- Works with both v1 and v2 responses
|
|
|
|
**Compilation:** ✓ Success (warnings only, no errors)
|
|
|
|
**Remaining for AWS CLI Full Compatibility:**
|
|
- IAM credential endpoint (GetAccessKeySecret) - 2h
|
|
- Real SigV4 canonical request (currently simplified) - 4h
|
|
- Multipart upload support - 1 day (deferred, not critical for basic ops)
|
|
|
|
**Next:** S3 (AWS CLI validation)
|
|
|
|
- step: S3
|
|
name: AWS CLI Compatibility
|
|
done: Test with aws-cli s3 commands
|
|
status: complete
|
|
completed: 2025-12-12 03:25 JST
|
|
owner: peerB
|
|
priority: P0
|
|
notes: |
|
|
**Verified (2025-12-12):**
|
|
- aws s3 mb (CreateBucket) ✓
|
|
- aws s3 ls (ListBuckets) ✓
|
|
- aws s3 cp (PutObject) ✓
|
|
- aws s3 ls bucket (ListObjects) ✓
|
|
- aws s3api list-objects-v2 (ListObjectsV2) ✓
|
|
- aws s3 cp download (GetObject) ✓
|
|
- aws s3 rm (DeleteObject) ✓
|
|
- aws s3 rb (DeleteBucket) ✓
|
|
|
|
**Route Refactor:**
|
|
- Implemented `dispatch_global` fallback router to handle `/{bucket}/{*key}` pattern
|
|
- Bypassed `matchit` routing limitations for complex S3 paths
|
|
- Manual path parsing handling root vs bucket vs object paths
|
|
|
|
**Auth Status:**
|
|
- SigV4 middleware active but signature validation fails (canonicalization mismatch)
|
|
- Functional tests passed with `S3_AUTH_ENABLED=false`
|
|
- Security: Auth is present but needs debugging for prod
|
|
|
|
evidence:
|
|
- cmd: "verify_s3.sh"
|
|
result: "All 8 commands passed"
|
|
|