Newer
Older
openstack-caracal-ipv4 / runbooks / appendix-C-identity-rbac.md

Appendix C -- Identity / RBAC reference

Authoritative reference for the cloud's identity model: which keystone roles and personas exist, what each is for, and which accounts should receive which assignments. Governed by D-051 (SCS Domain Manager persona) as reconciled by D-064 (scs-0302 alignment + create-op templating fix).

The persona is delivered by a keystone policy override (policies/domain-manager-policy.yaml) attached as a policyd-override resource. Provenance: SCS standard scs-0302-w1 (Domain Manager). This is a TRANSITIONAL policy for pre-2024.2 keystone; on any upgrade to 2024.2+ the override MUST be removed in favour of the native domain-manager persona (see "Removal" below).

Do NOT hand-assign roles ad hoc. Provision accounts per the tables below so the model stays auditable and the tenant isolation guarantees hold.


C.1 Role / persona catalog

Role / persona Keystone rule What it is for Typical scope Notes
Admin / admin admin_required (role:Admin); becomes cloud_admin when scoped to the admin domain/project Full cloud authority (as cloud_admin), or domain-scoped admin over a single service domain admin domain + admin project (cloud_admin); or a service domain (e.g. magnum) "Admin" and "admin" are the same role (case-insensitive alias). After D-064 an admin-on-a-domain can create users/projects in THAT domain. NOT given to tenants -- an admin role is not safely domain-confinable; tenants get manager instead.
manager (SCS Domain Manager) is_domain_manager = role:manager, plus the D-051/D-064 override Domain-confined IAM self-service: create/manage users, projects, groups, and role assignments WITHIN the manager's own domain a tenant's domain Requires the policy override attached. Can assign ONLY the roles in is_domain_managed_role (below); cannot grant admin or manager (anti-escalation).
member standard project role Operate project resources (compute, network, volumes, images) a project The baseline tenant working role.
load-balancer_member Octavia project role Create / manage Octavia load balancers a project Required for tenant LBs and for Magnum (the cluster apiserver LB). Must be held by the Magnum trustor on capi-mgmt (D-039).
reader standard read role Read-only visibility project or domain Optional. Part of the Magnum trustor role set on capi-mgmt (D-039).

Manager-assignable roles (is_domain_managed_role): member and load-balancer_member only. This is the anti-escalation boundary -- a compromised or careless domain manager cannot mint an admin or another manager, and cannot reach outside its own domain.


C.2 Account -> role assignment

Account Role(s) Scope Why / reference
admin (operator super-admin) Admin admin domain + admin project (= cloud_admin) Cloud operator; full authority. Bootstrap identity.
admin (as Magnum trustor) member + load-balancer_member + reader capi-mgmt project So the app-cred Magnum mints per cluster carries Octavia authority for the apiserver LB (D-039). These are the frozen trustor roles delegated into each cluster trust.
magnum_domain_admin Admin magnum domain Magnum trustee domain admin; creates the per-cluster trustee USER at cluster-create (D-046; Magnum docs). Works via the D-064 create-op fix -- no extra grant needed. Recreated by the domain-setup charm action after every teardown/redeploy (D-046).
-domain-admin manager the tenant's domain SCS Domain Manager persona (D-051/D-064). Operator provisions the domain + this one account; the tenant self-services users, projects, and member/load-balancer_member grants from there.
human users member (+ load-balancer_member if they use LBs or Magnum) the tenant's project(s) Created and assigned by the tenant's own domain-manager via Horizon/CLI. Operator is not in the loop.
-ci / service accounts member + load-balancer_member the tenant's project Backing identity for the application credential that CI/automation authenticates with. load-balancer_member so tenant CI can drive Magnum/LBs.
per-cluster trustee (delegated via trust -- not a direct grant) -- Magnum mints this at cluster-create and deletes it at cluster-delete. It carries the trustor's frozen roles through the trust (D-039). Never assign roles to it by hand.

