Correct whynot credential tenant path
This commit is contained in:
@@ -3,9 +3,9 @@ kind: credential-change-request
|
||||
schema_version: 1
|
||||
request_type: workload-kv-read
|
||||
title: whynot-design npm publish token lane
|
||||
status: approved
|
||||
status: proposed
|
||||
created: '2026-06-27'
|
||||
updated: '2026-06-27'
|
||||
updated: '2026-06-28'
|
||||
requester:
|
||||
agent: ops-warden
|
||||
message_id: fe5b1696-8956-4bd5-9d6f-dbde1901a076
|
||||
@@ -26,15 +26,22 @@ review:
|
||||
decision: approved
|
||||
comment: 'State Hub decision 250669d0-8475-4527-9624-cd072249f9a9: APPROVE: scoped
|
||||
path and confirmed binding are acceptable'
|
||||
- at: '2026-06-27T22:54:20+00:00'
|
||||
reviewer: bernd.worsch
|
||||
decision: scope_corrected_requires_review
|
||||
comment: Corrected tenant from whynot-design to coulomb per operator clarification.
|
||||
The previous approval covered platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
and must not be reused for the corrected platform/workloads/coulomb/whynot-design/npm-publish
|
||||
scope.
|
||||
target:
|
||||
domain: financials
|
||||
tenant: whynot-design
|
||||
tenant: coulomb
|
||||
workload: whynot-design
|
||||
environment: production
|
||||
purpose: npm package publishing through ops-warden caller-scoped fetch/exec
|
||||
openbao:
|
||||
mount: platform
|
||||
kv_path: platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
kv_path: platform/workloads/coulomb/whynot-design/npm-publish
|
||||
fields:
|
||||
- NPM_AUTH_TOKEN
|
||||
policy_name: workload-kv-read-whynot-design-npm-publish
|
||||
@@ -90,7 +97,6 @@ state_hub:
|
||||
related_workplan_id: RAILIANCE-WP-0006
|
||||
ops_warden_reply_message_id: b175c561-7858-43f5-a309-949b0dede1b4
|
||||
ops_warden_batch_message_id: fe5b1696-8956-4bd5-9d6f-dbde1901a076
|
||||
decision_id: 250669d0-8475-4527-9624-cd072249f9a9
|
||||
decision_api_url: http://127.0.0.1:8000/decisions/250669d0-8475-4527-9624-cd072249f9a9
|
||||
decision_dashboard_url: http://127.0.0.1:3000/decisions
|
||||
decision_resolved_at: '2026-06-27T22:04:32.956077Z'
|
||||
superseded_decision_id: 250669d0-8475-4527-9624-cd072249f9a9
|
||||
superseded_decision_resolved_at: '2026-06-27T22:04:32.956077Z'
|
||||
superseded_decision_reason: tenant/workload scope corrected before secret provisioning
|
||||
|
||||
@@ -137,12 +137,16 @@ Default pattern:
|
||||
workload namespace.
|
||||
3. Reference that Kubernetes Secret from the Deployment, Job, or CronJob.
|
||||
|
||||
Path convention:
|
||||
Path convention for workload credential custody:
|
||||
|
||||
```text
|
||||
platform/workloads/<namespace>/<service-account>/<secret-name>
|
||||
platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>
|
||||
```
|
||||
|
||||
Kubernetes namespace and service-account bounds belong in the OpenBao auth role
|
||||
or External Secrets binding, not in the tenant segment unless the namespace is
|
||||
itself the approved workload identity.
|
||||
|
||||
Use CSI-mounted files only for workloads that need file references, sharper
|
||||
mount boundaries, or refresh behavior that should not rewrite application
|
||||
manifests. Do not use the OpenBao injector in the current deployment.
|
||||
|
||||
@@ -103,7 +103,7 @@ A reviewer should see a concise rendered proposal:
|
||||
Request: whynot-design npm publish token lane
|
||||
Type: workload-kv-read
|
||||
Mount/path/field:
|
||||
platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
platform/workloads/coulomb/whynot-design/npm-publish
|
||||
NPM_AUTH_TOKEN
|
||||
Policy:
|
||||
workload-kv-read-whynot-design-npm-publish
|
||||
|
||||
@@ -395,7 +395,7 @@ tenant contract):
|
||||
Path convention:
|
||||
|
||||
```text
|
||||
platform/workloads/<namespace>/<service-account>/<secret-name>
|
||||
platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>
|
||||
platform/object-storage/<consumer>
|
||||
platform/databases/<consumer>
|
||||
platform/operators/<purpose>
|
||||
|
||||
@@ -25,8 +25,10 @@ Ops-warden batch follow-up:
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| ops-warden catalog id | `whynot-design-npm-publish` |
|
||||
| Tenant/org | `coulomb` |
|
||||
| Workload/project | `whynot-design` |
|
||||
| KV mount | `platform` |
|
||||
| OpenBao CLI path | `platform/workloads/whynot-design/whynot-design/npm-publish` |
|
||||
| OpenBao CLI path | `platform/workloads/coulomb/whynot-design/npm-publish` |
|
||||
| Secret field | `NPM_AUTH_TOKEN` |
|
||||
| Front-door readiness | `template`, `resolvable=false` until CCR verification |
|
||||
| Read policy | `workload-kv-read-whynot-design-npm-publish` |
|
||||
@@ -45,7 +47,7 @@ bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
|
||||
Expected OpenBao fetch shape:
|
||||
|
||||
```bash
|
||||
bao kv get -field=NPM_AUTH_TOKEN platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
bao kv get -field=NPM_AUTH_TOKEN platform/workloads/coulomb/whynot-design/npm-publish
|
||||
```
|
||||
|
||||
Expected ops-warden exec shape after activation:
|
||||
@@ -63,8 +65,8 @@ logging it.
|
||||
The source policy grants only:
|
||||
|
||||
```text
|
||||
read platform/data/workloads/whynot-design/whynot-design/npm-publish
|
||||
read platform/metadata/workloads/whynot-design/whynot-design/npm-publish
|
||||
read platform/data/workloads/coulomb/whynot-design/npm-publish
|
||||
read platform/metadata/workloads/coulomb/whynot-design/npm-publish
|
||||
```
|
||||
|
||||
It does not grant write, delete, patch, sudo, auth, sibling workload, or parent
|
||||
@@ -121,7 +123,7 @@ and service account.
|
||||
An approved operator must create or confirm the secret with:
|
||||
|
||||
```text
|
||||
path: platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
path: platform/workloads/coulomb/whynot-design/npm-publish
|
||||
field: NPM_AUTH_TOKEN
|
||||
```
|
||||
|
||||
@@ -129,14 +131,14 @@ In the OpenBao UI, open the `platform` KV engine and create or edit the secret
|
||||
at:
|
||||
|
||||
```text
|
||||
workloads/whynot-design/whynot-design/npm-publish
|
||||
workloads/coulomb/whynot-design/npm-publish
|
||||
```
|
||||
|
||||
For policies and API checks, the same KV-v2 secret is addressed as:
|
||||
|
||||
```text
|
||||
platform/data/workloads/whynot-design/whynot-design/npm-publish
|
||||
platform/metadata/workloads/whynot-design/whynot-design/npm-publish
|
||||
platform/data/workloads/coulomb/whynot-design/npm-publish
|
||||
platform/metadata/workloads/coulomb/whynot-design/npm-publish
|
||||
```
|
||||
|
||||
The OpenBao UI path does not include the `data/` or `metadata/` segment. Those
|
||||
@@ -169,7 +171,7 @@ Send ops-warden only these pointers:
|
||||
```text
|
||||
catalog id: whynot-design-npm-publish
|
||||
mount: platform
|
||||
path: platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
path: platform/workloads/coulomb/whynot-design/npm-publish
|
||||
field: NPM_AUTH_TOKEN
|
||||
oidc login: bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
|
||||
policy: workload-kv-read-whynot-design-npm-publish
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
# path used by ops-warden's caller-scoped access lane. It does not grant list
|
||||
# access to sibling workloads or mutation capabilities.
|
||||
|
||||
path "platform/data/workloads/whynot-design/whynot-design/npm-publish" {
|
||||
path "platform/data/workloads/coulomb/whynot-design/npm-publish" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "platform/metadata/workloads/whynot-design/whynot-design/npm-publish" {
|
||||
path "platform/metadata/workloads/coulomb/whynot-design/npm-publish" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ Applies source-owned OpenBao workload KV read-lane policies.
|
||||
|
||||
Current lane:
|
||||
- policy: workload-kv-read-whynot-design-npm-publish
|
||||
- path: platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
- path: platform/workloads/coulomb/whynot-design/npm-publish
|
||||
- field: NPM_AUTH_TOKEN
|
||||
|
||||
The script reads an OpenBao operator token from OPENBAO_TOKEN_FILE or an
|
||||
@@ -131,7 +131,7 @@ Remaining live steps:
|
||||
1. Confirm the whynot-design KeyCape/NetKingdom bound claim or service account.
|
||||
2. Create auth/netkingdom/role/whynot-design-workload-kv-read with only the
|
||||
workload-kv-read-whynot-design-npm-publish policy.
|
||||
3. Provision platform/workloads/whynot-design/whynot-design/npm-publish with
|
||||
3. Provision platform/workloads/coulomb/whynot-design/npm-publish with
|
||||
field NPM_AUTH_TOKEN through approved OpenBao/operator custody.
|
||||
4. Run positive and negative fetch verification without printing the token.
|
||||
NEXT
|
||||
|
||||
@@ -50,7 +50,7 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
ccr, _errors, warnings = credential_change.validate_ccr(self.sample)
|
||||
rendered = credential_change.render_summary(ccr, warnings)
|
||||
self.assertIn("whynot-design npm publish token lane", rendered)
|
||||
self.assertIn("platform/workloads/whynot-design/whynot-design/npm-publish", rendered)
|
||||
self.assertIn("platform/workloads/coulomb/whynot-design/npm-publish", rendered)
|
||||
self.assertIn("whynot-design-npm-publish", rendered)
|
||||
self.assertIn("readiness: template resolvable=False", rendered)
|
||||
self.assertIn("approve | deny | needs_changes", rendered)
|
||||
@@ -58,18 +58,15 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
def test_status_payload_marks_template_not_resolvable(self) -> None:
|
||||
ccr, _errors, warnings = credential_change.validate_ccr(self.sample)
|
||||
payload = credential_change.status_payload(ccr, warnings)
|
||||
self.assertTrue(payload["apply_allowed"])
|
||||
self.assertFalse(payload["apply_allowed"])
|
||||
self.assertFalse(payload["frontdoor_resolvable"])
|
||||
self.assertEqual(payload["access_frontdoor"]["readiness"], "template")
|
||||
self.assertEqual(payload["access_frontdoor"]["catalog_id"], "whynot-design-npm-publish")
|
||||
self.assertEqual(payload["apply_blockers"], [])
|
||||
self.assertEqual(payload["apply_blockers"], ["apply requires status approved, got proposed"])
|
||||
self.assertEqual(payload["warnings"], [])
|
||||
self.assertEqual(
|
||||
payload["state_hub"]["decision_id"],
|
||||
"250669d0-8475-4527-9624-cd072249f9a9",
|
||||
)
|
||||
self.assertIsNone(payload["state_hub"]["decision_id"])
|
||||
self.assertIn(
|
||||
"front door requires CCR status active, got approved",
|
||||
"front door requires CCR status active, got proposed",
|
||||
payload["frontdoor_blockers"],
|
||||
)
|
||||
self.assertIn("front door is marked resolvable=false", payload["frontdoor_blockers"])
|
||||
@@ -94,6 +91,11 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
copied = Path(tmp) / self.sample.name
|
||||
shutil.copy2(self.sample, copied)
|
||||
copied_ccr = credential_change.load_yaml(copied)
|
||||
copied_ccr.setdefault("state_hub", {})[
|
||||
"decision_id"
|
||||
] = "250669d0-8475-4527-9624-cd072249f9a9"
|
||||
credential_change.dump_yaml(copied, copied_ccr)
|
||||
original = credential_change.state_hub_decision_status
|
||||
try:
|
||||
credential_change.state_hub_decision_status = lambda _ccr, _url: {
|
||||
@@ -144,7 +146,7 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"# bao kv put platform/workloads/whynot-design/whynot-design/npm-publish",
|
||||
"# bao kv put platform/workloads/coulomb/whynot-design/npm-publish",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn("NPM_AUTH_TOKEN=<enter-through-approved-custody>", rendered)
|
||||
@@ -199,7 +201,7 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
def test_generated_policy_is_narrow(self) -> None:
|
||||
ccr, _errors, _warnings = credential_change.validate_ccr(self.sample)
|
||||
policy = credential_change.generated_policy_hcl(ccr)
|
||||
self.assertIn('path "platform/data/workloads/whynot-design/whynot-design/npm-publish"', policy)
|
||||
self.assertIn('path "platform/data/workloads/coulomb/whynot-design/npm-publish"', policy)
|
||||
self.assertNotIn("*", policy)
|
||||
self.assertNotIn("delete", policy)
|
||||
|
||||
|
||||
@@ -123,12 +123,16 @@ Kubernetes workloads, use External Secrets Operator to materialize OpenBao
|
||||
values as Kubernetes Secrets. Do not use the OpenBao injector in the current
|
||||
deployment.
|
||||
|
||||
Runtime path convention:
|
||||
Runtime path convention for workload credential custody:
|
||||
|
||||
```text
|
||||
platform/workloads/<namespace>/<service-account>/<secret-name>
|
||||
platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>
|
||||
```
|
||||
|
||||
Kubernetes namespace and service-account bounds belong in the auth role or
|
||||
External Secrets binding unless the namespace is itself the approved workload
|
||||
identity.
|
||||
|
||||
ArgoCD repository credentials are operator credentials, not workload secrets,
|
||||
and should live under:
|
||||
|
||||
|
||||
@@ -52,11 +52,10 @@ whynot-design.
|
||||
|
||||
## Proposed Contract
|
||||
|
||||
Use the existing workload convention documented in `docs/openbao.md` and
|
||||
`docs/argocd-gitops.md`:
|
||||
Use the workload credential convention documented in `docs/openbao.md`:
|
||||
|
||||
```text
|
||||
platform/workloads/<namespace>/<service-account>/<secret-name>
|
||||
platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>
|
||||
```
|
||||
|
||||
For this lane, the proposed non-secret contract is:
|
||||
@@ -64,9 +63,11 @@ For this lane, the proposed non-secret contract is:
|
||||
| Item | Proposed value |
|
||||
| --- | --- |
|
||||
| KV mount | `platform` |
|
||||
| CLI path | `platform/workloads/whynot-design/whynot-design/npm-publish` |
|
||||
| KV-v2 policy data path | `platform/data/workloads/whynot-design/whynot-design/npm-publish` |
|
||||
| KV-v2 policy metadata path | `platform/metadata/workloads/whynot-design/whynot-design/npm-publish` |
|
||||
| Tenant/org | `coulomb` |
|
||||
| Workload/project | `whynot-design` |
|
||||
| CLI path | `platform/workloads/coulomb/whynot-design/npm-publish` |
|
||||
| KV-v2 policy data path | `platform/data/workloads/coulomb/whynot-design/npm-publish` |
|
||||
| KV-v2 policy metadata path | `platform/metadata/workloads/coulomb/whynot-design/npm-publish` |
|
||||
| Secret field | `NPM_AUTH_TOKEN` |
|
||||
| OpenBao read policy | `workload-kv-read-whynot-design-npm-publish` |
|
||||
| OIDC auth mount | `netkingdom` unless KeyCape compatibility requires `keycape` |
|
||||
@@ -78,7 +79,7 @@ The expected caller-facing read shape is:
|
||||
|
||||
```bash
|
||||
bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read
|
||||
bao kv get -field=NPM_AUTH_TOKEN platform/workloads/whynot-design/whynot-design/npm-publish
|
||||
bao kv get -field=NPM_AUTH_TOKEN platform/workloads/coulomb/whynot-design/npm-publish
|
||||
```
|
||||
|
||||
The command shape is illustrative only. Verification must avoid printing the
|
||||
@@ -109,7 +110,7 @@ Acceptance:
|
||||
ops-warden signing smoke.
|
||||
|
||||
**2026-06-27:** Reviewed the unread ops-warden request and existing
|
||||
`platform/workloads/<namespace>/<service-account>/<secret-name>` convention.
|
||||
`platform/workloads/<tenant-or-org>/<workload>/<secret-purpose>` convention.
|
||||
Captured the proposed `whynot-design` npm publish lane above with no secret
|
||||
values.
|
||||
|
||||
@@ -129,7 +130,7 @@ the selected `npm-publish` path.
|
||||
Acceptance:
|
||||
|
||||
- A policy file under `openbao/policies/` defines read access to the exact
|
||||
`platform/data/workloads/whynot-design/whynot-design/npm-publish` path.
|
||||
`platform/data/workloads/coulomb/whynot-design/npm-publish` path.
|
||||
- Metadata/list capabilities are only as broad as needed for the caller and
|
||||
ops-warden fetch UX.
|
||||
- The policy grants no write, delete, patch, sudo, auth, or unrelated workload
|
||||
@@ -140,7 +141,7 @@ Acceptance:
|
||||
**2026-06-27:** Added the concrete policy artifact at
|
||||
`openbao/policies/workload-kv-read-whynot-design-npm-publish.hcl`. It grants
|
||||
only `read` on the exact KV-v2 data and metadata paths for
|
||||
`platform/workloads/whynot-design/whynot-design/npm-publish`; it does not grant
|
||||
`platform/workloads/coulomb/whynot-design/npm-publish`; it does not grant
|
||||
write/delete/list/sudo/auth or sibling workload access. Added
|
||||
`scripts/openbao-apply-workload-kv-lanes.sh`,
|
||||
`make openbao-workload-kv-lanes-dry-run`, and
|
||||
@@ -195,7 +196,7 @@ publish token.
|
||||
Acceptance:
|
||||
|
||||
- The path exists at
|
||||
`platform/workloads/whynot-design/whynot-design/npm-publish`.
|
||||
`platform/workloads/coulomb/whynot-design/npm-publish`.
|
||||
- The field is named exactly `NPM_AUTH_TOKEN`.
|
||||
- The token value is entered through an approved operator/OpenBao path and is
|
||||
never written to Git, State Hub, chat, prompts, shell history, or workplan
|
||||
|
||||
Reference in New Issue
Block a user