Fix KV v2 policy path shape; live end-to-end verification succeeded
Two more real bugs found completing this lane for real: 1. platform-admin's own policy had no entry for the new reins/ mount -- the founder's paste-once-provision write 403'd because the admin identity that created the mount was never granted access to operate on it. Fixed live (added path "reins/*" matching every other mount already in that policy). 2. _policy_hcl wrote the bare KV-v1-shaped path (reins/rein-openweights/openrouter) instead of KV v2's data/+metadata/ sub-paths -- bao token capabilities on the bare path even reported full access, but the actual kv get still 403'd, because OpenBao evaluates the real request against the data/-prefixed path. Caught when the AppRole's own read failed during live verification. Fixed in code (now emits both data/ and metadata/ paths), locked in with a dedicated unit test, and re-applied to the live policy. Live end-to-end verification succeeded after both fixes: real AppRole login, real KV v2 read via the corrected policy, real OpenRouter call, real commit -- with OPENROUTER_API_KEY unset the whole time. Plan status: catalogued. glas-harness/GLAS-WP-0002-T02 is closed by this. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
846ef0561c
commit
9bcb5819de
3 changed files with 79 additions and 4 deletions
|
|
@ -3,7 +3,21 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
import pytest
|
||||
|
||||
from ops_mason.executor import AppRoleKVSpec, BuildError, BuildRefused, build_approle_kv_lane
|
||||
from ops_mason.executor import (
|
||||
AppRoleKVSpec,
|
||||
BuildError,
|
||||
BuildRefused,
|
||||
_policy_hcl,
|
||||
build_approle_kv_lane,
|
||||
)
|
||||
|
||||
|
||||
def test_policy_hcl_uses_kv_v2_data_and_metadata_paths() -> None:
|
||||
hcl = _policy_hcl("reins/rein-openweights/openrouter", ("read",))
|
||||
assert 'path "reins/data/rein-openweights/openrouter" {' in hcl
|
||||
assert 'path "reins/metadata/rein-openweights/openrouter" {' in hcl
|
||||
assert 'path "reins/rein-openweights/openrouter" {' not in hcl
|
||||
assert 'capabilities = ["read"]' in hcl
|
||||
from ops_mason.plan import ConstructionPlan
|
||||
|
||||
|
||||
|
|
@ -88,8 +102,11 @@ def test_build_writes_policy_approle_and_delivers_credentials(tmp_path) -> None:
|
|||
assert oct(secret_id_file.stat().st_mode)[-3:] == "600"
|
||||
|
||||
# policy write call carried the HCL on stdin, not argv -- never in a log line
|
||||
# -- KV v2 shape: data/ and metadata/ sub-paths, not the bare path
|
||||
policy_call = next(c for c in run.call_args_list if c.args[0][:2] == ["bao", "policy"])
|
||||
assert "reins/test/openrouter" in policy_call.kwargs["input"]
|
||||
assert 'path "reins/data/test/openrouter"' in policy_call.kwargs["input"]
|
||||
assert 'path "reins/metadata/test/openrouter"' in policy_call.kwargs["input"]
|
||||
assert 'path "reins/test/openrouter"' not in policy_call.kwargs["input"]
|
||||
|
||||
# audit record landed at the explicit path, metadata only, no role_id/secret_id values
|
||||
audit_text = spec.audit_log_path.read_text()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue