Skip to content

[DPE-10184] fix mtls certificate for cross-model-relations#266

Open
reneradoi wants to merge 22 commits into
mainfrom
mtls-cross-model-relations
Open

[DPE-10184] fix mtls certificate for cross-model-relations#266
reneradoi wants to merge 22 commits into
mainfrom
mtls-cross-model-relations

Conversation

@reneradoi

@reneradoi reneradoi commented May 27, 2026

Copy link
Copy Markdown

This PR fixes an issue when providing the mTLS certificate in a cross-model relation.

Due to juju/juju#21248 (comment), granting a Juju secret from the requirer side of a cross-model relations fails with sharing consumer secrets across a cross model relation not supported. The proposed workaround from DA264 is to place the mtls-cert into regular relation data instead of a secret, if the relation is a cross-model relation.

The scope of this PR is to fix this issue for data-interfaces v0. The required fixes for v1 will be provided in a separate PR to https://github.com/canonical/data-platform-charmlibs (see canonical/data-platform-charmlibs#16).

Changes:

  • add dependency to cryptography for using Fernet
  • add list CROSS_MODEL_RELATION_CONSUMER_SECRETS (currently only includes mtls-cert
  • ignore keys defined in CROSS_MODEL_RELATION_CONSUMER_SECRETS for requirer-side secrets in cross-model relations
  • add handling for relation-created event in ProviderEventHandlers class: in cross-model relations, generate the encryption key, store it in a secret, grant the secret to the requirer and add the secret id to relation data
  • add logic for cross-model relations in _update_relation_data_without_secrets: read the encryption key from the secret encryption-secret and encrypt keys defined in CROSS_MODEL_RELATION_CONSUMER_SECRETS; in case of failures, values will be left blank
  • add logic for cross-model relations in _fetch_relation_data_without_secrets: read the encryption key from the secret encryption-secret and decrypt keys defined in CROSS_MODEL_RELATION_CONSUMER_SECRETS
  • adjust the relation-changed events in EtcdRequirerEventHandlers and KafkaRequirerEventHandlers classes: resend a previous request if the encryption secret was added to relation data from provider side, to ensure data is sent correctly

Testing:
Functionality was tested manually and with integration test coverage on charmed-etcd (see this draft PR, example CI run here). Integration test coverage for this repo can be added after changes where merged in this etcd PR (because a provider charm with mtls support is needed)

  • add cryptography to deps for all test charms
  • fix the broken s3-app test charm
  • remove check_logs where possible (only if action results are ensured otherwise) to avoid test flakyness

@reneradoi reneradoi force-pushed the mtls-cross-model-relations branch from 291b50e to dfadf62 Compare June 5, 2026 07:39
Comment thread lib/charms/data_platform_libs/v0/data_interfaces.py Outdated
try:
remote_model = relation.remote_model.uuid
except (FileNotFoundError, ModelError, RuntimeError):
# access to remote model added in Juju 3.6.2, fails with 2.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.

What is the error raised in case of Juju 2.9 ?
Maybe we could have a log line for that specific case?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've added a log line.

According to ops, this raises a ModelError. But I've also seen instances of FileNotFoundError and RuntimeError in integration test runs, that's why I added those.


# in cross-model relations, generate an encryption key and share it with the requirer as a secret
event_data = {}
secret_label = f"{self.model.uuid}-{event.relation.id}-encryption-secret"

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.

What is the need for the model uuid in the secret label ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Mostly consistency with another instance of creating a "helper" secret here.

Comment thread tests/v0/integration/application-charm-etcd-client/requirements.txt
Comment on lines -10 to -11
series:
- focal

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.

Isn't this for juju 2.9 purposes?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Well, interesting one: I think this is a mistake (or leftover from the past). Even when deployed on jammy juju container, the container image was always focal, which resulted in issues when using the default Python of the container. It took quite some time to figure out why integration tests started to fail since the last commit and this repo and my PR.

Building for different bases is defined here, which stays untouched.

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.

What's the reason of all this cleanup ?
Where those tests testing nothing?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, these assertions where useless. The actual check happens afterwards, in the assertion of the relation data to be present (or not). Asserting log messages is error prone and should be avoided in general, I believe. Especially if there are random wait times (3s) for a message to be present. In these cases, it caused test flakeyness and CI instability, and as it doesn't bring value, I decided to remove.

@imanenami imanenami 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.

Thanks for the effort, looks good to me 👍

Comment thread lib/charms/data_platform_libs/v0/data_interfaces.py Outdated
Comment thread lib/charms/data_platform_libs/v0/data_interfaces.py Outdated
@reneradoi reneradoi requested a review from Gu1nness June 10, 2026 15:20
LIBPATCH = 59

PYDEPS = ["ops>=2.0.0"]
PYDEPS = ["ops>=2.0.0", "cryptography"]

@dragomirp dragomirp Jun 14, 2026

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 would prefer if cryptography is inline import with a runtime error instead of a hard dependency. It's a pretty big library a lot of products don't necessarily need and latest versions already dropped support for Python versions on some of our supported platforms (focal with 3.8).

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.

4 participants