Work Done
Full design + implementation session for vxData access control (supersedes mono#90/#49).
Research phase: parallel exploration of vxdata-api internals, dashboard-frontend, keycloak/IAM infra (infra_ansible realm.json.j2, infra_iam group chain), PR archaeology (#49/#50/#90), and external best practices. Twelve design decisions locked with Felix (hybrid static-token+Keycloak-JWT resolver; policy in app config; license+access_level read / payload_type write dims; NULL fails closed; resource-scoped presign in v1; SDK device-flow login; SPA PKCE; seeded dev tokens + startup hard-fail; static bot tokens first; staging→callers→prod rollout; stacked minimal PRs). Plan in ~/work/tries/2026-07-14-access-control/PLAN.md.
Draft PRs (all validated locally; mono suite 73-78 green per branch, live just deploy smoke matrix passed):
- mono#234 — policy core (
api/access.py), bearer resolution (api/auth.py), read scoping baked intobuild_query_statement(parquet-safe) + bypass paths, write gating, dev tokens + facet-tagged mock data. - mono#235 —
POST /s3/presign/resource(row-scoped), path endpoints gated to wildcard-read, upload presigns declare payload_type,GET /s3/parquetdeleted. NOTE deviation:/s3/listkept (gated) because SDK directory downloads need it. - mono#236 — Keycloak JWT resolver (PyJWT + injectable JWKS, groups/azp→grants, fake-JWKS test matrix), principal subject in request logs.
- mono#237 — SDK
Client(token=)/VXDATA_TOKEN+vxdata logindevice flow with token cache/refresh. - mono#238 — dashboard PKCE via oidc-spa (
dashboardclient), fetch-wrapper bearer injection, dashboard-api forwards user token (agent-built). - infra_ansible#75 —
vxdata-clidevice-grant client,vxdata-apiaudience client + mappers (coordinate with open #59). - infra_k8s#149 — optional
vxdata-credentials-{env}envFrom in run-image template + dashboard-apiVXDATA_TOKEN; staging flip is secret-only.
Remaining rollout: provision secrets (1Password → k8s), flip staging, migrate vxdata-jobs/CI via VXDATA_TOKEN env, classify NULL-license ODELIA rows (mono#154), prod flip, close #90/#49.
Lessons Learned: Pitfalls
wiki/workstreams/infrastructure/index.mdis empty — the begin-work skill’s step 4 dead-ends for infrastructure work. Either populate it or point it at the virdx-work skill references.- vxdata-api’s
pixi run --frozen ruff format src testsreports “No Python files found” ([tool.ruff] include = ["src"]quirk); theformatpixi task has the same issue. Use explicit file paths or fix the include config. - ty typecheck output goes through
taileasily hiding failures — its “Found N diagnostics” exit status must be checked directly; vxdata-sdk has 6 pre-existing ty diagnostics on main (namespaces/base.py, storage.py) that look like new breakage but aren’t.
Lessons Learned: Improvements
- minio-py’s
presigned_*methods do a GetBucketLocation round trip unlessregion=is pinned — this breaks offline tests and adds latency; vxdata-api now hasS3_REGIONfor this. Worth a note in the vxdata-api AGENTS.md. - The whole access-control design context (why session-hook scoping leaks via parquet, grants model, NULL rule) lives in mono#234’s description and
PLAN.md; future auth work should start there instead of re-deriving from #90. gh pr view 90+ the closed #49 contain zero review threads — all design rationale is in PR bodies only; don’t waste time hunting for review comments on those.- Keycloak realm changes are testable offline by rendering
roles/keycloak/templates/realm.json.j2with jinja2 + stub secrets and parsing the JSON — cheap validation worth documenting in infra_ansible.