Skip to content

fix(server-charm): add pydantic validation to CSFLE master key#1154

Open
rene-oromtz wants to merge 2 commits into
mainfrom
fix/add-pydantic-csfle
Open

fix(server-charm): add pydantic validation to CSFLE master key#1154
rene-oromtz wants to merge 2 commits into
mainfrom
fix/add-pydantic-csfle

Conversation

@rene-oromtz

Copy link
Copy Markdown
Contributor

Description

This add a pydantic validation at charm level so MongoDB CSFLE encryption key is valid base64 with 96-byte length.
When unset, this will also clear the stored CSFLE key in charm.

Resolved issues

NA

Documentation

NA

Web service API changes

Tests

Added unit tests for this behavior

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.04%. Comparing base (4e9a8f1) to head (2d68648).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1154      +/-   ##
==========================================
+ Coverage   78.01%   78.04%   +0.03%     
==========================================
  Files         118      118              
  Lines       12412    12431      +19     
  Branches     1023     1026       +3     
==========================================
+ Hits         9683     9702      +19     
  Misses       2508     2508              
  Partials      221      221              
Flag Coverage Δ *Carryforward flag
agent 75.78% <ø> (ø) Carriedforward from 4e9a8f1
cli 91.85% <ø> (ø) Carriedforward from 4e9a8f1
device 64.18% <ø> (ø) Carriedforward from 4e9a8f1
server 89.09% <100.00%> (+0.09%) ⬆️

*This pull request uses carry forward flags. Click here to find out more.

Components Coverage Δ
Agent 75.78% <ø> (ø)
CLI 91.85% <ø> (ø)
Common ∅ <ø> (∅)
Device Connectors 64.18% <ø> (ø)
Server 89.09% <100.00%> (+0.09%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ajzobro ajzobro left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good, minor questions.

Comment thread server/charm/src/charm.py
# If the key was unset, clear the stored key so the next
# config-changed with a valid key is treated as a fresh deployment.
if not new_key:
logger.info("Master key unset, clearing stored key")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we really want to support on-the-fly removal of the secret master key?

Is this also going to disable secrets when/if someone clears out the master key?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removing it will disable the secret store but also additional cleanup is needed (manually removing the relation), this is also needed because the stored state can't be modified easily, so you need to unset to not force a rotation

Comment thread server/charm/src/charm.py
return

# Rotate only if master key was previously defined, has changed,
# and this is the leader unit.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Here we only change the key if we are the leader unit... should we consider that when we are clearing the key as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question, normally this is required when sending changes directly to a DB (such as Mongo). Given this is internal state, perhaps its also a DB 🤔 I can add this, doesn't hurt to have it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ah perhaps I was wrong? It seems that the data may be per unit if I get this right:
https://documentation.ubuntu.com/ops/latest/reference/ops/#ops.StoredState

Data is stored alongside the charm (in the charm container for Kubernetes sidecar charms, and on the machine for machine charms).

If I get this right, each container have its own data store, so we need to clear them from all units

for state in state_out.stored_states
if state.owner_path == "TestflingerCharm" and state.name == "_stored"
)
assert stored.content["previous_master_key"] == ""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is verifying the "next" state has a "previous" master key that is blank; shouldn't we be verifying the current key is empty?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The previous_master_key is the value of the key internally stored by Juju which needs to be cleared if it was unset

@rene-oromtz rene-oromtz requested a review from ajzobro June 17, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants