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
9 changes: 6 additions & 3 deletions docs/OPERABILITY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Operability, Recovery, and Release Guide

**Status:** Accepted cross-cutting operating baseline
**Last reviewed:** 2026-08-09
**Last reviewed:** 2026-08-11

Feature-specific procedures under `docs/operations/`, federation/RP onboarding, and deployment READMEs remain authoritative for their slices. This guide defines the shared operating model and evidence needed before declaring the identity platform healthy or release-ready.

Expand Down Expand Up @@ -61,7 +61,10 @@ rotation source, claim-to-tenant mapping, ABAC/RBAC result, cross-tenant denial
result, and production-mode fail-closed result. A successful Keyverse client
receipt or mapper check is not sufficient acceptance evidence.

PR #72's mapper profile requires the same acceptance after merge: operators must test the **Naruon** product login/token/authorization journey using the `naruon-web` RP client ID and verify the expected audience and bounded claims. Mapper unit tests alone do not prove Naruon product authorization readiness.
The integrated PR #72 mapper profile requires the same acceptance: operators
must test the **Naruon** product login/token/authorization journey using the
`naruon-web` RP client ID and verify the expected audience and bounded claims.
Mapper unit tests alone do not prove Naruon product authorization readiness.

## Account merge recovery

Expand Down Expand Up @@ -95,7 +98,7 @@ Back up Keycloak PostgreSQL and Keyverse-owned configuration/audit/intent/receip

## Automation incident RCA

PR #74 demonstrates that a workflow can appear successful while doing no useful work if a GitHub API gate fails open. Scheduled governance must classify transport failure separately from a valid empty/unhealthy result, fit its time budget, keep provider secrets in the broker phase only, and require exact `success` for protected evidence. After PR #74 merges, operational closure requires a real protected-main scheduled/manual run.
PR #74 demonstrates that a workflow can appear successful while doing no useful work if a GitHub API gate fails open. Scheduled governance must classify transport failure separately from a valid empty/unhealthy result, fit its time budget, keep provider secrets in the broker phase only, and require exact `success` for protected evidence. With PR #74 integrated, operational closure requires a real protected-main scheduled/manual run.

## Release gate

Expand Down
10 changes: 5 additions & 5 deletions docs/PRD.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Product Requirements Document

**Status:** Accepted cross-cutting product baseline for protected `main` at `c8968ec1e68fab16d0ad8216fb5c8fd0b385e95f`
**Last reviewed:** 2026-08-09
**Status:** Accepted cross-cutting product baseline for protected `main` at `196814abe45ecf972a7776836af3933506d13fd5`
**Last reviewed:** 2026-08-11

## 1. Product purpose

Expand All @@ -27,10 +27,10 @@ Its job is to let CWL products consume stable standards-based identity without e

The current SCIM `PATCH active=false` deprovisioning path is not protected by the shared cross-process user-operation lock used by merge and full replacement. It must not be represented as transactionally serialized with merge until a source change and concurrency regression prove that boundary.

## 3. Active-PR boundaries
## 3. Integrated protected-main changes

- PR #72 adds a closed OIDC RP mapper profile for exactly one audience mapper plus bounded `role`, `org`, and `workspace` hardcoded claims; it remains **active-PR** and is not protected-main behavior until merged.
- PR #74 repairs the hourly product-development GitHub API/egress/time-budget/evidence boundary; it remains **active-PR** operational-governance work until merged and then proven by a protected-main run.
- PR #72 is integrated in protected main: the closed OIDC RP mapper profile permits exactly one audience mapper plus bounded `role`, `org`, and `workspace` hardcoded claims. Downstream RPs remain deployment-restricted until their issuer/audience/JWKS, tenant, ABAC/RBAC, and fail-closed acceptance evidence exists.
- PR #74 is integrated in protected main: the hourly product-development GitHub API/egress/time-budget/evidence boundary is fail-closed. Operational closure still requires a real protected-main scheduled or manual run.

## 4. Primary users

Expand Down
8 changes: 5 additions & 3 deletions docs/TEST_STRATEGY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Test Strategy

**Status:** Accepted quality baseline
**Last reviewed:** 2026-08-09
**Last reviewed:** 2026-08-11

## Mandatory gates

Expand Down Expand Up @@ -69,7 +69,9 @@ Use realistic create/read/update/replace/delete lifecycle, authoritative/deprovi
- Keyverse `org`/`workspace` claim mapping, tenant mismatch rejection, resource ownership/delegation, purpose/sensitivity, and role/scope elevation/downgrade;
- production fail-closed behavior for RPs whose Keyverse verifier or policy is unavailable.

PR #72 mapper tests remain active-PR evidence until merged. They should cover exact audience mapper, bounded `role`/`org`/`workspace`, Keycloak-generated mapper IDs/order, and rejection of scripts/arbitrary claims/classes.
Protected main includes the PR #72 mapper tests. They cover the exact audience
mapper, bounded `role`/`org`/`workspace`, Keycloak-generated mapper IDs/order,
and rejection of scripts/arbitrary claims/classes.

