Files
ops-warden/tests/test_access.py
tegwick bd335ec724 feat(WARDEN-WP-0019): route secret-exec lanes to secrets-engine (route-primary, proxy fallback)
secrets-engine (SECRETS-WP-0003) shipped a native secret-exec front door
(`secrets-engine route/exec`, decision e6381a56) and asked ops-warden to route to it.
Bernd's call: route-primary, proxy-fallback — surface the secrets-engine exec as the
primary path for owned lanes, keep `warden access --exec` as a transparent fallback.

T1 — RouteEntry gains exec_owner/exec_command/pointer_command (+ has_native_exec),
screened for secret material like the other handoff fields. whynot-design-npm-publish
points its native exec at secrets-engine. `warden access` renders Primary (secrets-engine
exec) + Fallback (warden proxy); route/access JSON gain the fields and a native-exec-aware
next_action. Tests added; 217 pass, lint clean.

T2 — credential-routing.md adds secrets-engine as the secret-exec owner (route primary,
proxy fallback); SCOPE adds secrets-engine to Related Repos and records the npm lane as
production-exercised (@whynot/design@0.4.0); playbook leads with secrets-engine exec and
fixes the fallback one-liner (--field NPM_AUTH_TOKEN, --no-policy) per whynot-design.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 17:41:49 +02:00

121 lines
4.6 KiB
Python

"""Tests for the `warden access` operator front door (WP-0014 T2)."""
from __future__ import annotations
import json
from pathlib import Path
from typer.testing import CliRunner
from warden.access import expand_handoff, policy_gate_status
from warden.cli import app
from warden.routing.models import RouteEntry
runner = CliRunner()
def _repo_catalog() -> Path:
return Path(__file__).resolve().parents[1] / "registry" / "routing" / "catalog.yaml"
def _openbao_entry() -> RouteEntry:
return RouteEntry(
id="openbao-api-key",
title="API key, DB credential, or dynamic lease",
need_keywords=["api", "key", "npm", "token"],
owner_repo="railiance-platform",
subsystem="OpenBao",
warden_executes=False,
wiki_ref="wiki/CredentialRouting.md#routing-table",
canon_ref="net-kingdom/docs/x.md",
reviewed="2026-06-27",
status="active",
auth_method="key-cape OIDC → bao login -method=oidc role=<domain>",
path_template="platform/workloads/<domain>/<workload>/<bundle>",
fetch_command="bao kv get -field=<FIELD> <path_template>",
policy_ref="flex-auth check secret.read:<domain>",
exec_capable=True,
)
# --- pure expansion --------------------------------------------------------
def test_expand_inlines_path_template_token():
e = expand_handoff(_openbao_entry())
assert "<path_template>" not in e.fetch_command
assert e.fetch_command.startswith("bao kv get -field=<FIELD> platform/workloads/")
def test_expand_substitutes_domain():
e = expand_handoff(_openbao_entry(), domain="coulomb_social")
assert "coulomb_social" in e.path_template
assert "<domain>" not in e.path_template
assert "<domain>" not in e.auth_method
# owner-side names stay as placeholders — warden does not invent them
assert "<workload>" in e.path_template and "<bundle>" in e.path_template
def test_expand_without_domain_keeps_placeholder():
e = expand_handoff(_openbao_entry())
assert "<domain>" in e.path_template
def test_policy_gate_status_no_config(monkeypatch, tmp_path):
monkeypatch.setenv("WARDEN_CONFIG", str(tmp_path / "nope.yaml"))
assert "advisory" in policy_gate_status()
# --- CLI -------------------------------------------------------------------
def test_access_advisory_output(monkeypatch):
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "npm token", "--domain", "coulomb_social"])
assert r.exit_code == 0
assert "railiance-platform" in r.stdout
assert "platform/workloads/coulomb_social/" in r.stdout
# npm is an exec_capable lane → the front door leads with the proxy, not "owner vends".
assert "can fetch this for you" in r.stdout
assert "never holds" in r.stdout
def test_access_native_exec_shows_primary_and_fallback(monkeypatch):
"""A secrets-engine-owned lane leads with the native exec; proxy is the fallback."""
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "whynot-design-npm-publish"])
assert r.exit_code == 0
assert "secrets-engine exec --catalog whynot-design-npm-publish" in r.stdout
assert "Primary" in r.stdout and "Fallback" in r.stdout
def test_access_route_only_lane_says_owner_vends(monkeypatch):
"""A non-exec lane (host principal deploy) keeps the advise-only framing."""
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "host principal deploy"])
assert r.exit_code == 0
assert "warden advises, the owner vends" in r.stdout
def test_access_json_shape_is_secret_free(monkeypatch):
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "npm token", "--domain", "coulomb_social", "--json"])
assert r.exit_code == 0
payload = json.loads(r.stdout)
assert payload["id"] == "openbao-api-key"
assert payload["domain"] == "coulomb_social"
assert payload["handoff"]["exec_capable"] is True
# only placeholders/templates — never a concrete credential
assert "<FIELD>" in payload["handoff"]["fetch_command"]
def test_access_ssh_lane_points_to_sign(monkeypatch):
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "ssh cert for host access"])
assert r.exit_code == 0
assert "issues this directly" in r.stdout
assert "warden sign" in r.stdout
def test_access_no_match_exits_nonzero(monkeypatch):
monkeypatch.setenv("WARDEN_ROUTING_CATALOG", str(_repo_catalog()))
r = runner.invoke(app, ["access", "zzzz qqqq xyzzy"])
assert r.exit_code == 1