Skip to content

feat(multitenancy): add secure Yandex OAuth and account discovery (P4) - #24

Open
Adel7418 wants to merge 8 commits into
feat/multitenant-p3-identity-tenancyfrom
feat/multitenant-p4-yandex-oauth-vault
Open

Adel7418 wants to merge 8 commits into
feat/multitenant-p3-identity-tenancyfrom
feat/multitenant-p4-yandex-oauth-vault

Conversation

@Adel7418

@Adel7418 Adel7418 commented Sep 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

Stacked P4 pull request on top of #23 (feat/multitenant-p3-identity-tenancy).

Implemented:

  • P4-01/P4-02: secure Yandex OAuth start/callback flow and stable provider identity;
  • P4-03: AES-GCM envelope credential vault with connection/account-scoped AAD;
  • P4-04: serialized refresh, invalid-grant reauthorization, disconnect and credential purge lifecycle;
  • P4-05: strict ordinary/agency account discovery, encrypted provider Login, atomic reconciliation, stale inventory handling, RLS/FORCE RLS, and read-only direct.read capabilities;
  • P4-06: user/workspace/connection/account-bound read-only Direct client factory with explicit credentials, protected agency routing, pre-send lease revalidation, and no global credential fallback.
  • P4-07: explicit operator_local/public startup profiles with fail-closed public configuration, restricted route composition, bound OAuth dependency graph, safe cookies, and deterministic runtime cleanup.

P4-01 through P4-07 are implemented and independently gated. Final GitHub CI passed on da302c7cc53064362ae1a71c5607647e8bb06259.

Security properties

  • No caller-controlled Client-Login discovery path.
  • P4-05 never derives or grants direct.edit.
  • Provider Login is encrypted and excluded from safe DTO/repr/error surfaces.
  • Strict JSON parsing rejects duplicate keys, malformed data, LimitedBy: null, and non-RFC NaN/Infinity constants before reconciliation.
  • Failed/incomplete discovery preserves prior inventory.
  • Provider accounts are workspace/connection scoped with RLS + FORCE RLS.
  • Connection deletion cascades to provider accounts for disconnect and invalid-grant lifecycle paths.
  • Connection-scoped clients use the selected encrypted credential and agency Login only; advertiser requests omit Client-Login.
  • Membership, status, capability, version, and account binding are revalidated immediately before each provider request.
  • Connection-scoped clients allow only Direct get, never use operator units, and reject legacy account_balance() before settings or transport access.
  • Closed/invalidated leases fail locally; there is no fallback to global YANDEX_OAUTH_TOKEN.
  • Public startup uses fresh settings and fails closed unless PostgreSQL, OAuth, credential vault, HTTPS origin/callback, cookie, route, and capability invariants all pass.
  • Public composition excludes legacy/test/docs/OpenAPI routes, fake auth, global provider credentials, and live_write.
  • Injected public OAuth dependencies must match the validated settings and share the expected provider/persister/lifecycle graph.
  • Application-owned database runtime closes once on normal ASGI shutdown and on validated construction failures.
  • No live Yandex write or credential-bearing provider call was used for verification.

Verification

Final P4-05 fingerprint:

eb089fc72dcf9b656531a9f09f68d99c9c3af4386842bdf9807967f7fe12190a

Latest independent gates:

  • P4-05 account-discovery suite: 42 passed;
  • affected OAuth/vault/refresh regression receipt reused only for byte-identical blobs: 23 passed;
  • Ruff: PASS;
  • mypy: PASS (6 source files);
  • Alembic: 20260906_0010 (head);
  • OpenAPI sync: PASS;
  • git diff --check: PASS;
  • evidence: PASS / result_class: NONE;
  • verifier: PASS / result_class: NONE;
  • strict reviewer: PASS / result_class: NONE, HIGH=0, MEDIUM=0, LOW=0.

Final P4-06 fingerprint:

8d37b6cdc08f867b0887536f15a2cedf3d9d309bdcc2d5a1b84465b79c800e4f

Latest independent P4-06 gates:

  • focused factory/client/bootstrap suite: 38 passed;
  • full repository suite: 894 passed, 1 skipped;
  • Ruff: PASS;
  • mypy: PASS (3 source files);
  • Alembic: 20260906_0010 (head);
  • OpenAPI sync: PASS;
  • git diff --check: PASS;
  • evidence: PASS / result_class: NONE;
  • verifier: PASS / result_class: NONE;
  • strict reviewer follow-up: APPROVE / result_class: NONE, blocking findings=0.

Final P4-07 fingerprint:

1f5158bc7fcabd93992ab788fa40a3b6e1ee23e26d24c8d2fbfcaa94e9638aca

Latest independent P4-07 gates:

  • evidence targeted suite: 118 passed;
  • verifier ordered P4/public + Yandex asset regression: 101 passed;
  • verifier full repository suite: 981 passed, 1 skipped;
  • Ruff: PASS;
  • mypy: PASS (9 source files);
  • Alembic: 20260906_0010 (head);
  • OpenAPI sync: PASS;
  • repository secret guard: PASS;
  • git diff --check: PASS;
  • isolated patch apply-check: PASS;
  • evidence: PASS / result_class: NONE;
  • verifier: PASS / result_class: NONE;
  • strict reviewer follow-up: APPROVE / result_class: NONE, HIGH=0, MEDIUM=0, LOW=0.

Stack / rollout

@Adel7418
Adel7418 marked this pull request as ready for review September 6, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant