# POST3-012: Authentication system **Status:** Todo **Priority:** P1 **Blocked by:** — ## Description Add authentication to post3-server. Currently the server accepts any request regardless of credentials. We need to support API key-based authentication that is compatible with the AWS SigV4 signing process (so the official AWS SDKs and CLI work transparently). ## Approach ### Phase 1: API key authentication (simple) Use a shared secret key pair (access_key_id + secret_access_key) configured via environment variables. The server validates that the `Authorization` header contains a valid AWS SigV4 signature computed with the known secret. - [ ] Database table `api_keys`: ```sql CREATE TABLE api_keys ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), access_key_id TEXT NOT NULL, secret_key TEXT NOT NULL, -- stored hashed or plaintext for SigV4 name TEXT NOT NULL, -- human-readable label is_active BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE UNIQUE INDEX idx_api_keys_access_key ON api_keys (access_key_id); ``` - [ ] SigV4 signature verification middleware (axum layer) - [ ] Extract access_key_id from `Authorization` header - [ ] Look up secret_key from `api_keys` table - [ ] Recompute the SigV4 signature and compare - [ ] Return `403 AccessDenied` XML error on mismatch - [ ] Environment variable `POST3_AUTH_ENABLED=true|false` to toggle (default: false for backward compat) ### Phase 2: Per-bucket ACLs (future) - [ ] `bucket_permissions` table linking api_keys to buckets with read/write/admin roles - [ ] Enforce permissions in handlers - [ ] Admin API for managing keys and permissions ### Phase 3: Admin CLI - [ ] `post3-server admin create-key --name "my-app"` — generates and prints access_key_id + secret_access_key - [ ] `post3-server admin list-keys` — list all API keys - [ ] `post3-server admin revoke-key --access-key-id AKIA...` — deactivate a key ## Migration - [ ] New migration file for `api_keys` table - [ ] Existing deployments unaffected (auth disabled by default) ## SDK Integration - [ ] `Post3Client::builder().credentials(access_key, secret_key)` passes real credentials - [ ] When auth is disabled, dummy credentials still work ## Testing - [ ] Test: request with valid signature succeeds - [ ] Test: request with invalid signature returns 403 - [ ] Test: request with unknown access_key_id returns 403 - [ ] Test: auth disabled mode accepts any credentials - [ ] Test: admin CLI key management commands ## Notes SigV4 verification requires access to the raw request (method, path, headers, body hash). The `aws-sigv4` crate from the AWS SDK can help with signature computation on the server side. Alternatively, implement the HMAC-SHA256 chain manually — it's well-documented. The secret_key must be stored in a form that allows recomputing signatures (SigV4 uses the secret directly in HMAC, not a hash of it). This means secret_keys are stored as plaintext or with reversible encryption. This is inherent to SigV4's design.