Follow-up from the Phase 1 gate (#31). The live-server e2e suites test_acl_e2e.py and test_ingestion_e2e.py are not yet CI-ready and were intentionally left out of the required gate. They were run locally with ACL_ENABLED=true + a real OpenAI key during #31 and came back 9 failed / 13 passed — but the failures are stale-test issues, not an ACL vulnerability:
test_00_acl_disabled_list_shows_all (and other acl_disabled_* tests) assert 200 but get 401 — they do not skip when ACL is enabled. The 401 is ACL correctly blocking unauthenticated access.
setUpClass polls GET /v1/ingest/job/{id} without entitlement headers, which now returns 401 under ACL, so ingested docs are not tracked and downstream tests fail/skip.
- Count-based assertions (e.g. "admin sees all in tenant") assume a clean database; they break against pre-existing data.
To make them CI-gateable
- Add proper skip guards keyed on the live
features.acl_enabled (run acl_disabled_* only when off, acl_enabled_* only when on), or split into two parametrized runs.
- Send entitlement headers (
X-Tenant-Id/X-User-Id/X-Roles) when polling job status.
- Make assertions tolerant of pre-existing data (filter to the docs this run ingested; avoid absolute counts).
- Then add a keyed CI job that boots uvicorn + a Celery worker, sets
ACL_ENABLED=true and OPENAI_API_KEY (from the OPENAI_API_KEY repo secret), waits for health, and runs these suites.
Until hardened, the ACL canary suite (test_acl_canary.py) remains the required leak-prevention gate, which passes cleanly without a key. Part of #25.
Follow-up from the Phase 1 gate (#31). The live-server e2e suites
test_acl_e2e.pyandtest_ingestion_e2e.pyare not yet CI-ready and were intentionally left out of the required gate. They were run locally withACL_ENABLED=true+ a real OpenAI key during #31 and came back 9 failed / 13 passed — but the failures are stale-test issues, not an ACL vulnerability:test_00_acl_disabled_list_shows_all(and otheracl_disabled_*tests) assert200but get401— they do not skip when ACL is enabled. The 401 is ACL correctly blocking unauthenticated access.setUpClasspollsGET /v1/ingest/job/{id}without entitlement headers, which now returns401under ACL, so ingested docs are not tracked and downstream tests fail/skip.To make them CI-gateable
features.acl_enabled(runacl_disabled_*only when off,acl_enabled_*only when on), or split into two parametrized runs.X-Tenant-Id/X-User-Id/X-Roles) when polling job status.ACL_ENABLED=trueandOPENAI_API_KEY(from theOPENAI_API_KEYrepo secret), waits for health, and runs these suites.Until hardened, the ACL canary suite (
test_acl_canary.py) remains the required leak-prevention gate, which passes cleanly without a key. Part of #25.