Skip to content

[cifmw_cephadm] Allow legacy CephX while daemons use aes256k - #4130

Open
rebtoor wants to merge 1 commit into
openstack-k8s-operators:mainfrom
rebtoor:fix-ceph-v20-client-openstack-auth
Open

[cifmw_cephadm] Allow legacy CephX while daemons use aes256k#4130
rebtoor wants to merge 1 commit into
openstack-k8s-operators:mainfrom
rebtoor:fix-ceph-v20-client-openstack-auth

Conversation

@rebtoor

@rebtoor rebtoor commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Ceph 20.2.4 (CVE-2025-30156) can fail the CephX handshake for OpenStack Glance, Cinder, and Manila. Those Antelope service images still ship librados that only understands key type aes, while Tentacle daemons may use aes256k.

This is a fresh cephadm cluster every CI run, so the CVE upgrade path is:

  1. Keep auth_allowed_ciphers=aes,aes256k so daemons can use the new type and legacy aes clients can still authenticate.
  2. Do not set auth_preferred_cipher. New keys would otherwise default to aes256k before OpenStack images understand that type.
  3. Mint client.openstack as type aes until Glance/Cinder/Manila images ship librados that understands aes256k.
  4. Keep the RBD vs CephFS cap split (profile rbd on RBD pools, allow rw on CephFS pools, plus mon: allow r). That is a separate Manila/RBD fix, not the errno 5 connect path.

HCI scenario hci_ceph_backends.yml sets the allow-list and cifmw_ceph_key_cipher: aes. The cifmw_cephadm role does not set auth_preferred_cipher.

@rebtoor
rebtoor requested review from fmount and fultonj August 20, 2026 20:56
@openshift-ci

openshift-ci Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign evallesp for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix Ceph v20+ client.openstack cephx auth for HCI (aes256k + correct caps)

🐞 Bug fix ⚙️ Configuration changes 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Default client.openstack cephx keys to aes256k on Ceph Tentacle/v20+.
• Generate complete cephx caps for mixed RBD/CephFS pools (incl. mon allow r).
• Add role/scenario knobs to set auth_preferred_cipher and align HCI defaults.
Diagram

