GitHub user yz271544 added a comment to the discussion: [Ideas] data encrypt or
privacy infomation protection
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 `pgcrypto`.
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 policy
An administrator could define policies based on:
* column name or pattern
* data type
* scope: database / schema / table / column
* transformation algorithm
* algorithm-specific parameters
For CPT, possible parameters could include:
* mode
* key / key ID
* start position
* transformation length
* a special value meaning "from start position to the end"
For example:
```sql id="5qhs11"
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:
```text id="0uuw7q"
column > table > schema > database
```
## 2. Global metadata and cache
The 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:
```text id="1obwwl"
authoritative policy catalog
|
v
policy generation/version
|
+----------------------+
| |
v v
coordinator cache segment-local cache
```
Each database instance could keep:
```text id="aiwu6p"
L1: backend-local cache
L2: instance shared-memory cache
L3: persistent catalog
```
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 authorization
For CLI/JDBC/ODBC scenarios, I would like authorization to be session-scoped,
for example:
```sql id="29lfk0"
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:
* database
* database user
* privilege such as `privacy:bypass`
* validity period
After validation, the backend could keep a small session-local authorization
context.
Then runtime behavior becomes:
```text id="8gwii6"
authorized session
-> return original value
normal session
-> apply privacy policy
```
One concern is token leakage through SQL logs, `pg_stat_activity`, audit logs,
or client history, so the token value should be treated as sensitive
configuration.
## 4. Apply protection only at the output boundary
Initially I thought this could simply be based on whether the statement is a
`SELECT`.
But I think the better rule is:
**Only protect sensitive data when it crosses the database-to-client boundary.**
For example:
```sql id="6lmdij"
SELECT mobile FROM customer;
```
should apply privacy transformation.
But:
```sql id="4qt19t"
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 `UPDATE ... FROM`, CTAS and `SELECT INTO`.
However:
```sql id="t8snkk"
UPDATE customer
SET ...
RETURNING mobile;
```
should still protect `mobile`, because the value is returned to the client.
Likewise for:
```text id="ipuxjh"
INSERT ... RETURNING
DELETE ... RETURNING
COPY ... TO STDOUT
cursor FETCH
```
So conceptually:
```text id="j7idke"
Scan / Filter / Join / Aggregate / Sort / Motion
|
| plaintext
v
Final client-visible output
|
v
Privacy Policy
/ \
authorized normal
| |
plaintext CPT / MASK
```
This keeps indexes, joins, grouping, ordering and normal internal query
semantics unchanged.
## 5. MPP execution
Since 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:
```text id="pb2ux6"
Segment 1 -> privacy projection --\
Segment 2 -> privacy projection ----> Coordinator -> Client
Segment 3 -> privacy projection --/
```
while relational processing still happens on plaintext values before that final
projection.
## 6. Expression bypass
Protecting only direct column references is not enough.
For example:
```sql id="qgwpbd"
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:
* direct sensitive column output -> apply configured policy
* expression derived from sensitive column -> deny or apply a safe fallback
* safe aggregate such as `COUNT(*)` -> allow
* authorized session -> bypass
## 7. Implementation questions
I would especially appreciate feedback on these points:
1. Would an authoritative catalog plus per-instance shared-memory caches be a
reasonable architecture for policy metadata in Cloudberry?
2. Would a custom session GUC such as:
```sql id="f6q176"
SET privacy.token = '...';
```
be a reasonable integration point for session authorization?
3. Would it make more sense to implement the privacy transformation close to
the final output / executor boundary, rather than modifying both the PostgreSQL
planner and GPORCA?
My current preference is to keep the transformation as late as possible, so
that only data actually leaving the database is affected.
GitHub link:
https://github.com/apache/cloudberry/discussions/1943#discussioncomment-18269641
----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]