Record Policy Nexus metadata apply and diagnose bootstrap
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
This commit is contained in:
parent
1d5f35539d
commit
a6d47c51cc
3 changed files with 46 additions and 2 deletions
|
|
@ -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: approved
|
||||
status: applied
|
||||
created: '2026-08-31'
|
||||
updated: '2026-08-31'
|
||||
requester:
|
||||
|
|
@ -137,6 +137,16 @@ verification:
|
|||
and its public health endpoint returns 200; the KeyCape openbao-admin authorize
|
||||
path returns 302. No Forgejo identity, PAT, OpenBao secret value, Actions secret,
|
||||
or workflow run was created.
|
||||
- at: '2026-08-31T22:15:50+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.
|
||||
lifecycle:
|
||||
deactivate: Remove the repository Actions secret, revoke the Forgejo PAT, disable
|
||||
the OpenBao access path, and leave scheduled publication failing closed.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ SECRET = "FORGEJO_SOURCE_TOKEN"
|
|||
TOKEN_PREFIX = "policy-nexus-source-read-"
|
||||
SCOPES = ["read:repository"]
|
||||
REPO_DIR = Path(__file__).resolve().parent.parent
|
||||
DIAGNOSTIC_PATH = Path("/tmp/policy-nexus-source-bootstrap-diagnostic.json")
|
||||
NON_CODE_UNITS = (
|
||||
"repo.actions",
|
||||
"repo.packages",
|
||||
|
|
@ -43,6 +44,14 @@ class ProvisionError(RuntimeError):
|
|||
pass
|
||||
|
||||
|
||||
def write_diagnostic(stage: str, error: Exception | None = None) -> None:
|
||||
detail = str(error) if isinstance(error, ProvisionError) else "unexpected internal error"
|
||||
DIAGNOSTIC_PATH.write_text(
|
||||
json.dumps({"stage": stage, "detail": detail}, sort_keys=True) + "\n"
|
||||
)
|
||||
DIAGNOSTIC_PATH.chmod(0o600)
|
||||
|
||||
|
||||
def api_request(
|
||||
token: str,
|
||||
method: str,
|
||||
|
|
@ -332,6 +341,7 @@ def provision(admin_token: str) -> None:
|
|||
|
||||
|
||||
def outer() -> int:
|
||||
DIAGNOSTIC_PATH.unlink(missing_ok=True)
|
||||
result = subprocess.run(
|
||||
[
|
||||
"warden",
|
||||
|
|
@ -350,6 +360,8 @@ def outer() -> int:
|
|||
check=False,
|
||||
timeout=900,
|
||||
)
|
||||
if result.returncode != 0 and not DIAGNOSTIC_PATH.exists():
|
||||
write_diagnostic("forgejo-admin-route")
|
||||
return result.returncode
|
||||
|
||||
|
||||
|
|
@ -362,7 +374,12 @@ def main() -> int:
|
|||
admin_token = os.environ.get("API_TOKEN", "")
|
||||
if not admin_token:
|
||||
raise ProvisionError("Warden did not provide API_TOKEN")
|
||||
provision(admin_token)
|
||||
try:
|
||||
provision(admin_token)
|
||||
except Exception as error:
|
||||
write_diagnostic("provision", error)
|
||||
raise
|
||||
DIAGNOSTIC_PATH.unlink(missing_ok=True)
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,23 @@ class PolicyNexusForgejoSourceProvisionTests(unittest.TestCase):
|
|||
MODULE.verify_source_token("candidate", ["read:repository", "write:repository"])
|
||||
request.assert_not_called()
|
||||
|
||||
def test_diagnostic_redacts_unexpected_exception_details(self) -> None:
|
||||
with self.subTest("unexpected"):
|
||||
with mock.patch.object(MODULE, "DIAGNOSTIC_PATH") as path:
|
||||
MODULE.write_diagnostic("provision", RuntimeError("sensitive detail"))
|
||||
payload = path.write_text.call_args.args[0]
|
||||
self.assertNotIn("sensitive detail", payload)
|
||||
self.assertIn("unexpected internal error", payload)
|
||||
|
||||
with self.subTest("bounded provision error"):
|
||||
with mock.patch.object(MODULE, "DIAGNOSTIC_PATH") as path:
|
||||
MODULE.write_diagnostic(
|
||||
"provision",
|
||||
MODULE.ProvisionError("PUT /bounded/path returned HTTP 403"),
|
||||
)
|
||||
payload = path.write_text.call_args.args[0]
|
||||
self.assertIn("PUT /bounded/path returned HTTP 403", payload)
|
||||
|
||||
def test_actions_failure_revokes_pat_and_removes_new_kv_value(self) -> None:
|
||||
calls: list[tuple[str, str]] = []
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue