Make the offline RAG chain observable without widening credential access
Some checks failed
verify / verify (push) Has been cancelled

Expose the verified synthetic retrieval path through a typed React client and a non-root Nginx edge while keeping database credentials and data-network reachability out of the browser tier. A fixed-origin gateway preserves request boundaries and now closes upstream streams even when downstream disconnects before body iteration. The deployment ADR and runbooks record the four-network topology and its accepted Web edge-egress risk.

Constraint: The previously exposed Bailian key must be revoked and no live provider credential may enter Git, images, logs, or the browser.
Rejected: Connect Web directly to the data network | expands lateral reach to PostgreSQL.
Rejected: Publish the database-aware API on the edge network | gives a credential-bearing process a public default route.
Rejected: Buffer streaming responses in either proxy | prevents incremental chat delivery in the future.
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Do not mark Stage 1 or Stage 2 complete until the rotated-key live smoke and remaining stage gates pass.
Tested: make verify; 65 backend tests; 14 frontend tests; Docker image build; container health and isolation probes; real HTTP demo/status/search/docs/OpenAPI checks.
Not-tested: Live Bailian models, real document ingestion, business chat SSE generation, and final browser screenshot automation because the browser skill runtime was unavailable.
This commit is contained in:
2026-07-12 17:38:57 +08:00
parent 2fa27ae71c
commit c3bad0f186
60 changed files with 9062 additions and 82 deletions

View File

@@ -18,6 +18,8 @@ from app.persistence.job_queue_sql import ( # noqa: E402
COMPOSE = (ROOT / "compose.yaml").read_text(encoding="utf-8")
DOCKERFILE = (BACKEND / "Dockerfile").read_text(encoding="utf-8")
FRONTEND_DOCKERFILE = (ROOT / "frontend/Dockerfile").read_text(encoding="utf-8")
NGINX = (ROOT / "frontend/nginx.conf").read_text(encoding="utf-8")
DEMO_API = (BACKEND / "app/api/v1/demo.py").read_text(encoding="utf-8")
BOOTSTRAP = (ROOT / "ops/postgres/init/10-bootstrap-rag.sh").read_text(encoding="utf-8")
MIGRATION = (BACKEND / "migrations/versions/0001_initial_schema.py").read_text(encoding="utf-8")
@@ -35,6 +37,7 @@ def test_compose_isolates_database_credentials_and_networks() -> None:
migrate = _service_block("migrate")
api = _service_block("api")
gateway = _service_block("gateway")
web = _service_block("web")
provider_smoke = _service_block("provider-smoke")
seed_demo = _service_block("seed-demo")
seed_demo_offline = _service_block("seed-demo-offline")
@@ -59,15 +62,29 @@ def test_compose_isolates_database_credentials_and_networks() -> None:
assert "no-new-privileges:true" in api
assert "cap_drop:" in api and " - ALL" in api
assert '"127.0.0.1:8000:8000"' in gateway
assert " - edge" in gateway
assert '"127.0.0.1:8000:8000"' not in gateway
assert " - ingress" in gateway
assert " - data" in gateway
assert " - edge" not in gateway
assert " - egress" not in gateway
assert "secrets:" not in gateway
assert "POSTGRES_" not in gateway
assert "BAILIAN_" not in gateway
assert "read_only: true" in gateway
assert "no-new-privileges:true" in gateway
assert '"127.0.0.1:8000:8080"' in web
assert " - edge" in web
assert " - ingress" in web
assert " - data" not in web
assert " - egress" not in web
assert "secrets:" not in web
assert "POSTGRES_" not in web
assert "BAILIAN_" not in web
assert "read_only: true" in web
assert "no-new-privileges:true" in web
assert len(re.findall(r"(?m)^ ports:$", COMPOSE)) == 1
assert "bailian_api_key" in provider_smoke
assert "postgres_" not in provider_smoke
@@ -83,11 +100,15 @@ def test_compose_isolates_database_credentials_and_networks() -> None:
assert "./data/samples/public:/demo:ro" in seed_demo_offline
assert re.search(r"(?ms)^ data:\n.*?^ internal: true$", COMPOSE)
assert re.search(r"(?ms)^ ingress:\n.*?^ internal: true$", COMPOSE)
assert re.search(r"(?m)^ edge:$", COMPOSE)
assert re.search(r"(?m)^ egress:$", COMPOSE)
assert "USER 10001:10001" in DOCKERFILE
assert 'CMD ["uvicorn", "app.main:app"' in DOCKERFILE
assert "USER 101:101" in FRONTEND_DOCKERFILE
assert "proxy_buffering off" in NGINX
assert "server gateway:8000" in NGINX
def test_demo_queries_pin_governed_offline_identity() -> None: