Security release: closes the independent audit's High/Medium findings, plus a Python-first Getting Started rewrite and an audit-driven architecture cleanup. See PR #32.
Security (docs/SECURITY_AUDIT.md #1–#8)
- #1 IDOR (High): object-level ownership checks on all read endpoints (404, no existence leak).
- #2 Dev-login backdoor (High): fail-closed — requires explicit
PORTAL_DEV_LOGIN=1; local compose binds the portal to127.0.0.1. - #3 apiserver SA (High): off the operator's cluster-wide SA (base → no-RBAC
default; prod IRSA overlay unchanged). - #4 Leaked token (Med): scrubbed from the sample notebook.
- #5 Ref validation (Med): server-side
s3://-into-the-right-bucket checks blockfile://, bare paths, and cross-bucket reads. - #6 Auth secret (Med): portal refuses to start in prod with an unset/placeholder
BETTER_AUTH_SECRET. - #7 Runner (Med): runs as non-root UID 10001.
- #8 Batch cap (Low):
SP_MAX_BATCH_VARIANTS(default 10000). - Also removed a production magic-link bearer token from an auth log line.
Other
- Getting Started now leads with the Python SDK (notebook + script views); REST is the no-Python fallback.
- Architecture cleanup: 24 safe behavior-preserving items (dead code, dedup, domain-language alignment, a failed-upload artifact-URI correctness fix).
⚠️ Operator action required
Rotate the two exposed sp_live_… API tokens and the Gmail SMTP app-password (the in-repo scrub does not revoke them), and remove gmail.com from production ALLOWED_EMAIL_DOMAINS.
🤖 Generated with Claude Code