Activate Policy Nexus source credential lane
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
This commit is contained in:
codex 2026-09-01 01:35:48 +02:00
parent a6d47c51cc
commit 62423fd092
3 changed files with 207 additions and 7 deletions

View file

@ -3,7 +3,7 @@ kind: credential-change-request
schema_version: 1
request_type: workload-kv-read
title: Policy Nexus Forgejo private-source read token lane
status: applied
status: active
created: '2026-08-31'
updated: '2026-08-31'
requester:
@ -75,8 +75,8 @@ access_frontdoor:
type: ops-warden
catalog_id: policy-nexus-forgejo-source-read
selector: policy nexus Forgejo private source repository read token Actions
readiness: pending-review
resolvable: false
readiness: ready
resolvable: true
delivery:
surface: forgejo-actions-secret
bootstrap_command: warden access openbao-platform-admin-login --exec -- scripts/openbao-bootstrap-policy-nexus-source.sh
@ -147,6 +147,99 @@ verification:
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:19:13+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:20:52+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:22:40+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:24:53+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:27:18+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:29:29+00:00'
actor: attended operator via governed platform-admin lane
kind: delegated_metadata_apply
result: passed
details:
- Delegated metadata applier ran as attended operator via governed platform-admin
lane using local bao CLI ambient authority.
- 'Policy metadata write: sys/policies/acl/workload-kv-read-policy-nexus-forgejo-source'
- 'Auth role metadata write: auth/netkingdom/role/policy-nexus-forgejo-source-workload-kv-read'
- No secret values were read, written, printed, or accepted in argv.
- at: '2026-08-31T22:29:36+00:00'
actor: attended operator via governed platform-admin lane
kind: forgejo_source_bootstrap
result: passed
details:
- Restricted user policy-nexus-source and all-repository repo.code-read team policy-nexus-source-readers
verified; PAT policy-nexus-source-read-20260831T222932Z reports exactly read:repository;
archive read passed; effective repository permission is read-only; Actions-secret
read and instance-admin probes were denied; OpenBao and repository Actions secret
were populated without value output; workflow dispatch run_id=3802.
- at: '2026-08-31T23:28:57+00:00'
actor: codex via verified Forgejo Actions
kind: workflow_verification
result: passed
details:
- Forgejo Actions run 32 succeeded for exact Policy Nexus commit 1e6720b9eeba819b42133afcdfb9693608cddb42
after resolving the complete private-source inventory and publishing 65 documents.
- Candidate OCI digest sha256:a3a2b7b8b9432535771b588b9c78c554924ec1adc6d5a9bbc1c35b28fea6b724;
publication manifest 0af785af708b3698bb7af89aacf246be93031c69566180699c7dfaf1b3e549d3;
source inventory 2ff18298f0bd8ce75ca3adcdf09323f136a8ff71a2d55a2e43556d55a0bbf250;
source set 5f9e0bb9c19f95927c6bee96ad72f5446cb9a28f188effafe443446c5c07b0b0.
- The run used the repository Actions secret and emitted no credential value.
- at: '2026-08-31T23:29:23+00:00'
actor: codex via installed ops-warden CLI
kind: frontdoor_activation
result: passed
details:
- Installed Warden catalog route policy-nexus-forgejo-source-read is active, exact,
high-risk, and resolvable with no placeholders.
- Warden route and plan select the exact OpenBao path and FORGEJO_SOURCE_TOKEN
field; agent callers are limited to sanctioned exec, out, or wrap transports.
- 'The complete ops-warden suite passed: 406 selected tests, including the generated
high-risk data-path boundary.'
lifecycle:
deactivate: Remove the repository Actions secret, revoke the Forgejo PAT, disable
the OpenBao access path, and leave scheduled publication failing closed.

View file

