diff --git a/docs/design-decisions.md b/docs/design-decisions.md index f3ec6aa..ec61b40 100644 --- a/docs/design-decisions.md +++ b/docs/design-decisions.md @@ -1757,6 +1757,28 @@ **Related:** D-064 (origin), D-051 (mechanism), D-050 (closed), scs-0302 posture. +## D-073 -- AMENDMENT (2026-07-06): implementation STAGED (zip rebuilt); live apply PENDING + +- policies/domain-manager-policy.yaml: `identity:list_trusts` added at the modern + keystone default VERBATIM (39 rules now). One documented exception to the overlay's + "no new-style rules" header invariant: the (role:reader and system_scope:all) branch + is provably inert under this cloud's old-style enforcement -- narrows only, kept + verbatim for 2024.2+ reconciliation provenance. Trust-rule siblings left UNCHANGED + (evidence-gated per D-064: code-guarded, and no verified shipped-default strings in + repo evidence to copy). +- policies/overrides.zip rebuilt via python3 zipfile (no zip(1) on the jumphost); + provider-bundle-check item 7 content-compare PASS. +- Validated here: yaml.safe_load (39 string rules), ASCII+LF, tooling compatibility + (tenant-offboard/tenant-acceptance call `trust list` in the admin context only). + NOT validated here: oslo.policy parse (module absent on the jumphost; D-064's parse + ran in the main-chat sandbox -- rerun there if desired) and BEHAVIORAL acceptance. +- LIVE APPLY (gated, operator-present; in the batch-3 window do-doc): stage the zip + under $HOME (snap /tmp limit), `juju attach-resource keystone + policyd-override=/overrides.zip`, wait for `PO:`, then behavioral verify: + tenant-token `openstack trust list` -> 403; admin context -> succeeds; magnum + cluster create/delete (trust machinery) unaffected. Rollback: re-attach the prior + zip from git history (`git show HEAD~:policies/overrides.zip`). + ## D-072 -- AMENDMENT (2026-07-06): upstream bug NOT filed (operator ruling) Operator ruled 2026-07-06: the drafted upstream bug (docs/upstream-bug-draft-dashboard-tls.md) diff --git a/docs/v1-redeploy-changelog.md b/docs/v1-redeploy-changelog.md index 1fc6af1..5b58fd3 100644 --- a/docs/v1-redeploy-changelog.md +++ b/docs/v1-redeploy-changelog.md @@ -2145,3 +2145,18 @@ REVERT: git checkout HEAD~ -- scripts/tenant-onboard.sh tests/tenant-onboard/run-tests.sh docs/handoff-20260705-open-items.md docs/session-ledger.md docs/v1-redeploy-changelog.md Next-free after this push (per scan, keep this line unwrapped): D-074, DOCFIX-093, BUNDLEFIX-012. + +### 2026-07-06 (addendum 24, jumphost stream) -- D-073 implementation staged: list_trusts hardening in the policy zip + +- policies/domain-manager-policy.yaml: identity:list_trusts at the modern keystone + default verbatim (38 -> 39 rules); full provenance + the documented one-off + exception to the no-new-style invariant (branch inert under old-style enforcement, + narrows only) + tooling-compat note in the file itself. +- policies/overrides.zip rebuilt (python3 zipfile -- no zip(1) on jumphost); + provider-bundle-check content-compare PASS; yaml/ASCII/LF validated. +- NOT done here (deferred to the gated live window): oslo.policy parse (module absent + on jumphost) and behavioral acceptance (tenant 403 / admin ok / magnum unaffected). +- See the D-073 amendment in design-decisions for the gated live-apply block. +REVERT: git checkout HEAD~ -- policies/domain-manager-policy.yaml policies/overrides.zip docs/design-decisions.md docs/v1-redeploy-changelog.md + +Next-free after this push (per scan, keep this line unwrapped): D-074, DOCFIX-093, BUNDLEFIX-012. diff --git a/policies/domain-manager-policy.yaml b/policies/domain-manager-policy.yaml index 796995b..e8bfb77 100644 --- a/policies/domain-manager-policy.yaml +++ b/policies/domain-manager-policy.yaml @@ -117,3 +117,22 @@ "identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:cloud_admin or rule:admin_and_matching_target_group_domain_id" "identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:cloud_admin or rule:admin_and_matching_target_group_domain_id" +# --- Trusts: enumeration hardening (D-073, adopted 2026-07-06) --- +# Live default was "" (empty): ANY authenticated user could enumerate ALL trusts +# cloud-wide (trustor/trustee/project relationships) -- an info disclosure on a +# multi-tenant cloud. Tightened to the modern keystone default VERBATIM (string as +# recorded in the D-064 create_trust RCA evidence). This is the ONE deliberate +# exception to the header's "no new-style rules" invariant: the +# (role:reader and system_scope:all) branch can never evaluate TRUE under this +# cloud's OLD-STYLE enforcement (enforce_scope forced false; no system-scoped +# tokens issued), so the effective behavior HERE is exactly rule:admin_required -- +# the dead branch can only narrow, never widen, and keeping the upstream string +# verbatim preserves provenance for the 2024.2+ reconciliation. +# Tooling compatibility (checked 2026-07-06): tenant-offboard.sh and +# tenant-acceptance.sh call `trust list` in the ADMIN context only -> unaffected. +# Siblings get_trust / delete_trust / list_roles_for_trust / get_role_for_trust +# remain UNCHANGED per D-064's evidence-gated scope: live "" but code-guarded in +# keystone (_trustor_trustee_only) -> functional, and no verified shipped-default +# strings exist in repo evidence to copy. [D-073] +"identity:list_trusts": "rule:admin_required or (role:reader and system_scope:all)" + diff --git a/policies/overrides.zip b/policies/overrides.zip index 93b6070..7afb42f 100644 --- a/policies/overrides.zip +++ b/policies/overrides.zip Binary files differ