Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/TRACEABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
| secrets from KV/DB, env bootstrap only | architecture/security decision | config/bootstrap/template validation | implemented-main |
| work-conserving fail-closed hourly API gate | automation safety decision | PR #74 protected-main workflow tests/exact-head evidence; scheduled/manual run remains required | implemented-main |
| non-fork RP Keyverse authorization boundary | ADR-0008; OIDC/JWT recipient validation and least-privilege policy | six-app audit, per-RP issuer/audience/tenant/ABAC/RBAC evidence required | accepted-contract |
| sidecar anonymous-access boundary | ADR-0008; private service-boundary and least-privilege policy | newsdom-api PR #595 fail-closed token gate; Keyverse-aware gateway evidence remains required for exposure | accepted-contract |
| pg-erd-cloud Keyverse organization boundary | ADR-0008; verified tenant binding before project authorization | pg-erd-cloud PR #855 `e4b4771` exact `org`/audience/`iat` checks, single-tenant profile, API-key bypass denial; shared multi-tenant persistence remains unimplemented | active-PR |
| sidecar anonymous-access boundary | ADR-0008; private service-boundary and least-privilege policy | newsdom-api PR #595 `f790252` fail-closed token gate, explicit anonymous opt-in, and pypdf Trivy remediation; Keyverse-aware gateway evidence remains required for exposure | active-PR |
| 100% production statement/branch/docstring | CWL quality contract | CI/pytest/interrogate | implemented-main |

## Research, standards, and operations records
Expand Down
13 changes: 9 additions & 4 deletions docs/adr/0008-keyverse-rp-authorization-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ The snapshot is reproducible from the Keyverse README at immutable revision
`4d2841071e9a8136298bb7198229d47ff406284d` and these audited application refs:

- `naruon`: `develop` at `da16757b78341de372c3fbd4d9c525dd9812bd1d`;
- `pg-erd-cloud`: `main` at `72afe6db712b145baaba084f64a1ff4fb36d9fd0`;
- `pg-erd-cloud`: PR #855 at `e4b4771fa0c46cbbcbd9ca7e777e20b5179b0bcd` (open; based on `main` at `72afe6db712b145baaba084f64a1ff4fb36d9fd0`);
- `semantic-data-portal`: PR #58 at `46b9fdb4480c665f6f513acfef4edfdb5848ca64`;
- `clearfolio`: `main` at `55d7ae8647208e301f282350f076eeddaba61d11`;
- `contextual-orchestrator`: `main` at `6841b71935e0b7cb98fb52bcb4709cc5100c8d87`;
- `newsdom-api`: PR #595 at `7b3770034cecb8494840c445c6e06b31622ebea6`.
- `newsdom-api`: PR #595 at `f79025224dabc997ea6376225066804f1ed6ba6e` (open; based on `develop` at `2f29e69c99a1201ce6b4e43370a463701efdc81c`).

