0501850a9c826604c99f8f7b8c4d869f083c3690
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0501850a9c |
Phase 0 milestone 0.3: auth + JWT + iam.assurance_level claim
Lands local password auth with JWT access + refresh tokens, and starts
carrying YPMS-specific claims (`uid`, `roles`, `iam.assurance_level`,
`mfa_verified`) so downstream authorization can gate high-risk actions
above base RBAC without a DB round-trip. Follows the OWC auth pattern
verbatim except where noted.
Added:
- src/ypms/auth/security.py hash_password / verify_password
(pbkdf2_sha256), create_access_token
with YPMS-specific claims,
create_refresh_token, decode_token
- src/ypms/auth/rate_limit.py SlidingWindow (vendored from OWC),
login_limiter tuned to NIST AC-7 /
source RFP C.5.7.10: 5 failed attempts
per IP per 15 minutes → 429 lockout
- src/ypms/auth/schemas.py LoginResponse, RefreshRequest,
RefreshResponse, ChangePasswordRequest,
UserRead
- src/ypms/auth/deps.py get_current_user replaces the milestone
0.2 stub; rejects refresh tokens on
resource endpoints; refuses inactive users
- src/ypms/auth/router.py POST /auth/login (OAuth2 form; audit-logs
successful auth; DOES_SYSTEM_ADMIN role
upgrades assurance_level to `admin` in
the token)
POST /auth/refresh (issues fresh access;
refuses non-refresh tokens)
GET /auth/me
POST /auth/change-password (self-service;
≥12 char floor; audit-logged)
- src/ypms/main.py Registers auth_router
Tests (43 passing, 93.47% coverage — up from 26 / 93.10%):
- tests/auth/test_security.py Token claims shape, refresh-vs-access
separation, invalid-token handling
(5 tests)
- tests/auth/test_router.py End-to-end via TestClient with a
dependency-overridden DB: login happy
path + wrong password + inactive user,
admin assurance upgrade, /me auth-gate,
refresh happy path + reject access token,
change-password full flow + length gate,
login lockout after 5 attempts (12 tests)
Test-infra fixes:
- tests/conftest.py Env defaults moved from a session-scoped
fixture to module-import time so
`ypms.main` (which builds the app at
import) can be transitively imported by
test modules without ValidationError on
Settings.
`db` fixture switched to StaticPool +
check_same_thread=False so TestClient's
worker thread sees the same in-memory
SQLite DB the fixture set up.
Notes:
- OWC includes an /auth/register for external users; that's out of scope
here — Phase 1 lands parental co-consent and youth/host registration,
which needs its own PIA-driven flow. Keeping /auth minimal in Phase 0.
- MFA is captured in `User.mfa_verified` and JWT claim but not enforced
yet; enforcement lands as an assurance-level gate in a later phase.
- Refresh flow returns only a new access token; refresh-token rotation
is a later hardening step.
Advances YPMS-POAM-040 and unblocks milestone 0.4 (RBAC seed) and 0.5
(Registrant vertical slice).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
7379bb4cf1 |
Mark milestone 0.2 complete in PHASE0_PLAN and POA&M
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
ba756586aa |
Phase 0 milestone 0.2: vendor OWC framework + YPMS pii_audit
Brings in a working generic-CRUD framework plus its dependencies from OWC
(../owc-system/src/owc/, snapshot 2026-04-20). Every vendored module carries
a header comment naming the source; the OWC → ypms rename is the only
mechanical change.
Vendored modules:
- framework/base.py TimestampMixin, SoftDeleteMixin, VersionedMixin
- framework/pagination.py Page[T] with to_dict()
- framework/version_history.py Snapshot table
- framework/crud.py CRUDService with audit emission
- framework/bulk.py BulkOps (BulkResult / BulkUpdateItem)
- framework/router.py make_router() factory (kept without
`from __future__ import annotations` for
FastAPI type introspection — see the module
docstring)
- audit/models.py AuditLog
- audit/service.py record()
- security/models.py Permission
- security/rbac.py can() + require_permission() dependency
(DOES_SYSTEM_ADMIN as the super-role)
- users/models.py User, Role, UserRole (YPMS adds
mfa_verified and assurance_level; drops
OWC-specific claimant_id)
- auth/deps.py get_current_user() placeholder — real JWT
verify lands in 0.3
YPMS-specific additions on top of the vendored framework:
- framework/pii_audit.py emit_pii_read() — NIST AU-14 / source RFP
C.5.6.9 #5. OWC doesn't need this because
its case-management surface is staff-only;
YPMS must audit reads of minors' PII, SSN,
banking, FERPA-covered OSSE records, and
CFSA foster/ward flags.
Bugfix vs. upstream OWC:
- framework/crud.py Pagination `next_cursor` was previously the
peek-ahead row's id, which combined with
`where id > cursor` on the next page
silently dropped one row per boundary.
Caught by test_list_pagination_forwards_cursor.
Fixed here; noted in the module header so
re-vendoring OWC surfaces it upstream.
Migrations:
- 0002_framework_tables.py Baseline for users, roles, user_roles,
permissions, audit_log, version_history.
Immutable once merged per CONTRIBUTING.md.
- migrations/env.py Imports the new model modules so
autogenerate compares against them.
Tests (26 passing, 93.10% coverage, floor 80%):
- tests/framework/test_crud.py CRUDService lifecycle + snapshots
+ audit emission (7 tests)
- tests/framework/test_bulk.py BulkOps happy paths + failure
reporting (4 tests)
- tests/framework/test_pagination.py Page.to_dict serializer contract
(2 tests)
- tests/framework/test_pii_audit.py emit_pii_read row shape,
anonymous case (2 tests)
- tests/security/test_rbac.py can() + admin bypass + role union
(4 tests)
- tests/test_readyz.py /readyz smoke (1 test)
- tests/test_logging.py sanitize_for_log contract (3 tests)
Green locally: ruff clean, mypy clean (with a targeted override on
framework/router.py and framework/crud.py for TypeVar limitations that
OWC also accepts).
Advances YPMS-POAM-040. Prepares milestone 0.3 (JWT auth) and 0.4 (RBAC
seed) to plug into an already-live framework.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
09d862bf4a |
Mark milestone 0.1 complete in PHASE0_PLAN and POA&M
Cross-references commit
|
||
|
|
393631ad69 |
Phase 0 milestone 0.1: repo scaffold + Docker Compose
Scaffolding for the YPMS in-house build. Mirrors OWC's structure so future OWC framework code can be vendored in with minimal fiddling (milestone 0.2). Includes: - pyproject.toml — Python 3.12, FastAPI, SQLAlchemy 2.x, Alembic, Postgres, pydantic-settings, structlog, cryptography. Dev extras: pytest, ruff, mypy, bandit, pip-audit. - Dockerfile — multi-stage builder + slim runtime. - docker-compose.yml — app + Postgres (on 5433 to avoid clashing with OWC on 5432) + Adminer (on 8081). - alembic.ini + migrations/env.py + baseline 0001_baseline.py (empty by design; every future change is additive and immutable once merged). - src/ypms/main.py — FastAPI factory with /healthz and /readyz. - src/ypms/settings.py — pydantic-settings config (DB URL, JWT, column encryption key, log level, env, CORS). - src/ypms/logging.py — structlog + sanitize_for_log() for the sensitive-fields-never-in-logs rule from ARCHITECTURE.md §10.1. - src/ypms/db.py — SQLAlchemy Base, engine, session factory, get_db. - src/ypms/middleware.py — RequestIdMiddleware; X-Request-ID header echoed both ways. - src/ypms/framework/ and src/ypms/security/ — empty packages, to be populated in milestones 0.2 and 0.3-0.4. - tests/test_health.py — 3 smoke tests (healthz OK, header present, header honoured on incoming). - README.md — quickstart. - CONTRIBUTING.md — hard rules mirrored from OWC. - .github/workflows/ci.yml — lint (ruff), types (mypy), tests + 80% coverage floor, SAST (bandit), SCA (pip-audit), gitleaks. Green locally: ruff clean, mypy clean, pytest 3 passed. Advances YPMS-POAM-040 (architecture doc + Phase 0 kickoff). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
8712e93258 |
Initial YPMS planning and ATO artifacts
Pre-development state; no code yet. Delivery model: in-house build by DOES OIT on Azure Government, matching the DCYWP / OWC / Employer 360 pattern. Stack decision (2026-09-30): Python 3.12 / FastAPI / SQLAlchemy / Postgres, aligning with OWC. System Owner / ISSO / AO: Chris Tonjes (DOES CIO). Role concentration recorded in SSP §5 with risk-acceptance rationale. Source functional and security requirements derived from the prior YPMS RFP (Solicitation Docxxxxx, April 2025) — 54 C.5.7 security requirements and Appendix E non-functional requirements — treated as source specifications, not as Contractor obligations. Documents included: - CLAUDE.md, OVERVIEW.md — project router and program-level summary - SYSTEM_SECURITY_PLAN.md v0.3 — NIST 800-53 Moderate baseline SSP - NIST_800_53_CONTROL_MAPPING.md v0.2 — full control-family mapping with in-house ownership tags and evidence-artifact expectations - POAM.md v0.1 — 62-item POA&M seeded from tailorings, open decisions, missing companion docs, and pre-ATO deliverables; two items closed - PRIVACY_IMPACT_ASSESSMENT.md v0.1 — full PIA covering minors, SSN, banking, FERPA-covered OSSE records, CFSA foster/ward flags, and the dormant emergency health-record path - ARCHITECTURE.md v0.1 — forward-looking design blueprint, OWC-aligned - PHASE0_PLAN.md v0.1 — framework vendor-in, auth, RBAC, audit, Registrant vertical slice, 501 stubs for remaining entities - TODO.md — 12-section working checklist tied to POA&M IDs - OLA_RESPONSE_2026-09-30.md — Q&A for OLA / City Administrator Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |