Trilio Share Protectionfor OpenStack File Shares
Guide

Keystone Registration — Service, Endpoints, Account, Roles

Register the service and its catalog endpoints, create the service account, and assign roles


Overview

This page walks you through registering Trilio Share Protection (Abacá) as a first-class OpenStack service: creating the Keystone service entry and catalog endpoints, provisioning the service account and worker project, and assigning the roles that the control plane and domain owners need. Without these steps the API is unreachable from the service catalog, no token validation is possible, and domain owners cannot create backup targets. Complete this page before running the database, deployment, or any other installation step.


Prerequisites

Before you begin, ensure the following are in place:

  • RHOSO 18+ with OpenShift 4.14+ hosting the control plane
  • keystone-operator running and reconciling CRs in the control-plane namespace (verify with oc -n <cp-namespace> get keystoneservice)
  • cert-manager installed in the cluster (the script creates an Issuer and Certificate in the abaca namespace)
  • oc CLI authenticated to the OpenShift cluster with cluster-admin or equivalent rights
  • openstack CLI (python-abacaclient plugin optional at this stage) authenticated with cloud-admin credentials and the admin openrc sourced
  • The control-plane namespace name (ABACA_CP_NAMESPACE), Abacá namespace (ABACA_NAMESPACE), and desired service name/type variables exported or set in deploy/rhoso/lib.sh
  • Network access from the OpenShift cluster to the Keystone API

Note: The Kolla-Ansible reference environment (deploy/kolla/) follows the same logical steps but uses plain openstack CLI commands instead of Kubernetes CRs. The steps below document the authoritative RHOSO path. Refer to deploy/kolla/01-identity.sh and deploy/kolla/02-catalog.sh only for development or reference clusters.


Installation

The two scripts deploy/rhoso/01-identity.sh and deploy/rhoso/02-catalog.sh are the authoritative installers. Run them in order from the repository root after sourcing your admin credentials.

Step 1 — Source your environment

# Source the cluster admin openrc (or equivalent clouds.yaml entry)
source /path/to/admin-openrc.sh

# Verify you can reach Keystone
openstack token issue

Step 2 — Run the identity script

This script is idempotent. Re-running it does not rotate the service password unless you export ABACA_ROTATE=1.

bash deploy/rhoso/01-identity.sh

The script performs the following actions in order:

  1. Creates the abaca namespace in OpenShift (if absent) and labels it.
  2. Bootstraps Abacá's own CA chain using cert-manager — a self-signed root Issuer, a CA Certificate, and a subordinate Issuer (abaca-ca). This CA signs Abacá's own serving certificates; outbound trust to Keystone and other services comes from the platform's public CA bundle merged into the trust bundle.
  3. Generates and stores passwords — the service account password in the abaca-secret Kubernetes Secret and the database password in abaca-db-secret. Passwords are generated once; re-running preserves them.
  4. Applies a KeystoneService CR in the control-plane namespace. The keystone-operator reads this CR to create the Keystone service user and the service catalog record simultaneously. This replaces the manual openstack user create + openstack service create sequence used in Kolla environments.
  5. Waits up to 180 seconds for the KeystoneService CR to reach Ready=True.
  6. Creates the worker VM project (default name controlled by ABACA_WORKER_PROJECT) where conductor-launched worker VMs run.
  7. Assigns rolesservice and admin on the shared service project, and admin on the worker project — to the Abacá service user.
  8. Creates the abaca_domain_owner Keystone role (cluster-global, idempotent) and optionally grants it to the bootstrap admin on the bootstrap domain when ABACA_BOOTSTRAP_DOMAIN is set.
  9. Records the domain-to-service-project mapping in a ConfigMap (abaca-domain-map) for consumption by the 07-deploy.sh script's abaca-manage domain_register call.
# Successful output ends with:
OK.

If the KeystoneService does not become Ready within 180 seconds, inspect the CR status:

oc -n <cp-namespace> get keystoneservice abaca -o jsonpath='{.status.conditions}'

Step 3 — Register catalog endpoints

bash deploy/rhoso/02-catalog.sh

This script applies a KeystoneEndpoint CR that tells the keystone-operator to register Abacá's URLs in the service catalog. RHOSO registers two interfaces onlypublic (an OpenShift Route at the ingress) and internal (the in-cluster Service). There is no admin interface on RHOSO 18; this matches the pattern used by other services such as Barbican and Cinder on this control plane.

URL defaults are computed from the cluster ingress by abaca::public_url and abaca::internal_url helper functions in lib.sh. Override them before running the script:

export ABACA_PUBLIC_URL="https://abaca.apps.cluster.example.com/v1"
export ABACA_INTERNAL_URL="http://abaca-api.abaca.svc.cluster.local:9797/v1"
bash deploy/rhoso/02-catalog.sh

The script waits up to 180 seconds for KeystoneEndpoint/abaca-api to reach Ready=True, then prints the registered endpoints:

# Example output:
+----------+------------------------------------------------------+---------+
| Interface| URL                                                  | Enabled |
+----------+------------------------------------------------------+---------+
| public   | https://abaca.apps.cluster.example.com/v1            | True    |
| internal | http://abaca-api.abaca.svc.cluster.local:9797/v1     | True    |
+----------+------------------------------------------------------+---------+
OK.

Step 4 — Verify registration

# Confirm the service appears in the catalog
openstack service list --long | grep abaca

# Confirm both endpoints are registered
openstack endpoint list --service abaca

# Confirm the service user exists
openstack user show abaca

# Confirm the worker project exists
openstack project show abaca   # or your ABACA_WORKER_PROJECT value

# Confirm the domain owner role exists
openstack role show abaca_domain_owner

Step 5 — Grant domain owner access (per domain)

The abaca_domain_owner role is created globally but the grant is a per-site decision. After you know which user should own backup targets for a given domain, assign the role with a domain-scoped grant:

openstack role add \
  --user <username> \
  --user-domain <domain-name> \
  --domain <domain-name> \
  abaca_domain_owner

Without at least one holder of abaca_domain_owner in a domain, no backup target template can be created and all POST /v1/targets/templates requests for that domain will return 403.


Configuration

Keystone registration affects several [abaca] and [DEFAULT] configuration options in the Abacá INI-style .conf file (managed by oslo.config). Set these in the file consumed by both abaca-api and abaca-conductor pods.

[abaca] section

OptionTypeDefaultPurpose
service_user_idstring(none)The Keystone user ID of the Abacá service account. Set this to the ID shown by openstack user show abaca -f value -c id. Takes precedence over service_user_name when both are set.
service_user_namestring(none)The Keystone user name of the service account (abaca in standard deployments). Used when service_user_id is not set.
worker_project_idstring(none)The Keystone project ID of the worker VM tenant. Set to the ID of the project created in Step 2 above. Takes precedence over worker_project_name.
worker_project_namestring(none)The Keystone project name for worker VMs (e.g. abaca). Used as a fallback when worker_project_id is not set. For multi-domain deployments, prefer the ID form to avoid ambiguity.

Important: worker_project_id (or worker_project_name) acts as a single-domain bootstrap fallback. In a multi-domain deployment each domain has an explicit row in the domain_service_projects registry written by abaca-manage domain_register. If that row is missing, the API falls back to this option — and the dashboard will report is_service_project: false everywhere, hiding the Register Bucket button.

[DEFAULT] section (catalog discovery)

OptionTypeDefaultValid valuesPurpose
catalog_typestringshare-protection(free string)The service type used when looking up Abacá's own endpoint from the Keystone catalog. Must match the serviceType field in the KeystoneService CR.
endpoint_typestringpublicURLpublicURL, internalURL, adminURLWhich catalog interface the client libraries use when constructing requests to Abacá. Use internalURL for operator tooling running inside the cluster.

[api] section (service binding)

OptionTypeDefaultPurpose
bind_hoststring0.0.0.0Address the API process listens on.
bind_portinteger9797Port the API process listens on. The internal catalog URL should match this port.
noauthbooleanfalseDisable Keystone token validation. Never set true in production. Intended only for the local Docker Compose dev stack.

Annotated sample configuration snippet

[DEFAULT]
# Must match the serviceType in the KeystoneService CR
catalog_type = share-protection

# Use internalURL for pod-to-pod traffic; publicURL for operator CLI
endpoint_type = internalURL

[abaca]
# Resolved at install time: openstack user show abaca -f value -c id
service_user_id = <keystone-user-uuid>

# Resolved at install time: openstack project show abaca -f value -c id
worker_project_id = <keystone-project-uuid>

[api]
bind_host = 0.0.0.0
bind_port = 9797
# noauth must remain false in all non-dev deployments
noauth = false

Usage

Once registration is complete you interact with Abacá's identity surface in three ways: through the OpenStack CLI plugin, through the REST API, and through the Python client library.

Verifying the catalog from the CLI

Use the openstack share protection subcommands (provided by the python-abacaclient package) to confirm the service is reachable through the catalog:

# List all registered backup targets (proves catalog discovery and auth work)
openstack share protection target list

# Show the API service entry
openstack catalog show abaca

Obtaining a domain-scoped token

Domain-scoped tokens are required for operations that belong to a Keystone Domain (creating target templates, registering buckets, running abaca-manage domain_register). Request one with:

openstack token issue \
  --os-auth-url "$OS_AUTH_URL" \
  --os-username "$OS_USERNAME" \
  --os-user-domain-name "$OS_USER_DOMAIN_NAME" \
  --os-domain-name "<your-domain>" \
  --os-password "$OS_PASSWORD"

Pass the resulting token as X-Auth-Token in REST API calls that target domain-scoped resources.

Granting abaca_domain_owner to additional users

This is the most common post-install identity task. Whenever a new domain is onboarded or ownership changes:

# Grant the role
openstack role add \
  --user <username> \
  --user-domain <domain-name> \
  --domain <domain-name> \
  abaca_domain_owner

# Verify the grant
openstack role assignment list \
  --role abaca_domain_owner \
  --domain <domain-name> \
  --names

Revoking the role

openstack role remove \
  --user <username> \
  --user-domain <domain-name> \
  --domain <domain-name> \
  abaca_domain_owner

Checking endpoint registration

# Show both registered interfaces
openstack endpoint list --service abaca -c Interface -c URL -c Enabled

# Confirm the KeystoneEndpoint CR is Ready
oc -n <cp-namespace> get keystoneendpoint abaca-api \
  -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'

Registering additional domains (post-install)

Each additional Keystone Domain needs a domain_service_projects row so the conductor knows which project to use for that domain's worker VMs. Use abaca-manage:

abaca-manage domain_register \
  --domain-id <keystone-domain-uuid> \
  --service-project-id <keystone-project-uuid>

Run this for every domain beyond the bootstrap domain. Without it, the domain's projects will see is_service_project: false on all projects and the Register Bucket button will not appear in the dashboard.


Examples

Example 1 — Full RHOSO identity setup (end to end)

Run both scripts in sequence from the repository root:

export ABACA_BOOTSTRAP_DOMAIN=Default
export ABACA_ADMIN_USER=admin

bash deploy/rhoso/01-identity.sh
bash deploy/rhoso/02-catalog.sh

Expected terminal output (abridged):

