Skip to content

2026-07-14 vxdata access control

Designed and implemented the vxData access-control stack — 7 draft PRs across mono, infra_ansible, infra_k8s

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 into build_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/parquet deleted. NOTE deviation: /s3/list kept (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 login device flow with token cache/refresh.
  • mono#238 — dashboard PKCE via oidc-spa (dashboard client), fetch-wrapper bearer injection, dashboard-api forwards user token (agent-built).
  • infra_ansible#75 — vxdata-cli device-grant client, vxdata-api audience client + mappers (coordinate with open #59).
  • infra_k8s#149 — optional vxdata-credentials-{env} envFrom in run-image template + dashboard-api VXDATA_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.md is 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 tests reports “No Python files found” ([tool.ruff] include = ["src"] quirk); the format pixi task has the same issue. Use explicit file paths or fix the include config.
  • ty typecheck output goes through tail easily 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 unless region= is pinned — this breaks offline tests and adds latency; vxdata-api now has S3_REGION for 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.j2 with jinja2 + stub secrets and parsing the JSON — cheap validation worth documenting in infra_ansible.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close