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.
| 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.
| 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.
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.
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):
member and load-balancer_member to a user on a project in its own domainDENY cases (the same account must be refused):
admin or manager to anyone (anti-escalation)Unaffected:
Only when all three groups hold is the persona accepted for that release.
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: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.enforce_scope=False (old-style policy). It is a bridge, not the destination.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.