Trilio Share Protectionfor OpenStack File Shares
Guide

Policy & Roles (oslo.policy)

Default roles and policy rules, and how to override them


Overview

Abacá uses oslo.policy to govern every action exposed by the abaca-api service. Each API operation maps to a named policy rule; the conductor enforces those rules server-side using the Keystone token presented by the caller. This page describes the built-in roles Abacá defines, the default rules for every protected operation, and how you override them by supplying a policy.yaml file — following the same pattern used across OpenStack services.


Prerequisites

Before reading or modifying Abacá policy:

  • Abacá control plane deployedabaca-api and abaca-conductor running as pods in the abaca OpenShift namespace on RHOSO 18+.
  • Keystone ≥ 2023.1 with domain-scoped tokens and trusts enabled — Abacá policy evaluation depends on domain-scoped context for Domain-owner rules.
  • oslo.policy ≥ 3.x — installed automatically as a dependency of abaca; no separate installation is needed.
  • Operator access to the abaca-api pod — you need oc exec (or equivalent) to run abaca-manage and to place a policy.yaml file where the API process can read it.
  • Familiarity with OpenStack RBAC concepts — roles, role assignments, scope (project vs. domain vs. system), and how oslo.policy parses rule expressions.

Installation

Policy configuration requires no separate package installation. The default policy ships as code inside the abaca package (the same package that provides abaca-api and abaca-manage). The steps below cover generating the default policy file for reference and placing an override file into the running service.

Step 1 — Generate the default policy for reference

Run abaca-manage inside the abaca-api pod to export the compiled default rules as a commented YAML file:

oc exec -n abaca deployment/abaca-api -- \
  abaca-manage policy generate-default-policy \
  --output-file /tmp/abaca-policy-defaults.yaml

# Copy the file to your workstation
oc cp abaca/$(oc get pod -n abaca -l app=abaca-api -o name | head -1 | cut -d/ -f2):/tmp/abaca-policy-defaults.yaml ./abaca-policy-defaults.yaml

This file is read-only reference material. Do not deploy it unchanged — the service's compiled defaults are already active without any file on disk.

Step 2 — Create your override policy.yaml

Create a file containing only the rules you want to override (not the full set):

# policy.yaml — Abacá policy overrides
# Place only the rules you wish to change.

# Example: restrict on-demand backup creation to users with the
# 'abaca_power_user' role in addition to the default rules.
"backup:create": "role:abaca_power_user or rule:admin_or_owner"

Step 3 — Mount the override file into the API pod

Use a Kubernetes ConfigMap and a volume mount in the abaca-api Deployment manifest (managed via kustomize):

# Create the ConfigMap from your override file
oc create configmap abaca-policy \
  --from-file=policy.yaml=./policy.yaml \
  -n abaca

Then add the following to your kustomize overlay for the abaca-api Deployment:

# kustomization patch excerpt
patches:
  - target:
      kind: Deployment
      name: abaca-api
    patch: |-
      - op: add
        path: /spec/template/spec/volumes/-
        value:
          name: abaca-policy
          configMap:
            name: abaca-policy
      - op: add
        path: /spec/template/spec/containers/0/volumeMounts/-
        value:
          name: abaca-policy
          mountPath: /etc/abaca/policy.yaml
          subPath: policy.yaml

Apply the overlay:

kustomize build deploy/rhoso/overlays/production | oc apply -f -

Step 4 — Point abaca.conf at the policy file

Ensure the [oslo_policy] section of /etc/abaca/abaca.conf references the file (oslo.policy will hot-reload it on change without a pod restart if policy_file is set):

[oslo_policy]
policy_file = /etc/abaca/policy.yaml
policy_dirs =
enforce_scope = true
enforce_new_defaults = true

Step 5 — Verify the policy is loaded

Check the API pod logs for the oslo.policy load event:

oc logs -n abaca deployment/abaca-api | grep -i policy

Expected output includes a line such as:

INFO oslo_policy.policy [-] Loaded policy file: /etc/abaca/policy.yaml

Configuration

