Security: remove hardcoded credentials, fix db_init for non-owner users #1

Merged
dom merged 2 commits from security/remove-hardcoded-secrets into main 2026-07-14 09:44:23 +00:00
Owner

Summary

  • Entfernt alle hardcodierten Secrets aus config.yaml und .env (die .env war im Git eingecheckt)
  • Secrets kommen jetzt ausschließlich aus Umgebungsvariablen via env_file: .env in der docker-compose.yaml
  • Fügt .env.example als Vorlage hinzu; .env ist per .gitignore ausgeschlossen
  • Härtet das Dockerfile: App läuft nicht mehr als root, kein Bind-Mount des Quellcodes
  • Optimiert OCR: zweiter (teurer) Tesseract-Lauf nur noch als Fallback
  • Fügt Fail-fast-Prüfung beim Start hinzu: fehlt ein Secret, bricht die App mit klarer Meldung ab
  • Enthält MIGRATION.md mit vollständigem Runbook für Secret-Rotation und Server-Umzug
  • Behebt db_init für DB-User ohne Table-Ownership: ALTER TABLE, CREATE INDEX und CREATE FUNCTION werden nur ausgeführt wenn das Objekt noch nicht existiert

Test plan

  • .env aus .env.example erstellen und mit rotierten Credentials befüllen
  • docker compose up -d --build erfolgreich
  • Logs zeigen [RESULT] ... result=success
  • Bilder landen in S3 unter icu/processed/ und icu/thumbnails/
  • DB: SELECT status, count(*) FROM remote_cam.import_job GROUP BY 1; zeigt verarbeitete Jobs
## Summary - Entfernt alle hardcodierten Secrets aus `config.yaml` und `.env` (die `.env` war im Git eingecheckt) - Secrets kommen jetzt ausschließlich aus Umgebungsvariablen via `env_file: .env` in der `docker-compose.yaml` - Fügt `.env.example` als Vorlage hinzu; `.env` ist per `.gitignore` ausgeschlossen - Härtet das Dockerfile: App läuft nicht mehr als root, kein Bind-Mount des Quellcodes - Optimiert OCR: zweiter (teurer) Tesseract-Lauf nur noch als Fallback - Fügt Fail-fast-Prüfung beim Start hinzu: fehlt ein Secret, bricht die App mit klarer Meldung ab - Enthält `MIGRATION.md` mit vollständigem Runbook für Secret-Rotation und Server-Umzug - Behebt `db_init` für DB-User ohne Table-Ownership: `ALTER TABLE`, `CREATE INDEX` und `CREATE FUNCTION` werden nur ausgeführt wenn das Objekt noch nicht existiert ## Test plan - [ ] `.env` aus `.env.example` erstellen und mit rotierten Credentials befüllen - [ ] `docker compose up -d --build` erfolgreich - [ ] Logs zeigen `[RESULT] ... result=success` - [ ] Bilder landen in S3 unter `icu/processed/` und `icu/thumbnails/` - [ ] DB: `SELECT status, count(*) FROM remote_cam.import_job GROUP BY 1;` zeigt verarbeitete Jobs
dom added 2 commits 2026-07-14 09:43:21 +00:00
Secrets (S3 keys, PG password, DeerMapper API key) were committed in
config.yaml and .env and remain in git history. This removes them from
the tracked tree and moves all secrets to env injection.

Security:
- config.yaml: drop all credentials, keep only non-secret app tunables
- untrack .env, add .env.example template; .gitignore excludes .env
- main.py: tolerant config lookups + fail-fast validation for missing secrets
- docker-compose: env_file injection, no full-repo bind mount, debug port off
- Dockerfile: bake config into image, run as non-root user

Efficiency:
- OCR: run the second (expensive) tesseract pass only when the first
  is unparsable; identical fallback behavior

Docs:
- README with operation + security notes
- MIGRATION.md runbook: secret rotation, server cutover, decommission,
  git history purge

Note: the leaked secrets are compromised and MUST be rotated; removing
them from the tree is not sufficient. See MIGRATION.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ALTER TABLE, CREATE INDEX and CREATE OR REPLACE FUNCTION all require table/function
ownership in PostgreSQL. Replace IF NOT EXISTS DDL with explicit existence checks so
db_init works for unprivileged application users where the schema was created by a
different role (e.g. postgres).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dom merged commit 399913abe3 into main 2026-07-14 09:44:23 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meles2/melesICUmover#1