Provisioning direction: the operator creates a tenant's DOMAIN and its single manager account, then hands off. Everything below the domain (users, projects, member/LB grants) is tenant self-service. This is the whole point of the persona -- it removes the operator from routine tenant IAM while keeping a hard domain boundary.


C.3 Attaching the policy override

Prerequisite: keystone deployed with use-policyd-override=true (already set in the bundle). Note D-050: use-policyd-override=true with NO resource attached is a silent no-op -- the zip must actually be supplied, or the override does nothing while reporting healthy.

Pre-attach re-check on the jumphost (from the repo working copy), then attach:

# 1) validate the file before attaching (YAML + ASCII + connector lint)
python3 -c 'import yaml,sys; d=yaml.safe_load(open("policies/domain-manager-policy.yaml")); print("YAML OK:",len(d),"rules")'
LC_ALL=C grep -nP "[^\x00-\x7F]" policies/domain-manager-policy.yaml && { echo "NON-ASCII -- STOP"; exit 1; } || echo "ASCII clean"
grep -nE "\)\s+(rule:|role:|token|project_id|domain_id|user_id|None:)" policies/domain-manager-policy.yaml && { echo "MALFORMED connector -- STOP"; exit 1; } || echo "connector lint clean"

# 2) package and attach (the zip's top-level file name is what keystone reads)
cd policies && zip -j /tmp/overrides.zip domain-manager-policy.yaml && cd -
juju attach-resource -m openstack keystone policyd-override=/tmp/overrides.zip

Gate: juju status -m openstack keystone must move from PO (broken) to PO: and settle active/idle, with no other charm disturbed. If the charm rejects the file it stays PO (broken).

Rollback (immediate): juju config -m openstack keystone use-policyd-override=false (the override stops applying; keystone reverts to shipped defaults on the next hook).

The charm validates YAML only. It does NOT parse the oslo.policy rule grammar, so a syntactically malformed rule can pass validation and silently no-op. Always run the oslo.policy parse in the sandbox before delivering a change to this file.


C.4 Tenant self-service validation (G3)

Run after the override is active. Confirms the persona works AND is properly bounded.

PASS cases (a manager-on-domain account, scoped to its own domain, must succeed):

  • create a user in its own domain
  • create a project in its own domain
  • grant member and load-balancer_member to a user on a project in its own domain

DENY cases (the same account must be refused):

  • grant admin or manager to anyone (anti-escalation)
  • create/read/modify anything in a DIFFERENT domain (cross-domain isolation)

Unaffected:

  • cloud_admin (the operator admin) retains full authority everywhere

Only when all three groups hold is the persona accepted for that release.


C.5 Known limitations (carried from scs-0302)

  • CORRECTION (verified live 2026-07-01): on THIS deployment a domain manager's domain list returns ONLY its own domain -- keystone scope-filters the result even though the D-064 policy authorizes list_domains for a manager. So the cloud-wide domain-name enumeration described in the SCS worst-case does NOT manifest here; isolation is tighter than the standard warns. Role names (list_roles) may still be broadly visible (the persona needs to resolve role names); this remains names-only and confers no resource access. The original SCS caveat is retained below as version/config-dependent, NOT asserted as this cloud's behavior:
  • [SCS worst-case, not observed here] A domain manager could enumerate ALL domain names/ids (list_domains) and ALL role names (list_roles) cloud-wide. This is names/ids only -- no access to other domains' resources -- and is required for the manager to resolve domains/roles by name. It is inherent to the pre-2024.2 transitional policy; upstream RBAC-scoping of domain listing is a pending fix.
  • The persona relies on enforce_scope=False (old-style policy). It is a bridge, not the destination.

C.6 Removal (on upgrade to keystone 2024.2+)

2024.2 ships a native domain-manager persona and secure-RBAC scope enforcement. On that upgrade: detach the policyd-override resource (or set use-policyd-override=false), adopt the native persona, and retire this file. Leaving the old-style override in place on a secure-RBAC keystone is unsupported and will conflict. Tracked by D-051/D-064.