Authentication

Every BangmodStorage S3 API request must be signed with AWS Signature Version 4 (SigV4). Our gateway implements SigV4 with the same algorithm and headers AWS uses, so any S3 SDK that signs SigV4 will work unchanged.

Access keys

An access key has two parts: a public Access Key ID (begins with BGSAKIA) and a secret Secret Access Key. Both are needed to sign requests.

Generate, list, and rotate keys from /console/keys. You can have multiple active keys per account (recommended: one per environment, e.g. dev/staging/prod). When you generate a new key, the secret is displayed once — copy it immediately. We store only an AES-GCM-encrypted form on our side and cannot recover the plaintext.

SigV4 signing

SDKs handle this automatically. If you are signing manually, the canonical request and string-to-sign formats are identical to AWS S3. See AWS's Signature Version 4 specification for full algorithm details. The region string in the credential scope should be one of ap-southeast-1-bkk or ap-southeast-1-sg; the service is always s3.

Request requirements

  • HTTPS only. Plain HTTP is rejected.
  • Host header matches one of our published endpoints.
  • X-Amz-Date within 15 minutes of our gateway clock (UTC). Drift > 15 min is rejected as RequestTimeTooSkewed.
  • X-Amz-Content-SHA256 set to the SHA-256 of the request body, or to the literal UNSIGNED-PAYLOAD for unsigned bodies. The literal STREAMING-AWS4-HMAC-SHA256-PAYLOAD chunked-upload variant is also supported.
  • Authorization header carrying the SigV4 signature, OR the SigV4 query parameters for presigned URLs.

Presigned URLs

Presigned URLs let you grant time-limited access to specific objects without sharing your secret key. Generate them with any S3 SDK; example:

# Python boto3
url = s3.generate_presigned_url(
    'get_object',
    Params={'Bucket': 'my-bucket', 'Key': 'reports/2026-05.pdf'},
    ExpiresIn=300,  # 5 minutes
)

Max ExpiresIn is 604800 seconds (7 days), matching AWS's SigV4 limit.

Rotating keys

We recommend rotating access keys at least annually:

  1. Generate a new key from /console/keys.
  2. Deploy the new key to your applications.
  3. Verify traffic is using the new key (look at the "Last used" column).
  4. Disable the old key (puts it in revoked state but doesn't delete).
  5. After a soak period, delete the old key.

Common signing errors

Error codeCause
SignatureDoesNotMatchWrong secret, wrong region in credential scope, or signed-headers list out of sync.
RequestTimeTooSkewedClient clock drift > 15 min from UTC. Sync clock via NTP.
InvalidAccessKeyIdAccess key revoked, deleted, or belongs to a different region's gateway.
MissingAuthenticationTokenRequest unsigned. Configure SDK with credentials.