@ -4,10 +4,12 @@
from __future__ import annotations
import argparse
import base64
import datetime as dt
import json
import os
from pathlib import Path
import re
import secrets
import subprocess
import sys
@ -52,6 +54,33 @@ def write_diagnostic(stage: str, error: Exception | None = None) -> None:
DIAGNOSTIC_PATH.chmod(0o600)
def classify_warden_failure(result: subprocess.CompletedProcess[bytes]) -> str:
output = (result.stdout or b"") + b"\n" + (result.stderr or b"")
text = output.decode("utf-8", errors="replace").lower()
checks = (
("routing catalog", "routing-catalog"),
("caller auth", "caller-auth"),
("permission denied", "owner-permission"),
("fetch failed", "owner-fetch"),
("policy denied", "policy-denied"),
("founder_required", "founder-required"),
("not valid", "invalid-invocation"),
("requires --", "missing-argument"),
)
for needle, classification in checks:
if needle in text:
return classification
return "unclassified"
def sanitize_warden_failure(result: subprocess.CompletedProcess[bytes]) -> str:
output = (result.stdout or b"") + b"\n" + (result.stderr or b"")
text = output.decode("utf-8", errors="replace")
text = re.sub(r"[A-Za-z0-9_=.:-]{20,}", "<redacted>", text)
lines = [line.strip() for line in text.splitlines() if line.strip()]
return " | ".join(lines[-8:])[:600] or f"nested Warden exit {result.returncode}"
def api_request(
token: str,
method: str,
@ -60,6 +89,8 @@ def api_request(
payload: dict[str, object] | None = None,
expected: tuple[int, ...] = (200,),
read_body: bool = True,
extra_headers: dict[str, str] | None = None,
authorization: str | None = None,
) -> tuple[int, object | None]:
data = None if payload is None else json.dumps(payload).encode()
request = urllib.request.Request(
@ -67,9 +98,10 @@ def api_request(
data=data,
method=method,
headers={
"Authorization": f"token {token}",
"Authorization": authorization or f"token {token}",
"Accept": "application/json",
**({"Content-Type": "application/json"} if data is not None else {}),
**(extra_headers or {}),
},
)
try:
@ -267,15 +299,41 @@ def provision(admin_token: str) -> None:
token_name = TOKEN_PREFIX + timestamp
token_id: int | None = None
source_token = ""
service_password = ""
basic_authorization = ""
bao_written = False
activated = False
try:
_, created = api_request(
service_password = secrets.token_urlsafe(48)
api_request(
admin_token,
"PATCH",
f"/admin/users/{USER}",
payload={
"password": service_password,
"must_change_password": False,
"restricted": True,
"admin": False,
"allow_create_organization": False,
"allow_git_hook": False,
"allow_import_local": False,
"max_repo_creation": 0,
"prohibit_login": False,
"active": True,
"visibility": "private",
},
expected=(200,),
)
basic = base64.b64encode(f"{USER}:{service_password}".encode()).decode()
basic_authorization = f"Basic {basic}"
basic = ""
_, created = api_request(
"",
"POST",
f"/users/{USER}/tokens",
payload={"name": token_name, "scopes": SCOPES},
expected=(201,),
authorization=basic_authorization,
)
if not isinstance(created, dict) or not isinstance(created.get("id"), int):
raise ProvisionError("Forgejo returned an invalid access-token record")
@ -326,10 +384,11 @@ def provision(admin_token: str) -> None:
if not activated and token_id is not None:
try:
api_request(
admin_token,
"",
"DELETE",
f"/users/{USER}/tokens/{token_id}",
expected=(204, 404),
authorization=basic_authorization,
)
except Exception:
pass
@ -338,6 +397,8 @@ def provision(admin_token: str) -> None:
raise
finally:
source_token = ""
service_password = ""
basic_authorization = ""
def outer() -> int:
@ -361,7 +422,10 @@ def outer() -> int:
timeout=900,
)
if result.returncode != 0 and not DIAGNOSTIC_PATH.exists():
write_diagnostic("forgejo-admin-route")
write_diagnostic(
f"forgejo-admin-route:{classify_warden_failure(result)}",
ProvisionError(sanitize_warden_failure(result)),
)
return result.returncode

View file

@ -25,6 +25,25 @@ class PolicyNexusForgejoSourceProvisionTests(unittest.TestCase):
self.assertIn("repo.actions", MODULE.NON_CODE_UNITS)
self.assertIn("repo.packages", MODULE.NON_CODE_UNITS)
def test_token_creation_accepts_target_user_basic_auth(self) -> None:
with mock.patch.object(MODULE.urllib.request, "urlopen") as urlopen:
response = mock.MagicMock()
response.status = 201
response.read.return_value = (
b'{"id": 1, "sha1": "candidate", "scopes": ["read:repository"]}'
)
urlopen.return_value.__enter__.return_value = response
MODULE.api_request(
"",
"POST",
"/users/policy-nexus-source/tokens",
payload={"name": "candidate", "scopes": ["read:repository"]},
expected=(201,),
authorization="Basic non-production",
)
request = urlopen.call_args.args[0]
self.assertEqual(request.get_header("Authorization"), "Basic non-production")
def test_broader_returned_scope_is_rejected_before_network_checks(self) -> None:
with mock.patch.object(MODULE, "api_request") as request:
with self.assertRaises(MODULE.ProvisionError):
@ -48,6 +67,28 @@ class PolicyNexusForgejoSourceProvisionTests(unittest.TestCase):
payload = path.write_text.call_args.args[0]
self.assertIn("PUT /bounded/path returned HTTP 403", payload)
def test_warden_failure_classification_is_allowlisted(self) -> None:
result = subprocess.CompletedProcess(
["warden"],
2,
stdout=b"opaque provider material\n",
stderr=b"fetch failed (exit 2) - check caller auth and the path\n",
)
classification = MODULE.classify_warden_failure(result)
self.assertEqual(classification, "caller-auth")
self.assertNotIn("opaque provider material", classification)
def test_warden_failure_summary_redacts_token_like_strings(self) -> None:
result = subprocess.CompletedProcess(
["warden"],
2,
stdout=b"route failed for hvs.NONPRODUCTION_SECRET_SENTINEL\n",
stderr=b"invalid invocation\n",
)
summary = MODULE.sanitize_warden_failure(result)
self.assertIn("invalid invocation", summary)
self.assertNotIn("NONPRODUCTION_SECRET_SENTINEL", summary)
def test_actions_failure_revokes_pat_and_removes_new_kv_value(self) -> None:
calls: list[tuple[str, str]] = []
@ -57,6 +98,8 @@ class PolicyNexusForgejoSourceProvisionTests(unittest.TestCase):
return 200, []
if path.endswith("/actions/secrets?limit=100"):
return 200, []
if method == "PATCH" and path == "/admin/users/policy-nexus-source":
return 200, {"login": "policy-nexus-source", "restricted": True}
if method == "POST" and path == "/users/policy-nexus-source/tokens":
return 201, {
"id": 73,