graph TD
  S["HCI scenario vars"] --> P["ceph.yml hook"] --> K["Generate client.openstack key"] --> C[("Ceph cluster")]
  P --> A["Compute pool-specific caps"] --> C
  S --> R["cifmw_cephadm role"] --> M["Set mon auth_preferred_cipher"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Rely solely on Ceph auth_allowed_ciphers (keep aes keys)
  • ➕ Avoids regenerating client keys and potential interoperability concerns
  • ➕ Keeps legacy clients working without changing key material
  • ➖ Does not address Tentacle/v20 rejecting legacy aes keys in greenfield scenarios
  • ➖ Still requires correct caps; permission errors can persist
2. Generate client.openstack via ceph auth get-or-create (CLI) instead of cephx_key
  • ➕ Uses Ceph-native tooling; aligns with upstream expectations for key generation
  • ➕ May reduce differences across Ceph versions if CLI handles defaults
  • ➖ Harder to keep idempotent and testable in Ansible without careful parsing
  • ➖ Still needs explicit cipher selection and per-backend caps logic
3. Model caps per backend role (Glance/Manila) rather than per pool application
  • ➕ More explicit mapping of permissions to consumers (easier to reason about least privilege)
  • ➕ Allows tighter CephFS-specific grants (e.g., Manila-only)
  • ➖ Requires more inputs/coordination between OpenStack service config and Ceph pool layout
  • ➖ Higher maintenance overhead for scenarios with varying backends

Recommendation: The PR’s approach is the best pragmatic fix for HCI: default to aes256k on Tentacle/v20+, explicitly set auth_preferred_cipher, and correct cephx caps by distinguishing RBD vs CephFS pools (including mon allow r). This directly targets the observed permission failures with minimal new surface area while keeping overrides available for non-HCI or legacy deployments.

Files changed (5) +66 / -6

Enhancement (1) +10 / -0
cephadm_config_set.ymlSet mon auth_preferred_cipher during cephadm configuration +10/-0

Set mon auth_preferred_cipher during cephadm configuration

• Adds an optional task that runs 'ceph mon set auth_preferred_cipher <value>' when cifmw_cephadm_auth_preferred_cipher is non-empty, aligning monitor auth preferences with generated client keys.

roles/cifmw_cephadm/tasks/cephadm_config_set.yml

Bug fix (1) +40 / -5
ceph.ymlDefault v20+ client key cipher to aes256k and fix cephx caps +40/-5

Default v20+ client key cipher to aes256k and fix cephx caps

• Adds logic to default the cephx key cipher to aes256k for Tentacle/v20+ clusters while preserving aes for older releases. Updates client.openstack caps to include 'mon: allow r' and computes OSD caps separately for RBD pools (profile rbd) and CephFS pools (allow rw), preventing permission denied for mixed backends.

hooks/playbooks/ceph.yml

Documentation (1) +11 / -1
README.mdDocument new auth_preferred_cipher and v20 key cipher guidance +11/-1

Document new auth_preferred_cipher and v20 key cipher guidance

• Documents the new cifmw_cephadm_auth_preferred_cipher variable and clarifies when to use aes256k for Tentacle/v20+. Updates the example client.openstack caps to include 'mon: allow r, profile rbd'.

roles/cifmw_cephadm/README.md

Other (2) +5 / -0
main.ymlAdd default for cifmw_cephadm_auth_preferred_cipher +1/-0

Add default for cifmw_cephadm_auth_preferred_cipher

• Introduces cifmw_cephadm_auth_preferred_cipher with an empty default so role behavior is opt-in unless scenarios set it explicitly.

roles/cifmw_cephadm/defaults/main.yml

hci_ceph_backends.ymlEnable Tentacle/v20 auth cipher settings for HCI scenario +4/-0

Enable Tentacle/v20 auth cipher settings for HCI scenario

• Sets cifmw_ceph_key_cipher to aes256k and configures cifmw_cephadm_auth_allowed_ciphers/auth_preferred_cipher to include and prefer aes256k for Tentacle/v20+ HCI deployments.

scenarios/centos-9/hci_ceph_backends.yml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Underscored vars violate naming 📘 Rule violation ⚙ Maintainability
Description
New variables _cifmw_ceph_key_cipher_default and _cifmw_cephadm_* do not match the required
^cifmw_[a-z_][a-z0-9_]*$ pattern because they start with _. This can break variable naming
compliance/ansible-lint expectations and makes variables inconsistent across the collection.
Code

hooks/playbooks/ceph.yml[377]

+        _cifmw_ceph_key_cipher_default: >-
Evidence
PR Compliance ID 1 requires variables to start with cifmw_ and match the given regex. The changed
playbook introduces several new variables prefixed with _cifmw_..., which fails the stated pattern
because they do not start with cifmw_.

AGENTS.md: Ansible Role Variables Must Follow cifmw_ Naming Pattern
hooks/playbooks/ceph.yml[375-428]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New variables were introduced with a leading underscore (e.g., `_cifmw_ceph_key_cipher_default`, `_cifmw_cephadm_rbd_pools`), which violates the required variable naming regex `^cifmw_[a-z_][a-z0-9_]*$`.

## Issue Context
The repository enforces a collection-scoped `cifmw_...` naming convention for Ansible variables.

## Fix Focus Areas
- hooks/playbooks/ceph.yml[375-429]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. cephx_key missing FQCN 📘 Rule violation ⚙ Maintainability
Description
The modified task still calls the module as cephx_key: instead of a fully-qualified collection
name (e.g., cifmw.general.cephx_key:). This can fail ansible-lint FQCN rules and reduces clarity
about the module source.
Code

hooks/playbooks/ceph.yml[387]

+        cipher: "{{ cifmw_ceph_key_cipher | default(_cifmw_ceph_key_cipher_default) }}"
Evidence
PR Compliance ID 2 requires fully-qualified module names. In the updated Generate a cephx key
task, the module invocation remains cephx_key: (short name) while the PR modifies the task
arguments, making this non-FQCN usage part of the touched code.

AGENTS.md: Use Fully-Qualified Collection Names (FQCN) for All Ansible Module Calls
hooks/playbooks/ceph.yml[385-388]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A task uses the short module name `cephx_key:` rather than an FQCN, violating the FQCN requirement.

## Issue Context
`cephx_key` is provided by this collection (see `plugins/modules/cephx_key.py`), so the call should be fully qualified (e.g., `cifmw.general.cephx_key:`).

## Fix Focus Areas
- hooks/playbooks/ceph.yml[385-389]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unquoted cipher command arg 🐞 Bug ☼ Reliability
Description
cephadm_config_set.yml passes cifmw_cephadm_auth_preferred_cipher into a free-form
ansible.builtin.command without quoting, so any whitespace or unexpected tokens in the value will
be split into multiple argv entries and can break ceph mon set auth_preferred_cipher or alter the
effective arguments.
Code

roles/cifmw_cephadm/tasks/cephadm_config_set.yml[R70-72]

+  ansible.builtin.command: |
+    {{ cifmw_cephadm_ceph_cli }} mon set auth_preferred_cipher \
+    {{ cifmw_cephadm_auth_preferred_cipher }}
Evidence
The newly-added task constructs the ceph command using a free-form command: | string and appends
the preferred cipher variable unquoted; Ansible splits free-form commands into argv tokens, so
whitespace in that variable becomes additional argv elements. The ceph CLI base itself is a long,
space-separated string, confirming this execution style relies on tokenization.

roles/cifmw_cephadm/tasks/cephadm_config_set.yml[45-73]
roles/cifmw_cephadm/tasks/ceph_cli.yml[17-45]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ansible.builtin.command` (free-form) is tokenized into argv; interpolating `{{ cifmw_cephadm_auth_preferred_cipher }}` without quoting means values containing whitespace (or accidental extra tokens) are split into multiple arguments, which can make the ceph CLI invocation fail or behave unexpectedly.

### Issue Context
`cifmw_cephadm_ceph_cli` is itself a long, space-delimited CLI string, so these tasks already rely on Ansible's tokenization. The safest minimal fix is to ensure the *variable* is passed as a single token by applying Jinja `| quote`.

### Fix Focus Areas
- roles/cifmw_cephadm/tasks/cephadm_config_set.yml[65-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can copy the agent prompt from any finding and feed it to your IDE agent

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread hooks/playbooks/ceph.yml Outdated

- name: Select cephx cipher default for Ceph release
ansible.builtin.set_fact:
_cifmw_ceph_key_cipher_default: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Underscored vars violate naming 📘 Rule violation ⚙ Maintainability

New variables _cifmw_ceph_key_cipher_default and _cifmw_cephadm_* do not match the required
^cifmw_[a-z_][a-z0-9_]*$ pattern because they start with _. This can break variable naming
compliance/ansible-lint expectations and makes variables inconsistent across the collection.
Agent Prompt
## Issue description
New variables were introduced with a leading underscore (e.g., `_cifmw_ceph_key_cipher_default`, `_cifmw_cephadm_rbd_pools`), which violates the required variable naming regex `^cifmw_[a-z_][a-z0-9_]*$`.

## Issue Context
The repository enforces a collection-scoped `cifmw_...` naming convention for Ansible variables.

## Fix Focus Areas
- hooks/playbooks/ceph.yml[375-429]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread hooks/playbooks/ceph.yml Outdated
- name: Generate a cephx key
cephx_key:
cipher: "{{ cifmw_ceph_key_cipher | default('aes') }}"
cipher: "{{ cifmw_ceph_key_cipher | default(_cifmw_ceph_key_cipher_default) }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. cephx_key missing fqcn 📘 Rule violation ⚙ Maintainability

The modified task still calls the module as cephx_key: instead of a fully-qualified collection
name (e.g., cifmw.general.cephx_key:). This can fail ansible-lint FQCN rules and reduces clarity
about the module source.
Agent Prompt
## Issue description
A task uses the short module name `cephx_key:` rather than an FQCN, violating the FQCN requirement.

## Issue Context
`cephx_key` is provided by this collection (see `plugins/modules/cephx_key.py`), so the call should be fully qualified (e.g., `cifmw.general.cephx_key:`).

## Fix Focus Areas
- hooks/playbooks/ceph.yml[385-389]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +70 to +72
ansible.builtin.command: |
{{ cifmw_cephadm_ceph_cli }} mon set auth_preferred_cipher \
{{ cifmw_cephadm_auth_preferred_cipher }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Unquoted cipher command arg 🐞 Bug ☼ Reliability

cephadm_config_set.yml passes cifmw_cephadm_auth_preferred_cipher into a free-form
ansible.builtin.command without quoting, so any whitespace or unexpected tokens in the value will
be split into multiple argv entries and can break ceph mon set auth_preferred_cipher or alter the
effective arguments.
Agent Prompt
### Issue description
`ansible.builtin.command` (free-form) is tokenized into argv; interpolating `{{ cifmw_cephadm_auth_preferred_cipher }}` without quoting means values containing whitespace (or accidental extra tokens) are split into multiple arguments, which can make the ceph CLI invocation fail or behave unexpectedly.

### Issue Context
`cifmw_cephadm_ceph_cli` is itself a long, space-delimited CLI string, so these tasks already rely on Ansible's tokenization. The safest minimal fix is to ensure the *variable* is passed as a single token by applying Jinja `| quote`.

### Fix Focus Areas
- roles/cifmw_cephadm/tasks/cephadm_config_set.yml[65-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/1ff0a8b2a4b942688957ab19810959f5

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 29m 54s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 29m 41s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 42m 53s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 15m 16s
podified-multinode-hci-deployment-crc FAILURE in 1h 55m 20s
✔️ cifmw-pod-zuul-files SUCCESS in 5m 02s
✔️ openstack-k8s-operators-content-provider-bootc SUCCESS in 2h 32m 06s
✔️ cifmw-crc-podified-edpm-baremetal-bootc SUCCESS in 1h 56m 08s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 9m 27s
✔️ cifmw-pod-pre-commit SUCCESS in 10m 17s
✔️ cifmw-molecule-cifmw_cephadm SUCCESS in 5m 26s

@fmount fmount left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to iterate over this patch due to the recent ceph release, but I have a few questions:

  1. should we default to v20:aes256k?
  2. Instead of guessing the release via regex, do we want to keep a mapping of the current status (e.g. {v20:aes256k, v19:aes, etc ...} ) to make easy follow up based on the Ceph backports?
  3. is auth_preferred_cipher something we really need to enforce if we create the client.openstack key with the right cipher that we map to a struct or we guess via regex?
  4. should we update jobs like: https://github.com/openstack-k8s-operators/ci-framework/blob/main/zuul.d/edpm_multinode.yaml#L348 to finally switch to v20:aes256k as main is our 19 base (and 19 will be based on v20+).

I'd like also @fultonj to review the above and we can follow up in case CI is blocked and we need to land this patch asap.

Comment thread hooks/playbooks/ceph.yml
| map(attribute='name')
| list
}}
_cifmw_cephadm_cephfs_pools: >-

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok this worked in the past and probably changed with the new release. To give more context, this applied profile rbd pool=X to every pool, including the CephFS pools (cephfs.cephfs.meta and cephfs.cephfs.data) and while working, it was wrong.
I assume that on older Ceph releases this happened to work because cap validation was more flexible, but Ceph Tentacle (v20) enforces stricter cephx cap validation, causing RADOS permission denied errors when Manila try to access CephFS-backed pools.
Is that the case? @fultonj to double check.

Comment thread hooks/playbooks/ceph.yml Outdated
{{
'aes256k' if (
cifmw_cephadm_version | default('') == 'tentacle'
or (cifmw_cephadm_container_tag | default('v18') is match('^v(20|[2-9][0-9])'))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we swiftch the default here to v20 at this point for the main branch? 19 will be based on v20+ and I'm not sure we currently have upstream jobs based on previous releases.
We might need to patch github.com/openstack-k8s-operators/ci-framework/blob/1256a1cd4c0d52707f14c975f510cca324dabbe2/zuul.d/edpm_multinode.yaml#L347 and make sure it is reconciled we new defaults, but it might allow to simplify the logic for the main branch and start testing from v20 onward.

- cifmw_cephadm_auth_preferred_cipher is defined
- cifmw_cephadm_auth_preferred_cipher | length > 0
ansible.builtin.command: |
{{ cifmw_cephadm_ceph_cli }} mon set auth_preferred_cipher \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware about auth_preferred_cipher and I thought auth_allowed_ciphers [1] was sufficient to give to Ceph a list of allowed ciphers to accept.
What's the difference between these two commands? @fultonj might know this already.

[1] c7a2c0e

Comment thread hooks/playbooks/ceph.yml Outdated
- name: Generate a cephx key
cephx_key:
cipher: "{{ cifmw_ceph_key_cipher | default('aes') }}"
cipher: "{{ cifmw_ceph_key_cipher | default(_cifmw_ceph_key_cipher_default) }}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I recall we added support to customize ciphers via [1] and I'm wondering if we should simply update our defaults based on v20 instead of guessing the ceph tag (that can't be misleading unless you run podman run --rm <container> ceph versions and grep for the release).
So the real question is: should we update the defaults to tentacle (v20) by default and update the cipher to aes256k ? v20:aes256.
I assume that in the next future (weeks?) the assumption provided by this default will no longer be valid and we need to modify this logic again to meet new backports to the ceph clients.

[1] 03fdc8f

Ceph 20.2.4 (CVE-2025-30156) can reject or fail handshake for
OpenStack Glance/Cinder/Manila clients whose librados only
understands type `aes`. Keep `auth_allowed_ciphers=aes,aes256k`,
mint `client.openstack` as `aes`, and do not set
`auth_preferred_cipher`. Split RBD vs CephFS caps with `mon: allow r`.

Assisted-By: Cursor
Signed-off-by: Roberto Alfieri <ralfieri@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rebtoor
rebtoor force-pushed the fix-ceph-v20-client-openstack-auth branch from f93cfaa to c07d8d4 Compare August 24, 2026 21:10
@rebtoor rebtoor changed the title [cifmw_cephadm] Fix Ceph v20 client.openstack auth for HCI scenarios [cifmw_cephadm] Allow legacy CephX while daemons use aes256k Aug 24, 2026
@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/b7142cb3e40e4da1aa5615a5e2f18cdf

✔️ openstack-k8s-operators-content-provider SUCCESS in 2h 26m 21s
✔️ podified-multinode-edpm-deployment-crc SUCCESS in 1h 27m 19s
✔️ cifmw-crc-podified-edpm-baremetal SUCCESS in 1h 38m 07s
✔️ cifmw-crc-podified-edpm-baremetal-minor-update SUCCESS in 2h 12m 57s
podified-multinode-hci-deployment-crc FAILURE in 1h 23m 45s
✔️ cifmw-pod-zuul-files SUCCESS in 5m 35s
✔️ openstack-k8s-operators-content-provider-bootc SUCCESS in 2h 15m 01s
✔️ cifmw-crc-podified-edpm-baremetal-bootc SUCCESS in 1h 42m 38s
✔️ noop SUCCESS in 0s
✔️ cifmw-pod-ansible-test SUCCESS in 10m 56s
✔️ cifmw-pod-pre-commit SUCCESS in 10m 45s
✔️ cifmw-molecule-cifmw_cephadm SUCCESS in 5m 25s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants