package files
import (
"context"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
type Presigner struct {
bucket string
p *s3.PresignClient
}
func NewPresigner(cfg aws.Config, bucket string) *Presigner {
return &Presigner{bucket: bucket, p: s3.NewPresignClient(s3.NewFromConfig(cfg))}
}
func (p *Presigner) PresignPut(ctx context.Context, key string) (string, error) {
out, err := p.p.PresignPutObject(ctx, &s3.PutObjectInput{Bucket: &p.bucket, Key: &key}, s3.WithPresignExpires(2*time.Minute))
if err != nil {
return "", err
}
return out.URL, nil
}
When clients upload files directly to S3, your API avoids handling large payloads and you get better scalability. I generate a presigned PUT URL with a short expiry and a constrained object key prefix so users can’t overwrite arbitrary objects. The crucial part is that the backend owns the key: the client asks for an upload, the server returns {key, url}, and the client uploads bytes to S3. Then the client notifies the backend to “finalize” the upload. This two-step flow prevents a class of spoofing bugs where a client claims it uploaded something it didn’t. In production I also include expected content type and size limits in policy (for POST) or enforce them at finalize-time. Presigning is simple, but the workflow around it is where security lives.
Related snips
# AWS Lambda Function with API Gateway trigger
# === Lambda function ===
resource "aws_lambda_function" "api_handler" {
function_name = "${var.project}-api-handler"
description = "API request handler for ${var.project}"
AWS Lambda serverless functions with Terraform
package api
import (
"net/http"
"runtime/debug"
)
Expose build metadata for debugging deploys
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
package dbutil
import (
"context"
"github.com/jackc/pgconn"
Retry Postgres serialization failures with bounded attempts
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
Least privilege IAM policy for an application on AWS
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR="https://vault.internal:8200"
export VAULT_TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}"
Secrets management with environment isolation and Vault
Share this code
Here's the card — post it anywhere.