Abacá does not expose dedicated [policy] config keys of its own beyond the standard [oslo_policy] block inherited from the oslo.policy library. The settings below are the ones operators most commonly need to tune.

[oslo_policy] section

KeyTypeDefaultPurpose
policy_filestringpolicy.yamlPath (absolute or relative to config_dir) of the operator override file. If the file does not exist the compiled defaults apply.
policy_dirslistpolicy.dAdditional directories scanned for *.yaml policy fragments, merged in lexicographic order. Set to empty to disable.
enforce_scopebooleanfalse (upstream default)When true, oslo.policy rejects requests whose token scope does not match the rule's declared scope type (project / domain / system). Strongly recommended true for production.
enforce_new_defaultsbooleanfalse (upstream default)When true, the service uses the new-style defaults (personas) rather than legacy is_admin defaults. Enable alongside enforce_scope.

Abacá [api] options relevant to policy

KeyTypeDefaultPurpose
noauthbooleanfalseDisables Keystone authentication and all policy enforcement entirely. Development/local only (docker-compose dev stack). Never set true in production.

[DEFAULT] options relevant to service identity

KeyTypeDefaultPurpose
catalog_typestringshare-protectionThe Keystone service type string registered in the catalog. Affects how python-abacaclient discovers the endpoint.
endpoint_typestringpublicURLWhich catalog endpoint the client library prefers (publicURL, internalURL, or adminURL).

[abaca] service-user options

KeyTypeDefaultPurpose
service_user_idstringUUID of the Keystone user Abacá uses for service-to-service calls (Nova, Neutron, Manila, Barbican). Must hold admin or a suitable custom role in the relevant projects.
service_user_namestringHuman-readable name of that user, used in log attribution.

Usage

Roles Abacá defines

Abacá registers two custom Keystone roles during deployment (via deploy/rhoso/ install scripts):

RoleScopeWho holds itWhat it unlocks
abaca_domain_ownerDomain-scopedA designated Domain administratorCreate and manage BackupTargetTemplate objects and register S3 buckets (enroll targets) on behalf of all projects in the Domain.
abaca_adminSystem-scoped or project-scoped (operator)OpenStack operator / service teamRead fleet state, list all jobs and workers across projects, access admin-panel API routes (/v1/admin/...).

Tenants with the standard OpenStack member role in a project can create Policies, request on-demand backups, monitor their own jobs, and initiate restores within that project — no additional role assignment is required.

Default policy rules

Abacá's policy rules follow the standard OpenStack persona pattern. The table below shows each protected operation family, its default rule expression, and its scope.

Operation familyPolicy rule nameDefault expressionRequired scope
List/show backup targetstarget:get, target:listrule:project_member_or_adminProject
Create / update / delete target templatetarget_template:create, target_template:update, target_template:deleterole:abaca_domain_ownerDomain
Enroll a bucket (target registration)target:createrole:abaca_domain_ownerDomain
Create / update / delete a protection policypolicy:create, policy:update, policy:deleterule:project_member_or_adminProject
Request an on-demand backupbackup:createrule:project_member_or_adminProject
List / show backupsbackup:get, backup:listrule:project_member_or_adminProject
Delete a backupbackup:deleterule:project_member_or_adminProject
Request a restorerestore:createrule:project_member_or_adminProject
List / show restoresrestore:get, restore:listrule:project_member_or_adminProject
List / show jobsjob:get, job:listrule:project_member_or_adminProject
Admin — list all jobs (fleet-wide)admin:job:listrole:abaca_adminSystem
Admin — list / manage worker fleetadmin:worker:list, admin:worker:deleterole:abaca_adminSystem
Admin — list all targets (fleet-wide)admin:target:listrole:abaca_adminSystem
Admin — domain registrationadmin:domain:create, admin:domain:deleterole:abaca_adminSystem
Admin — QoS configurationadmin:domain:qosrole:abaca_adminSystem

Checking effective policy

You can use the openstack CLI with the python-abacaclient plugin to verify that a given user can perform an action by inspecting the HTTP response code. There is no dedicated policy check CLI subcommand — rely on the API directly:

# Attempt to list backup targets as a project member — should return 200
openstack share protection target list

# Attempt a domain-owner-only operation as a plain member — expect 403
openstack share protection target template create \
  --name test-template \
  --s3-endpoint https://s3.example.com \
  --bucket-scheme shared

Granting the abaca_domain_owner role

# Assign the domain-owner role to a user in a specific domain
openstack role add \
  --user alice \
  --domain MyDomain \
  abaca_domain_owner

Granting the abaca_admin role

# Assign the admin role system-wide to an operator account
openstack role add \
  --user ops-bot \
  --system all \
  abaca_admin

Examples

Example 1 — Viewing the compiled default policy

Generate the full default policy to understand what rules are in effect before writing any overrides:

oc exec -n abaca deployment/abaca-api -- \
  abaca-manage policy generate-default-policy \
  --output-file /tmp/defaults.yaml

oc cp abaca/$(oc get pod -n abaca -l app=abaca-api -o name | head -1 | cut -d/ -f2):/tmp/defaults.yaml ./abaca-policy-defaults.yaml

cat ./abaca-policy-defaults.yaml

Expected output (abbreviated):

# (generated by abaca-manage policy generate-default-policy)
# Rule: target_template:create
# Scope: domain
# Default: role:abaca_domain_owner
target_template:create: role:abaca_domain_owner

# Rule: backup:create
# Scope: project
# Default: rule:project_member_or_admin
backup:create: rule:project_member_or_admin
# ... (full rule set follows)

Example 2 — Restricting on-demand backup creation to a custom role

Suppose you want only users with a site-specific abaca_power_user role (in addition to operators) to create on-demand backups, while all members can still list and view them.

policy.yaml override file:

# Only power users and admins can trigger on-demand backups.
# Members retain read access (backup:get and backup:list keep their defaults).
"backup:create": "role:abaca_power_user or role:abaca_admin"

Apply it:

oc create configmap abaca-policy \
  --from-file=policy.yaml=./policy.yaml \
  -n abaca --dry-run=client -o yaml | oc apply -f -

Test as an unprivileged member (expect 403 Forbidden):

openstack share protection backup create --share <share-id> --policy <policy-id>
# HTTP 403 — Policy does not allow backup:create

Test as a abaca_power_user member (expect 202 Accepted):

# After assigning the role:
openstack role add --user alice --project MyProject abaca_power_user

openstack share protection backup create --share <share-id> --policy <policy-id>
# HTTP 202 — backup job queued

Example 3 — Enabling scope enforcement

Add to /etc/abaca/abaca.conf (via your kustomize ConfigMap for the abaca-api pod):

[oslo_policy]
enforce_scope = true
enforce_new_defaults = true
policy_file = /etc/abaca/policy.yaml

After rolling out the change, a project-scoped token can no longer satisfy a domain-scoped rule. Attempt an admin operation with a project-scoped token:

openstack --os-auth-type password \
  --os-project-name MyProject \
  share protection target template create \
  --name bad-attempt --s3-endpoint https://s3.example.com --bucket-scheme shared
# HTTP 403 — scope mismatch: domain scope required for target_template:create

Example 4 — Granting a user read-only access to the admin fleet panel

Create a read-only operator role assignment (system-scoped abaca_admin controls all admin routes; if you want a narrower grant, write a custom rule override):

# Full admin (all /v1/admin/ routes)
openstack role add --user fleet-reader --system all abaca_admin

To scope down to list-only, add a rule override:

# policy.yaml
# Allow fleet-reader to list workers and jobs but not modify them.
"admin:worker:list": "role:abaca_admin or role:abaca_fleet_reader"
"admin:job:list":    "role:abaca_admin or role:abaca_fleet_reader"
"admin:worker:delete": "role:abaca_admin"  # explicitly block fleet-reader

Then assign the custom role:

openstack role create abaca_fleet_reader
openstack role add --user fleet-reader --system all abaca_fleet_reader

Troubleshooting

Issue 1 — All API requests return 403 Forbidden after deploying a policy.yaml

Symptom: Every authenticated request to abaca-api returns HTTP 403, including requests from accounts that worked before.

Likely cause: The policy.yaml override file contains a syntax error, an unknown rule reference, or a rule that inadvertently overrides a base rule (e.g., rule:default) to always deny.

Fix:

  1. Check abaca-api pod logs for oslo.policy parse errors:
    oc logs -n abaca deployment/abaca-api | grep -i 'policy\|oslo_policy\|error'
    
  2. Validate YAML syntax locally:
    python3 -c "import yaml; yaml.safe_load(open('policy.yaml'))"
    
  3. If the file is invalid, update the ConfigMap with a corrected version and verify the pod reloads:
    oc create configmap abaca-policy \
      --from-file=policy.yaml=./policy.yaml \
      -n abaca --dry-run=client -o yaml | oc apply -f -
    oc logs -n abaca deployment/abaca-api | grep 'Loaded policy'
    
  4. If you cannot identify the bad rule, temporarily remove the ConfigMap volume mount (reverting to compiled defaults) to restore access, then debug the file offline.

Issue 2 — A abaca_domain_owner user receives 403 when creating a target template

Symptom: A user with the abaca_domain_owner role assigned in a Domain receives HTTP 403 when calling openstack share protection target template create.

Likely cause: The user's token is project-scoped rather than domain-scoped. Domain-owner rules require a domain-scoped token. This is enforced more strictly when enforce_scope = true.

Fix:

  1. Confirm the token scope by inspecting the token:
    openstack token issue
    # Check that 'domain' appears in the output, not just 'project'
    
  2. Re-authenticate with domain scope:
    export OS_AUTH_TYPE=password
    export OS_DOMAIN_NAME=MyDomain
    unset OS_PROJECT_NAME OS_PROJECT_ID
    openstack token issue
    
  3. Retry the target template creation with the domain-scoped token.

Issue 3 — abaca-manage policy generate-default-policy command is not found

Symptom: Running abaca-manage policy generate-default-policy inside the pod produces No such command 'policy' or similar.

Likely cause: The installed version of the abaca package does not yet include the policy subcommand group, or you are running the command outside the correct pod.

Fix:

  1. Confirm you are exec-ing into the abaca-api pod (not the conductor):
    oc exec -n abaca deployment/abaca-api -- abaca-manage --help
    
  2. Verify the package version:
    oc exec -n abaca deployment/abaca-api -- pip show abaca
    
  3. If the subcommand is absent, export the defaults from a local development environment using the same package version, or read the default policy directly from abaca/common/policies/ in the source tree.

Issue 4 — Policy changes have no effect after updating the ConfigMap

Symptom: You updated the abaca-policy ConfigMap but the old policy is still being applied.

Likely cause: oslo.policy caches the policy file. A ConfigMap update propagates to the pod's mounted file within ~60 seconds (kubelet sync), but the running process may not re-read it until the cache expires or the pod restarts.

Fix:

  1. Wait up to 60–90 seconds for kubelet to sync the ConfigMap volume, then test again.
  2. If the file has updated on disk (verify with oc exec) but the behavior has not changed, restart the pod to force an immediate reload:
    oc rollout restart deployment/abaca-api -n abaca
    oc rollout status deployment/abaca-api -n abaca
    
  3. Confirm the policy reloaded:
    oc logs -n abaca deployment/abaca-api | grep 'Loaded policy'
    

Issue 5 — noauth = true was inadvertently left enabled in production

Symptom: The abaca-api accepts requests with no X-Auth-Token header and applies no policy checks. Audit logs show no Keystone token validation events.

Likely cause: The [api] noauth = true setting intended for the local Docker Compose dev stack was carried into the production abaca.conf.

Fix: This is a critical security misconfiguration. Immediately:

  1. Set noauth = false in the [api] section of abaca.conf (via your kustomize ConfigMap for the API pod).
  2. Roll out the change:
    oc rollout restart deployment/abaca-api -n abaca
    oc rollout status deployment/abaca-api -n abaca
    
  3. Audit API access logs for the window during which noauth was enabled and report per your organization's incident-response process.