From e70dfa6d02f5ea3fbbce3f18f4435177a17bf4e7 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 10 Oct 2026 13:23:13 +0200 Subject: [PATCH] Routing: named client rotation outranks keycape-client-secret-generate Activation made the generic generate lane win the reported rapp-qonto rotation need (test_plan regression). Narrow its keywords and title to case-specific terms, give rapp-qonto-keycape-client its secret/rotation keywords, and add a two-way routing regression test. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 427672@bnt-lap001 Assistant-Session: a0a2367e-4697-440c-a4e5-9713c009f6d8 --- registry/routing/catalog.yaml | 9 ++++++--- tests/test_routing.py | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/registry/routing/catalog.yaml b/registry/routing/catalog.yaml index fdc559d..7767c44 100644 --- a/registry/routing/catalog.yaml +++ b/registry/routing/catalog.yaml @@ -952,7 +952,7 @@ entries: - id: rapp-qonto-keycape-client title: rapp-qonto KeyCape workload client - need_keywords: [rapp-qonto, qonto, keycape, oidc, client-credentials, service-token, workload-identity, binky] + need_keywords: [rapp-qonto, qonto, keycape, oidc, client-credentials, service-token, workload-identity, binky, client secret, secret, successor, rotate, rotation] owner_repo: key-cape subsystem: KeyCape + OpenBao warden_executes: false @@ -1532,7 +1532,7 @@ entries: lane: login - id: keycape-client-secret-generate - title: Generate a KeyCape client secret inside OpenBao custody (SecurityCase mint-secret) + title: SecurityCase mint-secret, first KeyCape client secret generated in custody # Pointer only, draft (WARDEN-WP-0044; railiance-platform RPF-WP-0054, # message d951386f, 2026-10-09). Lane named by SecurityCaseType # oidc-browser-relying-party 1.0, step mint-secret @@ -1552,7 +1552,10 @@ entries: workload_ref: applicability: not-applicable reason: "Per-case generation lane; each case's consuming service gets its own {consuming_service}-keycape-client entry." - need_keywords: [keycape client secret, generate client secret, mint-secret, client-secret-generate, oidc client secret, keycape/client-secret-generate, generated in custody, security case] + # Case-specific terms only. Broad phrases such as "keycape client secret" + # outranked named per-client lanes (rapp-qonto-keycape-client) on rotation + # needs, and this lane refuses an existing path (first generation only). + need_keywords: [mint-secret, client-secret-generate, keycape/client-secret-generate, generated in custody, generated_in_custody, security case, securitycase, oidc-browser-relying-party] owner_repo: railiance-platform subsystem: railiance-platform credential broker + OpenBao platform/workloads/keycape/ warden_executes: false diff --git a/tests/test_routing.py b/tests/test_routing.py index 0161a38..d3de0c9 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -149,6 +149,16 @@ def test_keycape_client_secret_generate_is_owner_native_and_never_proxied(): assert e.risk == "high" and e.rotation is not None +def test_named_client_rotation_outranks_generic_generate_lane(): + """Activating keycape-client-secret-generate must not capture a named client's + rotation need; it is first-generation only and refuses an existing path.""" + catalog = load_catalog(_repo_catalog()) + assert catalog.find("rotate rapp-qonto client secret")[0].id == "rapp-qonto-keycape-client" + assert catalog.find("mint-secret for a security case, generated in custody")[0].id == ( + "keycape-client-secret-generate" + ) + + def test_route_find_vault_token_ops_warden_prefers_broker_lane(): catalog = load_catalog(_repo_catalog()) matches = catalog.find("VAULT_TOKEN ops-warden warden sign", limit=3)