Files

4.9 KiB
Raw Permalink Blame History

Phase 7.3: Security — ES256 Algorithm Upgrade - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-06-05 Phase: 07.3-security-es256-algorithm-upgrade-inserted Areas discussed: Key format in env vars, Startup refresh-token rotation, Key generation workflow, JWT TTL / Remember Me


Key Format in Env Vars

Q1: How should P-256 PEM keys be stored in env vars?

Option Description Selected
Base64-encoded Single line, shell-safe, decoded in config.py
Escaped \n in .env python-dotenv expands \n; loader-dependent
Multiline .env block Breaks in docker-compose environment: block

User's choice: Base64-encoded
Notes: Standard 12-factor approach; no loader ambiguity.


Q2: Both keys required, or derive public from private at startup?

Option Description Selected
Both required env vars Clean separation; workers can hold public key only
Private key only — derive public Fewer env vars but more magic in config.py

User's choice: Both required env vars


Q3: What happens to SECRET_KEY after ES256?

Option Description Selected
Remove from JWT code SECRET_KEY no longer used for signing; stays in env for future HMAC
Repurpose as HMAC key for Phase 7.4 Forward-compatible but couples phases

User's choice: Remove SECRET_KEY from JWT code


Startup Refresh-Token Rotation

Q1: How to implement startup rotation?

Option Description Selected
DELETE all refresh_tokens Simple, one-shot; no schema change
Bulk revoke (set revoked=True) Cleaner audit trail; same user impact
Let natural expiry handle it Doesn't satisfy ROADMAP requirement

User's choice: Bulk revoke (set revoked=True)


Q2: How to detect "first boot after ES256 migration"?

Option Description Selected
Check system_settings table Stores jwt_algorithm; idempotent on restart
New env var JWT_TOKEN_GENERATION=N Simple but requires operator bump on deploy
One-time Alembic migration Runs at migrate time, not startup

User's choice: Check system_settings table (jwt_algorithm key)


Key Generation Workflow

Q1: How should developers generate the key pair?

Option Description Selected
Python one-liner in README Uses existing cryptography dep; no extra tooling
openssl CLI command Familiar to ops but multi-step, requires openssl
Auto-generate on first boot Convenient for dev; dangerous in prod (ephemeral keys)

User's choice: Python one-liner documented in README


Q2: docker-compose key placeholder vs. .env reference?

Option Description Selected
.env file reference only Follows existing ${SECRET_KEY} pattern
Placeholder comment in docker-compose Helpful but could mislead

User's choice: .env file reference only


JWT TTL / Remember Me

Q1 (freeform): What token should default to 12 hours?

User note: "JWT Tokens should only be valid for 12 hours and the user can opt-in to create a token which is valid for 30 days."

Asked for clarification on whether this applied to the access token or refresh token. User asked: "What do you think is the most secure way to handle tokens?"

Claude's recommendation: Keep access token at 15 min (CLAUDE.md requirement). Change refresh token default to 1624 hours with explicit "remember me" opt-in for 30 days.

User's decision: 16 hours — covers a full workday; guarantees session is revoked overnight.


Q2: Fold "remember me" into Phase 7.3 or separate phase?

Option Description Selected
Fold into Phase 7.3 Already touching token creation code; incremental work
Separate phase 7.5 Keeps 7.3 purely as ES256 upgrade

User's choice: Fold into Phase 7.3


Claude's Discretion

  • PyJWT API form: jwt.encode(payload, pem_str, algorithm="ES256") — PEM strings passed directly, no key object conversion needed
  • Bulk revoke via raw SQL UPDATE rather than ORM row-by-row — efficiency decision
  • "Stay signed in for 30 days" as checkbox label (clearer than "Remember me")
  • system_settings key name: jwt_algorithm, value "ES256"

Deferred Ideas

  • Phase 7.4: Token fingerprinting / token binding (fgp claim = HMAC of User-Agent + Accept-Language)
  • Key rotation ceremony: Dual-key overlap process for rotating P-256 keys in production — deferred until production hardening milestone