| Application | Keyverse recognition | Current authorization | Finding and required direction |
|---|---|---|---|
| `naruon` | Generic OIDC/JWKS configuration accepts an issuer, audience, and `role`/`org`/`workspace`-shaped claims; no explicit Keyverse profile or acceptance fixture is named | RBAC plus ABAC exists in `backend/services/access_policy.py`; organization/workspace, ownership, delegation, consent, and capability checks precede role allows | Add an explicit Keyverse issuer/audience/JWKS deployment profile and exact-token acceptance test. Continue to reject issuer/audience/signature failures and never treat a hardcoded claim as proof of entitlement. |
| `pg-erd-cloud` | Generic OIDC/JWKS verification is present in `backend/app/auth.py`; Keyverse claim-to-tenant mapping is absent | Project-member RBAC (`viewer`/`editor`/`owner`) exists in `backend/app/permissions.py`; organization/workspace ABAC is not enforced | Map verified Keyverse `sub` to the local account and `org` to a tenant boundary before project lookup. Add tenant-qualified membership queries and cross-tenant denial tests. |
| `pg-erd-cloud` | Generic OIDC/JWKS verification is present; PR #855 adds an opt-in `OIDC_ORGANIZATION` profile that requires an exact typed Keyverse `org`, audience, and `iat` after token verification | Project-member RBAC (`viewer`/`editor`/`owner`) exists in `backend/app/permissions.py`; the profile adds deployment-level single-tenant `org` ABAC and rejects `pgerd_` API-key bypasses | Use the profile for one-tenant-per-database deployments. A shared multi-tenant database still needs a persisted tenant key, tenant-qualified membership/resource queries, composite constraints, and cross-tenant denial tests before authorization-ready status. |
| `semantic-data-portal` | OIDC verification exists, but the mapper recognizes `tenant_id`/`tid`/`organization` and plural `roles`, not Keyverse `org` and singular `role` | RBAC and ABAC/purpose/sensitivity/evidence policy exists in `src/sdp/policy.py` | Add the bounded Keyverse aliases and regression tests in the app repository; preserve tenant, purpose, row-filter, masking, and evidence checks. This is an immediate application fix, not a documentation-only exception. Keep the repo-wide security gate green: `cryptography` must be pinned at `50.0.0` or newer in the source and every hash-locked requirements artifact after CVE-2026-69247. |
| `clearfolio` | No production OIDC/JWT verifier; current runtime is a gateway/header tenant scaffold documented in `docs/security/2026-07-02-auth-tenant-model.md` | Permission checks and tenant ownership are implemented, with optional gateway HMAC; the caller identity is not yet a Keyverse-verified token | Keep production fail-closed. Replace public header trust with Keyverse issuer/audience/JWKS verification at the service or a cryptographically trusted gateway, then map `org`/`sub`/roles/scopes and retain same-tenant checks. |
| `contextual-orchestrator` | Bearer-token configuration distinguishes `admin` and `inference` scopes but has no OIDC/JWT Keyverse validation | Coarse token-scope RBAC exists; resource/tenant ABAC is not established | Add a user-facing Keyverse OIDC resource-server boundary or a separately authenticated service-token/mTLS boundary for internal calls. Keep admin and inference scopes separate and add tenant/resource ownership conditions before exposing multi-tenant work. |
| `newsdom-api` | No Keyverse OIDC integration; PR #595 makes the local bearer boundary fail closed by default and permits anonymous parsing only through explicit `NEWSDOM_ALLOW_ANONYMOUS=true` | No application RBAC/ABAC; it is a PDF-to-DOM sidecar | Keep it private infrastructure while it has no user authorization model. If reachable beyond a trusted internal gateway, require a Keyverse-aware gateway or verified service boundary; never enable the anonymous opt-in on an exposed deployment. |
| `newsdom-api` | No Keyverse OIDC integration; PR #595 makes the local bearer boundary fail closed by default and permits anonymous parsing only through explicit `NEWSDOM_ALLOW_ANONYMOUS=true` | No application RBAC/ABAC; it is a PDF-to-DOM sidecar | Keep it private infrastructure while it has no user authorization model. If reachable beyond a trusted internal gateway, require a Keyverse-aware gateway or verified service boundary; never enable the anonymous opt-in on an exposed deployment. The same PR also remediates the current `pypdf` Trivy findings. |

Keyverse itself also has two boundaries that must not be confused with
downstream application authorization:
Expand Down Expand Up @@ -86,6 +86,11 @@ downstream application authorization:
`tests/test_authz.py::test_keyverse_unknown_role_does_not_grant_access`,
`tests/test_api.py::test_oidc_jwks_verification_maps_verified_token_without_token_leak`,
and `tests/test_api.py::test_oidc_jwks_verification_rejects_wrong_audience`.
pg-erd-cloud PR #855 adds
`backend/tests/test_auth_security.py::test_keyverse_organization_claim_is_required_and_exact`
and an API-key bypass regression; NewsDOM PR #595 adds default-deny and
explicit-anonymous-mode tests. Both remain `active-PR` evidence until
their application changes reach protected branches.
The contract is not a promise that every application supports every claim;
each other RP must add and record its own exact acceptance-test paths before
it can leave `deployment-restricted` status.
Expand Down
Loading