BLAST jobs shared visibility (dev-stage flag)¶
Motivation¶
During the development stage the Recent searches page only listed jobs whose
owner_oid matched the signed-in caller, so jobs submitted directly through the
OpenAPI surface (which carry an empty / different owner_oid) showed up while a
researcher's own UI-submitted jobs from a different identity context did not.
For single-tenant development we want every authenticated caller to see and open
every job regardless of who submitted it.
User-facing change¶
- New environment flag
BLAST_JOBS_SHARED_VISIBILITY(defaultfalse). - When
true, the BLAST job list (GET /api/blast/jobs), the operations job monitor (GET /api/monitor/jobs), and every per-job read/lifecycle route show and allow access to all jobs, not just the caller's own. Split-job child rollups keep working by grouping parents by their storedowner_oid. - When
false(production default) the per-owner isolation boundary is unchanged: a foreign job returns403 not owner.
The route layer still requires require_caller either way — this flag only
relaxes the per-row owner comparison, never the authentication gate.
API / IaC diff summary¶
api/services/blast/job_state.py: addedblast_shared_visibility_enabled()and_assert_job_owner(owner_oid, caller); routed the existing_ensure_job_read_allowedowner comparison through_assert_job_owner.api/services/state/repository.py: added owner-agnosticJobStateRepository.list_all(*, limit, include_payload)(queriesstatus ne 'deleted', newest-first).api/routes/blast/jobs.py: list route selectslist_allwhen the flag is on and the repo supports it; cache key now includesshared_visibility; all inline owner comparisons replaced by_assert_job_owner; split-child rollup grouped by owner under shared visibility.api/routes/blast/logs.py,api/routes/monitor/jobs.py: inline owner checks replaced by_assert_job_owner; monitor list useslist_allunder the flag.api/routes/_blast_shared.py: re-exports the two new helpers.infra/modules/containerAppControl.bicep: api sidecar gainsBLAST_JOBS_SHARED_VISIBILITYenv entry, default'false'.
Validation evidence¶
uv run ruff check api— all checks passed.uv run pytest -q api/tests— 2563 passed, 3 skipped.- New tests in
api/tests/test_blast_jobs_routes.py: test_assert_job_owner_isolation_default(flag off → 403 for foreign owner, allowed for empty owner and self).test_assert_job_owner_relaxed_when_flag_on(flag on → no raise).test_job_detail_blocks_other_owner_when_flag_off(route returns 403).test_job_detail_allows_other_owner_when_flag_on(route returns 200).