ADR-0008's application matrix remains deployment-restricted until each RP
repository supplies its own exact token-validation and ABAC/RBAC evidence.
Expand All @@ -91,7 +93,7 @@ Mirror `docs/THREAT_MODEL.md`: malicious IdP/LDAP URLs, path/resource IDs, dupli

## Documentation contract

CI should require PRD, TRD, Architecture, UML, ERD, Threat Model, Test Strategy, Operability, Traceability, ADR index, README, AGENTS, CLAUDE, CHANGELOG, and discoverable `docs/doctoring/`, `docs/papers/`, and `docs/operations/` research/standards/runbook records. It must assert PR #72/#74 remain active-PR claims until integrated and ADR-0008 remains indexed.
CI should require PRD, TRD, Architecture, UML, ERD, Threat Model, Test Strategy, Operability, Traceability, ADR index, README, AGENTS, CLAUDE, CHANGELOG, and discoverable `docs/doctoring/`, `docs/papers/`, and `docs/operations/` research/standards/runbook records. It must assert PR #72/#74 are recorded as integrated protected-main changes and ADR-0008 remains indexed.

## Release acceptance

Expand Down
12 changes: 8 additions & 4 deletions docs/THREAT_MODEL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Threat Model

**Status:** Accepted baseline for protected-main identity control plane
**Last reviewed:** 2026-08-09
**Last reviewed:** 2026-08-11

## Trust boundaries

Expand Down Expand Up @@ -44,7 +44,7 @@ flowchart LR
| tombstone reprovisioning | duplicate account resurrection | survivor pointer + disabled duplicate policy |
| password fallback | weakens passwordless policy | portable flow contains no password authenticator |
| RP redirect/origin mistake | auth-code/token theft | exact HTTPS/PKCE/client policy; separate native loopback profile |
| arbitrary protocol mapper | excessive claims/code execution | closed mapper classes/claims; PR #72 active-PR until merged |
| arbitrary protocol mapper | excessive claims/code execution | closed mapper classes/claims; PR #72 integrated in protected main |
| raw secret in desired state | leakage and poor rotation | secret-free RP source + separate credential provisioning |
| automation credential exposure | repository/provider compromise | isolated OpenCode/broker/verification/publication and reviewer separation |
| stale/false-green CI | unverified identity policy lands | exact-head checks, success-only evidence, fail-closed API gate |
Expand All @@ -59,9 +59,13 @@ flowchart LR
- **Denial of service:** API bodies, directory/provider configs, retries/timeouts, SCIM mutation rate, external lookups, queues, and automation loops are bounded.
- **Elevation of privilege:** public client IDs, email, UUIDs, or model output never create admin/reviewer/release authority.

## Current protected-main versus active PR
## Current protected-main versus operational acceptance

Protected main already has passwordless realm policy, account unification/SCIM, federation/directory/RP desired state, and deployment boundaries. PR #72 expands RP mappers; PR #74 repairs hourly automation. Those threat-surface changes remain active-PR until integrated and then require protected-main operational acceptance.
Protected main has passwordless realm policy, account unification/SCIM,
federation/directory/RP desired state, deployment boundaries, the PR #72 closed
RP mapper profile, and the PR #74 fail-closed hourly automation boundary.
Both integrated changes still require the protected-main operational acceptance
described in `docs/OPERABILITY.md`.

## Required security tests

Expand Down
6 changes: 3 additions & 3 deletions docs/TRACEABILITY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Requirements and Evidence Traceability

**Status:** Accepted cross-cutting baseline
**Last reviewed:** 2026-08-09
**Last reviewed:** 2026-08-11

| Requirement / decision | Standards / authoritative basis | Source/evidence boundary | Maturity |
|---|---|---|---|
Expand All @@ -12,14 +12,14 @@
| SAML/OIDC federation desired state | SAML/OIDC/Keycloak docs | preflight/reconciliation/receipt tests | implemented-main |
| LDAPS directory profile | LDAP RFC 4511–4515 + Keycloak component docs | directory preflight/reconciliation tests | implemented-main |
| secret-free RP desired state | OAuth/OIDC/PKCE/Keycloak client docs | RP preflight/reconciliation/integrity tests | implemented-main |
| RP audience/role/org/workspace mapper profile | OIDC/JWT audience + Keycloak mapper docs | PR #72 research/tests | active-PR |
| RP audience/role/org/workspace mapper profile | OIDC/JWT audience + Keycloak mapper docs | PR #72 protected-main source/tests; downstream RP acceptance remains required | implemented-main |
| merge/SCIM PUT shared operation lock | concurrency/data-integrity decision; ADR-0006 | merge + full-replacement lock/concurrency tests | implemented-main |
| SCIM PATCH active=false shared-lock parity | ADR-0006 boundary | current PATCH source has no shared-lock proof | gap-not-claimed |
| intent before mutation, receipt after re-observation | desired-state/recovery decision | federation/directory/RP reconciliation tests | implemented-main |
| receipt bound to exact desired-state version/hash | threat/recovery contract; ERD | persistence/migration/idempotency evidence required | accepted-contract |
| remote-first deletion | consistency/recovery decision | delete/reconciliation tests | implemented-main |
| 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 workflow tests/exact-head evidence | active-PR |
| 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 |
| 100% production statement/branch/docstring | CWL quality contract | CI/pytest/interrogate | implemented-main |

