Implements token security and management as specified in ADR-029: Database Changes (BREAKING): - Add secure tokens table with SHA256 hashed storage - Add authorization_codes table for IndieAuth token exchange - Drop old insecure tokens table (invalidates existing tokens) - Update SCHEMA_SQL to match post-migration state Token Management (starpunk/tokens.py): - Generate cryptographically secure tokens - Hash tokens with SHA256 for secure storage - Create and verify access tokens - Create and exchange authorization codes - PKCE support (optional but recommended) - Scope validation (V1: only 'create' scope) - Token expiry and revocation support Testing: - Comprehensive test suite for all token operations - Test authorization code replay protection - Test PKCE validation - Test parameter validation - Test token expiry Security: - Tokens never stored in plain text - Authorization codes single-use with replay protection - Optional PKCE for enhanced security - Proper UTC datetime handling for expiry Related: - ADR-029: Micropub IndieAuth Integration Strategy - Migration 002: Secure tokens and authorization codes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
58 lines
2.8 KiB
SQL
58 lines
2.8 KiB
SQL
-- Migration: Secure token storage and add authorization codes
|
|
-- Date: 2025-11-24
|
|
-- Version: 0.10.0 (BREAKING CHANGE)
|
|
-- ADR: ADR-029 Micropub IndieAuth Integration Strategy
|
|
--
|
|
-- SECURITY FIX: Migrate tokens table to use SHA256 hashed storage
|
|
-- BREAKING CHANGE: All existing tokens will be invalidated
|
|
--
|
|
-- This migration:
|
|
-- 1. Creates new secure tokens table with token_hash column
|
|
-- 2. Drops old insecure tokens table (invalidates all existing tokens)
|
|
-- 3. Creates authorization_codes table for IndieAuth token exchange
|
|
-- 4. Adds appropriate indexes for performance
|
|
|
|
-- Step 1: Drop the old insecure tokens table
|
|
-- This invalidates all existing tokens (necessary security fix)
|
|
DROP TABLE IF EXISTS tokens;
|
|
|
|
-- Step 2: Create new secure tokens table
|
|
CREATE TABLE tokens (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
token_hash TEXT UNIQUE NOT NULL, -- SHA256 hash of token (never store plain text)
|
|
me TEXT NOT NULL, -- User identity URL
|
|
client_id TEXT, -- Client application URL
|
|
scope TEXT DEFAULT 'create', -- Granted scopes (V1: only 'create')
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
expires_at TIMESTAMP NOT NULL, -- Token expiration (90 days default)
|
|
last_used_at TIMESTAMP, -- Track last usage for auditing
|
|
revoked_at TIMESTAMP -- Soft revocation support
|
|
);
|
|
|
|
-- Step 3: Create authorization_codes table for token exchange
|
|
CREATE TABLE authorization_codes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
code_hash TEXT UNIQUE NOT NULL, -- SHA256 hash of authorization code
|
|
me TEXT NOT NULL, -- User identity URL
|
|
client_id TEXT NOT NULL, -- Client application URL
|
|
redirect_uri TEXT NOT NULL, -- Client's redirect URI (must match on exchange)
|
|
scope TEXT, -- Requested scopes (can be empty per IndieAuth spec)
|
|
state TEXT, -- Client's state parameter
|
|
code_challenge TEXT, -- Optional PKCE code challenge
|
|
code_challenge_method TEXT, -- PKCE method (S256 if used)
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
expires_at TIMESTAMP NOT NULL, -- Short expiry (10 minutes default)
|
|
used_at TIMESTAMP -- Prevent replay attacks (code can only be used once)
|
|
);
|
|
|
|
-- Step 4: Create indexes for performance
|
|
CREATE INDEX idx_tokens_hash ON tokens(token_hash);
|
|
CREATE INDEX idx_tokens_me ON tokens(me);
|
|
CREATE INDEX idx_tokens_expires ON tokens(expires_at);
|
|
|
|
CREATE INDEX idx_auth_codes_hash ON authorization_codes(code_hash);
|
|
CREATE INDEX idx_auth_codes_expires ON authorization_codes(expires_at);
|
|
|
|
-- Migration complete
|
|
-- Security notice: All users must re-authenticate after this migration
|