[Ideas] data encrypt or privacy infomation protection #1943
Replies: 4 comments 1 reply
|
Thanks for opening this, @yz271544 — this is a topic I think a lot of users A few questions to help turn this into something actionable:
If there's interest, it might be worth turning this into a short design doc. Lirong |
|
Thanks for putting this together - data protection is a real gap for a lot of enterprise Cloudberry/Greenplum deployments, so it's good to see this raised. A few thoughts and questions on the proposal: Scope and threat model Prior art to consider pgcrypto already gives Postgres-family databases column-level encrypt/decrypt functions (pgp_sym_encrypt, etc.). Worth clarifying how this proposal differs - is the goal mainly to move key/claim management into a JWT-based session context rather than passing keys explicitly in SQL? JWT-based key delivery Load/export integration Happy to help think through a design doc if there's interest in moving this forward, particularly around how this would interact with the segment/coordinator split and existing external table protocols. |
|
Thanks for the feedback. I want to clarify the proposal a bit further. This is not intended to be another encryption-at-rest mechanism like TDE, and it is also different from storing encrypted column values with The underlying table data would remain unchanged. Privacy transformation would only happen when sensitive data is returned to a client. An authorized session could bypass the transformation and receive the original value. So this is probably closer to a Dynamic Privacy Protection / Dynamic Data Masking framework, with CPT being only one possible transformation algorithm. 1. Privacy policyAn administrator could define policies based on:
For CPT, possible parameters could include:
For example: CREATE PRIVACY POLICY phone_policy
SCOPE DATABASE current_database()
MATCH (
COLUMN_NAME ~ '(mobile|phone|tel)',
DATA_TYPE IN ('text', 'varchar')
)
USING CPT (
MODE = 'DIGIT',
KEY_ID = 'phone-key-v3',
START = 4,
LENGTH = -1
);Policy precedence could be: 2. Global metadata and cacheThe policy should be logically cluster-wide, but I do not think all coordinator and segment processes need to literally share one memory region. A possible design is: Each database instance could keep: When a policy changes, its generation/version changes and stale caches are invalidated or rebuilt. For CPT specifically, key-derived substitution mappings could also be precompiled and cached in shared memory rather than rebuilt for every row. 3. Session-level JWT authorizationFor CLI/JDBC/ODBC scenarios, I would like authorization to be session-scoped, for example: SET privacy.token = 'eyJ...';The JWT would not contain the CPT key. It would only authorize the session to bypass privacy transformation. Claims could bind the token to:
After validation, the backend could keep a small session-local authorization context. Then runtime behavior becomes: One concern is token leakage through SQL logs, 4. Apply protection only at the output boundaryInitially I thought this could simply be based on whether the statement is a But I think the better rule is: Only protect sensitive data when it crosses the database-to-client boundary. For example: SELECT mobile FROM customer;should apply privacy transformation. But: INSERT INTO backup_customer(mobile)
SELECT mobile FROM customer;should not, because this is internal data movement and the original value should be stored. The same applies to However: UPDATE customer
SET ...
RETURNING mobile;should still protect Likewise for: So conceptually: This keeps indexes, joins, grouping, ordering and normal internal query semantics unchanged. 5. MPP executionSince Cloudberry is MPP, applying all transformations only on the coordinator could become a bottleneck for large result sets. Ideally the final privacy projection should be pushed to segments where possible: while relational processing still happens on plaintext values before that final projection. 6. Expression bypassProtecting only direct column references is not enough. For example: SELECT mobile || '' FROM customer;
SELECT substring(mobile, 1, 11) FROM customer;
SELECT json_build_object('mobile', mobile) FROM customer;must not bypass the policy. Eventually this probably requires some form of sensitive-data lineage / taint propagation. For an initial implementation, a conservative approach could be:
7. Implementation questionsI would especially appreciate feedback on these points:
SET privacy.token = '...';be a reasonable integration point for session authorization?
My current preference is to keep the transformation as late as possible, so that only data actually leaving the database is affected. |
|
A few implementation details behind the proposal above, mainly to explain how I am currently thinking about policy management, session authorization, and query execution. 1. Policy representationOne possible model is to define privacy policies using:
For CPT, the parameters may include:
For example: CREATE PRIVACY POLICY phone_policy
SCOPE DATABASE current_database()
MATCH (
COLUMN_NAME ~ '(mobile|phone|tel)',
DATA_TYPE IN ('text', 'varchar')
)
USING CPT (
MODE = 'DIGIT',
KEY_ID = 'phone-key-v3',
START = 4,
LENGTH = -1
);I am also considering hierarchical policy precedence such as: This would allow a database-wide default policy while still supporting more specific overrides. 2. Policy metadata and cachingThe policy metadata needs to be logically consistent across the Cloudberry cluster, but I do not think this necessarily implies a single shared-memory region across the coordinator and all segments. A possible model is: Each database instance could maintain: When a policy is created, altered, or dropped, the policy generation could change and stale caches could be invalidated or rebuilt. For algorithms such as CPT, this may also be useful for precomputed state. For example, key-derived substitution mappings could be compiled once: The executor would then only need to look up the compiled context and apply the transformation. This avoids rebuilding CPT mappings for every row. 3. Session authorizationFor CLI/JDBC/ODBC usage, I would like the authorization mechanism to remain session-scoped and easy to consume. For example: SET privacy.token = 'eyJ...';The JWT itself would not carry the CPT key. It would only authorize the current session to bypass privacy transformation. Possible claims may bind the token to:
After successful validation, the backend could keep only a small session-local authorization context, for example: Then the per-query decision becomes inexpensive: One issue that probably needs special handling is credential leakage. A statement such as: SET privacy.token = '...';may otherwise appear in SQL logs, So if a GUC-based interface is used, I think 4. Execution semanticsOne point I changed my mind about is where the transformation should be triggered. Initially I was thinking in terms of: But this appears too coarse. I think a better semantic rule is:
For example: SELECT mobile FROM customer;would require protection. However: INSERT INTO backup_customer(mobile)
SELECT mobile FROM customer;would not, because the selected value is being used internally and should remain unchanged. Likewise, transformations should probably not affect: On the other hand: UPDATE customer
SET ...
RETURNING mobile;does expose a value to the client, so the The same reasoning applies to: Conceptually: The reason I prefer this model is that the privacy transformation would not change the semantics of filtering, joining, sorting, grouping, statistics, or other relational operations. 5. MPP executionThere is also an MPP-specific consideration. If the coordinator performs all transformations after receiving the final result set, it may become a bottleneck for large result sets. For example: Ideally, where the execution plan allows it, the final privacy projection could be executed on the segments: while filters, joins, grouping, sorting, and other internal operations still use the original values. This is another reason why having compiled policy state available in segment-local shared memory may be useful. 6. Derived expressionsA direct-column-only implementation would be easy to bypass. For example: SELECT mobile || '' FROM customer;
SELECT substring(mobile, 1, 11) FROM customer;
SELECT json_build_object('mobile', mobile) FROM customer;If Longer term, this may require some form of sensitive-data lineage or taint propagation. For an initial implementation, a conservative rule may be sufficient: This could keep the first implementation relatively small while avoiding obvious policy bypasses. 7. Open implementation questionsThe areas where I would especially appreciate implementation guidance are:
My current preference is to keep policy transformation as late in execution as possible and to avoid changing internal relational semantics. |
Uh oh!
There was an error while loading. Please reload this page.
Description
The following project describes a data encryption/decryption algorithm previously implemented in the Teradata data warehouse, which has also been used on other platforms.
The current Cloudberry could consider adding the issuance of decryption JWT tokens to the console, for example, by adding an administrator-set key to the claim.
Then, the JWT token could be configured at the JDBC or command-line connection session level to support encryption and decryption in various scenarios.
It's also worth considering scenarios where data is encrypted during loading and decrypted during export. Alternatively, it could support extended interfaces like Teradata's fastload and fastexp, providing inmod and outmod functions for both data loading and export.
data encrypt and decrypt demo
Use case/motivation
The goal is to enable native support for privacy data protection scenarios in next-generation data warehouses.
Related issues
No response
Are you willing to submit a PR?
All reactions