Expand Down
8 changes: 5 additions & 3 deletions docs/TRD.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse Technical Requirements Document

**Status:** Accepted cross-cutting technical baseline for protected main
**Last reviewed:** 2026-08-09
**Last reviewed:** 2026-08-11

## 1. Architecture objective

Expand Down Expand Up @@ -47,7 +47,9 @@ Current accepted profile is LDAPS-only, read-only, Kerberos-disabled, `trustEmai

Authorization code + PKCE S256, exact HTTPS redirect/origin/logout rules, exact scope policy, secret-free desired state, exact client lookup and UUID integrity, post-mutation re-observation, separate confidential-material provisioning, and downstream token/audience/tenant authorization acceptance. Native loopback redirects are not part of the protected-main RP profile; introducing them requires a separately accepted trust-policy change plus synchronized product, threat, test, and traceability evidence.

PR #72 claim mapper behavior remains active-PR until merged.
The PR #72 claim mapper profile is integrated in protected main. Downstream
authorization acceptance remains deployment-specific and is not implied by
Keycloak client reconciliation.

The per-application authorization matrix and remediation directions are governed
by ADR-0008. Keyverse client reconciliation does not imply downstream
Expand Down Expand Up @@ -81,7 +83,7 @@ Readiness is component/lifecycle specific. Preflight success does not imply Keyc

## 12. Automation boundary

Autonomous development uses NVIDIA NIM/OpenCode through an isolated model phase. Model execution has no publication/reviewer/release authority. PR #74 is active remediation of this boundary and must be proven again after protected-main merge.
Autonomous development uses NVIDIA NIM/OpenCode through an isolated model phase. Model execution has no publication/reviewer/release authority. PR #74 is integrated in protected main; its operational boundary must still be proven by a protected-main scheduled or manual run.

## 13. Change control

Expand Down
12 changes: 8 additions & 4 deletions docs/UML.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Keyverse UML and Runtime Views

**Status:** Accepted protected-main diagrams with active-PR items labelled.
**Last reviewed:** 2026-08-09
**Status:** Accepted protected-main diagrams with integrated changes labelled.
**Last reviewed:** 2026-08-11

## Component and authority view

Expand Down Expand Up @@ -86,7 +86,9 @@ sequenceDiagram
Deploy->>App: run login/logout/token acceptance
```

PR #72 extends this sequence with a closed mapper profile; it remains active-PR.
PR #72 extends this sequence with a closed mapper profile and is integrated
in protected main; downstream authorization acceptance remains deployment
specific.

Downstream authorization is a separate sequence after token issuance:

Expand Down Expand Up @@ -162,7 +164,9 @@ flowchart LR
REVIEW --> MAIN
```

PR #74 changes exact hourly gate implementation but not this authority separation.
PR #74 is integrated in protected main and changes the exact hourly gate
implementation without changing this authority separation; a protected-main
scheduled or manual run remains operational evidence.

## Maintenance rule

Expand Down
18 changes: 6 additions & 12 deletions tests/test_documentation_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,18 @@ def test_documentation_map_links_cross_cutting_contracts() -> None:
)


def test_active_pr_features_are_not_promoted_to_main() -> None:
"""Keep OIDC mapper and hourly-remediation PRs labelled as active work."""
def test_integrated_features_are_not_left_as_active_pr() -> None:
"""Keep integrated OIDC and hourly changes labelled as protected-main."""

prd = _read("docs/PRD.md")
traceability = _read("docs/TRACEABILITY.md")
assert any(
"PR #72" in line and "active-PR" in line
for line in prd.splitlines()
)
assert any(
"PR #74" in line and "active-PR" in line
for line in prd.splitlines()
)
assert any("PR #72" in line and "integrated" in line for line in prd.splitlines())
assert any("PR #74" in line and "integrated" in line for line in prd.splitlines())
mapper_row = _row_with(traceability, "RP audience/role/org/workspace mapper profile")
hourly_row = _row_with(traceability, "work-conserving fail-closed hourly API gate")
assert mapper_row.rstrip().endswith("| active-PR |")
assert mapper_row.rstrip().endswith("| implemented-main |")
assert "PR #72" in mapper_row
assert hourly_row.rstrip().endswith("| active-PR |")
assert hourly_row.rstrip().endswith("| implemented-main |")
assert "PR #74" in hourly_row


Expand Down
Loading