Skip to content

Separate key creation and usage #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

AndersAstrand
Copy link
Collaborator

This adds a function to explicitly create keys at key providers. It also removes the "create if exists" semantics as that seems quite useless in the real world. If customers want it it's easy to add later.

The documentation is not updated in this PR since I ran out of time and needed to submit the code changes for review.

I will update the documentation in a separate PR.

@codecov-commenter
Copy link

codecov-commenter commented Jun 12, 2025

Codecov Report

Attention: Patch coverage is 83.78378% with 6 lines in your changes missing coverage. Please review.

Project coverage is 84.66%. Comparing base (086b342) to head (1eff35c).
Report is 3 commits behind head on TDE_REL_17_STABLE.

❌ Your project status has failed because the head coverage (84.66%) is below the target coverage (90.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@                  Coverage Diff                  @@
##           TDE_REL_17_STABLE     #428      +/-   ##
=====================================================
- Coverage              84.76%   84.66%   -0.10%     
=====================================================
  Files                     21       21              
  Lines                   2566     2589      +23     
  Branches                 393      402       +9     
=====================================================
+ Hits                    2175     2192      +17     
- Misses                   311      316       +5     
- Partials                  80       81       +1     
Components Coverage Δ
access 81.11% <ø> (ø)
catalog 88.22% <83.78%> (-0.40%) ⬇️
common 77.77% <ø> (ø)
encryption 73.45% <ø> (ø)
keyring 72.88% <ø> (ø)
src 91.44% <ø> (ø)
smgr 94.88% <ø> (+0.02%) ⬆️
transam ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@@ -1,3 +1,5 @@
\! rm -f '/tmp/pg_tde_test_keyring.per'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Even if we remove the file, the previous keys are still in the cache - shouldn't that cause issues? It seems a bit strange that create_key succeeds, even if we have a key named exactly that in the in memory cache. (multiple tests create test-db-key, but we never delete it)

My main concern with this, are you sure that we are using the correct key in this situation? The affected tests that reuse the same keyname don't restart the server. create_key won't update the cache, that usually happens when we retrieve the key. So it is possible that we store a new random generated key in the file, but we keep using the old key from the cache.

Copy link
Collaborator

Choose a reason for hiding this comment

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

No, I just realized we still push it to the cache in set, so that part should still work - but this still seems like a possibly problematic situation.

Copy link
Collaborator Author

@AndersAstrand AndersAstrand Jun 13, 2025

Choose a reason for hiding this comment

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

I don't understand what the problem is. The files are removed before the providers are even created, so there is nothing to be in cache. The providers doesn't even exist when these files are removed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The sql tests are reusing the same postgres instance - so even if we delete these files, the in memory cache is still there, we aren't doing a complete reset.

Thinking about it more this is probably fine, but we are still running tests in a not entirely realistic way with this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm ok I get what you mean, but each regress file does recreate the extension, and thus runs clear_principal_key_cache(dbOid) at start of each script. so it's probably fine.

I agree that we should maybe think about how that stuff works a little bit more though!

if (providerOid == GLOBAL_DATA_TDE_OID && !superuser())
ereport(ERROR,
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to access global key providers"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not 100% sure that access is the correct word there - create maybe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the same message as we use for the other places where we check this. Maybe "use" is a better word than "access"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe. Access is just confusing in this context to me, because it suggests a read only operation, and this isn't that, it always writes a new key.

Copy link
Collaborator

@jeltz jeltz left a comment

Choose a reason for hiding this comment

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

I think the change is generally good but this did me dislike the local vs global a bit more due to have long that makes the function names. Also had a few comments.

@@ -447,15 +445,99 @@ clear_principal_key_cache(Oid databaseId)
* SQL interface to set principal key
*/

Datum
pg_tde_create_key_using_database_key_provider(PG_FUNCTION_ARGS)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think I would prefer to call it generate to differentiate it from commands which creates objects inside pg_tde.

Copy link
Collaborator Author

@AndersAstrand AndersAstrand Jun 13, 2025

Choose a reason for hiding this comment

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

Hmm... I think we should be better at what words we use. But to me this definitely feels like we're creating something.

We don't have any other user facing functions named "create" afaik, so I don't think there is something to differentiate from.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I also prefer create, as we are creating keys on the providers, generate wouldn't be that explicit about this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I disagree but seems like I am outvoted. :) I think generate makes the usage more clear.

}

if (strlen(key_name) >= sizeof(keyInfo->name))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't we actually still need this check due to our file format? Imagine if a key exists which they have created themselves which is longer than the field size in our file format?

Copy link
Collaborator Author

@AndersAstrand AndersAstrand Jun 13, 2025

Choose a reason for hiding this comment

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

Oh. You're completely right. I forgot that these names are stored in the tdemap header. Thank you!

@AndersAstrand
Copy link
Collaborator Author

I think the change is generally good but this did me dislike the local vs global a bit more due to have long that makes the function names. Also had a few comments.

I agree about the database/global thing, but I don't think we'll have time to change that unfortunately :(

Also move a couple of checks to the calling function.
To ensure the tests are always run from the same state we remove any key
provider files so that pg_tde_add_database/global_key_provider_file()
always creates a new file.
Add new functions pg_tde_create_key_using_database/global_key_provider()
to create keys instead of key creation being a side effect of setting
the key.

Also remove support for "create if not exists" semantics as any user
should know what keys their key provider contains.
@AndersAstrand AndersAstrand force-pushed the tde/separate-key-creation-and-usage branch from 73c9ea5 to 1eff35c Compare June 13, 2025 11:12
@AndersAstrand
Copy link
Collaborator Author

New version pushed!

Copy link
Collaborator

@jeltz jeltz left a comment

Choose a reason for hiding this comment

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

This PR should really include documentation changes too but I am approving it since we are so close to the freeze. Decide yourself if you merge with our without documentation changes.

@AndersAstrand AndersAstrand merged commit ceff90e into percona:TDE_REL_17_STABLE Jun 13, 2025
17 checks passed
@AndersAstrand AndersAstrand deleted the tde/separate-key-creation-and-usage branch June 13, 2025 12:21
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