[abaca] namespace abaca: exists
[abaca] ensuring Abaca's own CA chain
[abaca] trust bundle abaca-trust-bundle published (platform CAs + Abaca's own)
[abaca] applying KeystoneService/abaca in openstack (the keystone-operator only reconciles CRs beside Keystone)
[abaca] waiting for the keystone-operator to reconcile the service user
[abaca] service id: 7f3a1c8e2b4d...
[abaca] project abaca: creating (worker VM tenant)
[abaca] role service on service -> abaca
[abaca] role admin on service -> abaca
[abaca] role admin on abaca -> abaca
[abaca] role abaca_domain_owner (domain-owned targets, ch.17)
[abaca]   granting it to admin on domain Default
[abaca] recording domain map: Default -> abaca
OK.
[abaca] public  : https://abaca.apps.cluster.example.com/v1
[abaca] internal: http://abaca-api.abaca.svc.cluster.local:9797/v1
+----------+------------------------------------------------------+---------+
| Interface| URL                                                  | Enabled |
+----------+------------------------------------------------------+---------+
| public   | https://abaca.apps.cluster.example.com/v1            | True    |
| internal | http://abaca-api.abaca.svc.cluster.local:9797/v1     | True    |
+----------+------------------------------------------------------+---------+
OK.

Example 2 — Confirm the service catalog entry

openstack catalog show abaca

Expected output:

+-----------+------------------------------------------------------+
| Field     | Value                                                |
+-----------+------------------------------------------------------+
| endpoints | public: https://abaca.apps.cluster.example.com/v1   |
|           | internal: http://abaca-api.abaca.svc.cluster.local:9797/v1 |
| id        | 7f3a1c8e2b4d...                                      |
| name      | abaca                                                |
| type      | share-protection                                     |
+-----------+------------------------------------------------------+

Example 3 — Grant abaca_domain_owner to a new domain admin

openstack role add \
  --user alice \
  --user-domain CustomerDomain \
  --domain CustomerDomain \
  abaca_domain_owner

# Verify
openstack role assignment list \
  --role abaca_domain_owner \
  --domain CustomerDomain \
  --names

Expected output:

+--------------------+-------+---------+------------------+--------+-----------+
| Role               | User  | Group   | Domain           | Project| Inherited |
+--------------------+-------+---------+------------------+--------+-----------+
| abaca_domain_owner | alice |         | CustomerDomain   |        | False     |
+--------------------+-------+---------+------------------+--------+-----------+

Example 4 — Register an additional domain after initial deployment

After db_sync has run (step 07 of the full deploy), register a new domain's service project:

# Resolve IDs first
DOMAIN_ID=$(openstack domain show CustomerDomain -f value -c id)
PROJECT_ID=$(openstack project show abaca-customerdomain -f value -c id)

# Register the mapping
abaca-manage domain_register \
  --domain-id "${DOMAIN_ID}" \
  --service-project-id "${PROJECT_ID}"

Expected output:

Registered domain <DOMAIN_ID> -> service project <PROJECT_ID>

Example 5 — Override catalog URLs and re-register endpoints

export ABACA_PUBLIC_URL="https://abaca.apps.newcluster.example.com/v1"
export ABACA_INTERNAL_URL="http://abaca-api.abaca.svc.cluster.local:9797/v1"
bash deploy/rhoso/02-catalog.sh

The script updates the KeystoneEndpoint CR in place; the keystone-operator reconciles and updates the live endpoint objects without requiring a service restart.


Troubleshooting

Issue: KeystoneService does not reach Ready=True

Symptom: deploy/rhoso/01-identity.sh exits with KeystoneService did not become Ready after the 180-second timeout.

Likely causes:

  • The abaca-secret Kubernetes Secret does not exist in the control-plane namespace (the script copies it there, but a permissions error can silently skip that).
  • The keystone-operator is not running or is itself degraded.
  • The AbacaPassword key is missing from the secret.

Fix:

# Inspect the CR status conditions
oc -n <cp-namespace> get keystoneservice abaca \
  -o jsonpath='{.status.conditions}'

# Confirm the secret exists in the control-plane namespace
oc -n <cp-namespace> get secret abaca-secret

# Check keystone-operator logs
oc -n <cp-namespace> logs -l app=keystone-operator --tail=50

If the secret is absent, re-run 01-identity.sh. If the operator is degraded, resolve the operator issue first.


Issue: 403 on every POST /v1/targets/templates

Symptom: Domain owners receive 403 Forbidden when attempting to create a backup target template, even with apparently correct credentials.

Likely causes:

  • The user does not hold the abaca_domain_owner role on the domain (a project-scoped admin role is not sufficient).
  • The token was issued with project scope rather than domain scope.
  • ABACA_BOOTSTRAP_DOMAIN was not set during 01-identity.sh, so the bootstrap grant was skipped.

Fix:

# Verify the role assignment exists at domain scope
openstack role assignment list \
  --role abaca_domain_owner \
  --domain <domain-name> \
  --names

# If missing, grant it
openstack role add \
  --user <username> \
  --user-domain <domain-name> \
  --domain <domain-name> \
  abaca_domain_owner

# Ensure you are requesting a domain-scoped token, not a project-scoped one
openstack token issue --os-domain-name <domain-name>

Issue: Dashboard shows no Register Bucket button anywhere

Symptom: After a successful install, the Horizon Share Protection panel never shows the Register Bucket action, even in the service project.

Likely cause: The domain_service_projects table has no row for the domain. The API falls back to worker_project_id / worker_project_name but reports is_service_project: false on every project, which causes the dashboard to suppress the button.

Fix:

# Check whether a domain map ConfigMap was recorded
oc -n abaca get configmap abaca-domain-map -o yaml

# If missing or if db_sync has not yet applied it, register manually
abaca-manage domain_register \
  --domain-id <keystone-domain-uuid> \
  --service-project-id <keystone-project-uuid>

Re-run after db_sync has completed (step 07 of the full deployment).


Issue: KeystoneEndpoint does not reach Ready=True

Symptom: deploy/rhoso/02-catalog.sh exits with KeystoneEndpoint did not become Ready.

Likely causes:

  • 01-identity.sh has not completed successfully (the endpoint CR depends on the service record created by KeystoneService).
  • The keystone-operator is not watching the control-plane namespace.
  • A malformed URL was passed via ABACA_PUBLIC_URL or ABACA_INTERNAL_URL.

Fix:

# Inspect the CR
oc -n <cp-namespace> get keystoneendpoint abaca-api \
  -o jsonpath='{.status.conditions}'

# Verify the KeystoneService is Ready first
oc -n <cp-namespace> get keystoneservice abaca \
  -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'

# Confirm the service exists in Keystone
openstack service show abaca

Issue: Service account password rotated unexpectedly, control plane cannot authenticate

Symptom: After re-running 01-identity.sh, abaca-api or abaca-conductor pods fail Keystone authentication.

Likely cause: ABACA_ROTATE=1 was set (or the Kolla path was used, which always rotates), generating a new password that was not propagated to the running pod configuration.

Fix: The script is idempotent and does not rotate passwords unless ABACA_ROTATE=1 is explicitly exported. If rotation did occur, update the abaca-secret Secret and restart the pods:

# Confirm the current password in the secret
oc -n abaca get secret abaca-secret -o jsonpath='{.data.AbacaPassword}' | base64 -d

# Restart pods to pick up the updated secret
oc -n abaca rollout restart deployment abaca-api
oc -n abaca rollout restart deployment abaca-conductor