Skip to content

Commit f9377e6

Browse files
fix: update masking API endpoints to match current Bytebase API
Breaking API changes addressed: - Setting names: bb.workspace.semantic-types → SEMANTIC_TYPES, bb.workspace.data-classification → DATA_CLASSIFICATION (migrated in v3.7) - Policy URLs: policies/masking_rule → workspaces/-/policies/masking_rule (workspace prefix required by gRPC-gateway route) - Masking exception → exemption: renamed policy type, JSON fields, and data file (masking_exception → masking_exemption, maskingExceptionPolicy → maskingExemptionPolicy, maskingExceptions → exemptions) - CEL expressions: add resource. prefix (resource.environment_id, resource.classification_level) - Classification levels: id (string) → level (integer), levelId → level - JSON body fields: semanticTypeSettingValue → semanticType, data_classification_setting_value → dataClassification - Masking exemption: action field removed, member → members (array) Companion docs PR: bytebase/bytebase.com#1080 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f013a1d commit f9377e6

11 files changed

Lines changed: 58 additions & 71 deletions

.github/workflows/1-bb-masking-semantic-type-global.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
echo "File content:"
7979
cat "$CHANGED_FILE"
8080
81-
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/settings/bb.workspace.semantic-types" \
81+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/settings/SEMANTIC_TYPES" \
8282
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
8383
--header "Content-Type: application/json" \
8484
--data @"$CHANGED_FILE")
@@ -109,8 +109,9 @@ jobs:
109109
CHANGED_FILE="masking/global-masking-rule.json"
110110
echo "Processing: $CHANGED_FILE"
111111
112-
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/policies/masking_rule?allow_missing=true&update_mask=payload" \
112+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/workspaces/-/policies/masking_rule?allow_missing=true&update_mask=payload" \
113113
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
114+
--header "Content-Type: application/json" \
114115
--data @"$CHANGED_FILE")
115116
116117
# Extract status code and response body

.github/workflows/2-bb-masking-column.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Bytebase Masking Policy Update Column and Exception
1+
name: Bytebase Masking Policy Update Column and Exemption
22
on:
33
pull_request:
44
types: [closed]
@@ -7,7 +7,7 @@ on:
77
workflow_dispatch:
88

99
jobs:
10-
bytebase-masking-column-and-exception:
10+
bytebase-masking-column-and-exemption:
1111
if: github.event.pull_request.merged == true
1212
runs-on: ubuntu-latest
1313
permissions:
@@ -35,7 +35,7 @@ jobs:
3535
with:
3636
files: |
3737
masking/databases/**/**/database-catalog.json
38-
masking/projects/**/masking-exception.json
38+
masking/projects/**/masking-exemption.json
3939
since_last_remote_commit: true
4040
fetch_depth: 0
4141
include_all_old_new_renamed_files: true
@@ -49,7 +49,7 @@ jobs:
4949
echo "Modified files:"
5050
echo "${{ steps.changed-files.outputs.modified_files }}"
5151
echo "Contains database-catalog.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'database-catalog.json') }}"
52-
echo "Contains masking-exception.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'masking-exception.json') }}"
52+
echo "Contains masking-exemption.json: ${{ contains(steps.changed-files.outputs.all_changed_files, 'masking-exemption.json') }}"
5353
echo "Raw output:"
5454
echo "${{ toJSON(steps.changed-files.outputs) }}"
5555
@@ -89,17 +89,17 @@ jobs:
8989
fi
9090
done
9191
92-
- name: Apply masking exception policy
93-
id: apply-masking-exception
94-
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, '/masking-exception.json') }}
92+
- name: Apply masking exemption policy
93+
id: apply-masking-exemption
94+
if: ${{ steps.changed-files.outputs.any_changed == 'true' && contains(steps.changed-files.outputs.all_changed_files, '/masking-exemption.json') }}
9595
run: |
96-
# Process all masking-exception.json files
97-
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "masking-exception.json" | while read -r CHANGED_FILE; do
96+
# Process all masking-exemption.json files
97+
echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | grep "masking-exemption.json" | while read -r CHANGED_FILE; do
9898
echo "Processing: $CHANGED_FILE"
9999
PROJECT_NAME=$(echo "$CHANGED_FILE" | sed -n 's/masking\/projects\/\([^/]*\).*/\1/p')
100100
echo "PROJECT_NAME=$PROJECT_NAME"
101101
102-
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/projects/${PROJECT_NAME}/policies/masking_exception?allow_missing=true&update_mask=payload" \
102+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/projects/${PROJECT_NAME}/policies/masking_exemption?allow_missing=true&update_mask=payload" \
103103
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
104104
--header "Content-Type: application/json" \
105105
--data @"$CHANGED_FILE")
@@ -130,7 +130,7 @@ jobs:
130130
with:
131131
script: |
132132
const changedFiles = process.env.CHANGED_FILES || '';
133-
let commentBody = `### Update Column Masking and Exception Summary\n\n`;
133+
let commentBody = `### Update Column Masking and Exemption Summary\n\n`;
134134
135135
// Add status of merge
136136
commentBody += `✅ **PR Status:** Merged\n\n`;
@@ -163,18 +163,18 @@ jobs:
163163
});
164164
}
165165
166-
if (changedFiles.includes('masking-exception.json')) {
167-
const exceptionStatuses = Object.keys(${{ toJSON(steps.apply-masking-exception.outputs) }} || {})
166+
if (changedFiles.includes('masking-exemption.json')) {
167+
const exceptionStatuses = Object.keys(${{ toJSON(steps.apply-masking-exemption.outputs) }} || {})
168168
.filter(key => key.startsWith('status_code_'))
169169
.map(key => ({
170170
name: key.replace('status_code_', ''),
171-
status: ${{ toJSON(steps.apply-masking-exception.outputs) }}[key]
171+
status: ${{ toJSON(steps.apply-masking-exemption.outputs) }}[key]
172172
}));
173173
174174
exceptionStatuses.forEach(({name, status}) => {
175175
apiCallsFound = true;
176176
const success = status >= 200 && status < 300;
177-
commentBody += `- Masking Exception (${name}): ${success ? '✅' : '❌'} ${status}\n`;
177+
commentBody += `- Masking Exemption (${name}): ${success ? '✅' : '❌'} ${status}\n`;
178178
});
179179
}
180180

.github/workflows/3-bb-masking-classification.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
CHANGED_FILE="masking/data-classification.json"
6666
echo "Processing: $CHANGED_FILE"
6767
68-
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/settings/bb.workspace.data-classification" \
68+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/settings/DATA_CLASSIFICATION" \
6969
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
7070
--header "Content-Type: application/json" \
7171
--data @"$CHANGED_FILE")
@@ -91,8 +91,9 @@ jobs:
9191
CHANGED_FILE="masking/global-masking-rule-classification.json"
9292
echo "Processing: $CHANGED_FILE"
9393
94-
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/policies/masking_rule?allow_missing=true&update_mask=payload" \
94+
response=$(curl -s -w "\n%{http_code}" --request PATCH "${{ steps.bytebase-login.outputs.api_url }}/workspaces/-/policies/masking_rule?allow_missing=true&update_mask=payload" \
9595
--header "Authorization: Bearer ${{ steps.bytebase-login.outputs.token }}" \
96+
--header "Content-Type: application/json" \
9697
--data @"$CHANGED_FILE")
9798
9899
# Extract status code and response body

masking/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Docs: https://www.bytebase.com/docs/security/data-masking/semantic-types/
1313
API: https://api.bytebase.com/#tag/settingservice/PATCH/v1/settings/{setting}
1414

1515
```bash
16-
curl --request PATCH ${bytebase_url}/v1/settings/bb.workspace.semantic-types \
16+
curl --request PATCH ${bytebase_url}/v1/settings/SEMANTIC_TYPES \
1717
--header 'Authorization: Bearer '${bytebase_token} \
1818
--data @semantic-type.json
1919
```
@@ -25,7 +25,7 @@ Docs: https://www.bytebase.com/docs/security/data-masking/global-masking-rule/
2525
API: https://api.bytebase.com/#tag/orgpolicyservice/PATCH/v1/policies/{policy}
2626

2727
```bash
28-
curl --request PATCH "${bytebase_url}/v1/policies/masking_rule?allow_missing=true&update_mask=payload" \
28+
curl --request PATCH "${bytebase_url}/v1/workspaces/-/policies/masking_rule?allow_missing=true&update_mask=payload" \
2929
--header 'Authorization: Bearer '${bytebase_token} \
3030
--data @global-masking-rule.json
3131
```
@@ -37,14 +37,14 @@ Docs: https://www.bytebase.com/docs/security/data-masking/data-classification/
3737
API: https://api.bytebase.com/#tag/settingservice/PATCH/v1/settings/{setting}
3838

3939
```bash
40-
curl --request PATCH ${bytebase_url}/v1/settings/bb.workspace.data-classification \
40+
curl --request PATCH ${bytebase_url}/v1/settings/DATA_CLASSIFICATION \
4141
--header 'Authorization: Bearer '${bytebase_token} \
4242
--data @data-classification.json
4343
```
4444

45-
## Project-level masking exception
45+
## Project-level masking exemption
4646

47-
Project-level masking exception to overrule the workspace-level setting.
47+
Project-level masking exemption to overrule the workspace-level setting.
4848

4949
https://github.com/bytebase/database-security-github-actions-example/tree/main/masking/projects/project-sample
5050

masking/data-classification.json

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,66 @@
11
{
2-
"name": "bb.workspace.data-classification",
2+
"name": "settings/DATA_CLASSIFICATION",
33
"value": {
4-
"data_classification_setting_value": {
4+
"dataClassification": {
55
"configs": [
66
{
77
"title": "Classification Example",
88
"levels": [
99
{
10-
"id": "1",
1110
"title": "Level 1",
12-
"description": ""
11+
"level": 1
1312
},
1413
{
15-
"id": "2",
1614
"title": "Level 2",
17-
"description": ""
15+
"level": 2
1816
},
1917
{
20-
"id": "3",
2118
"title": "Level 3",
22-
"description": ""
19+
"level": 3
2320
},
2421
{
25-
"id": "4",
2622
"title": "Level 4",
27-
"description": ""
23+
"level": 4
2824
}
2925
],
3026
"classification": {
3127
"1": {
3228
"id": "1",
33-
"title": "Basic",
34-
"description": ""
29+
"title": "Basic"
3530
},
3631
"1-1": {
3732
"id": "1-1",
3833
"title": "Basic",
39-
"description": "",
40-
"levelId": "1"
34+
"level": 1
4135
},
4236
"1-2": {
4337
"id": "1-2",
4438
"title": "Assert",
45-
"description": "",
46-
"levelId": "1"
39+
"level": 1
4740
},
4841
"1-3": {
4942
"id": "1-3",
5043
"title": "Contact",
51-
"description": "",
52-
"levelId": "2"
44+
"level": 2
5345
},
5446
"1-4": {
5547
"id": "1-4",
5648
"title": "Health",
57-
"description": "",
58-
"levelId": "2"
49+
"level": 2
5950
},
6051
"2": {
6152
"id": "2",
62-
"title": "Relationship",
63-
"description": ""
53+
"title": "Relationship"
6454
},
6555
"2-1": {
6656
"id": "2-1",
6757
"title": "Social",
68-
"description": "",
69-
"levelId": "1"
58+
"level": 1
7059
},
7160
"2-2": {
7261
"id": "2-2",
7362
"title": "Business",
74-
"description": "",
75-
"levelId": "1"
63+
"level": 1
7664
}
7765
}
7866
}

masking/global-masking-rule-classification.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"name": "policies/masking_rule",
2+
"name": "workspaces/-/policies/masking_rule",
33
"inheritFromParent": false,
44
"type": "MASKING_RULE",
55
"maskingRulePolicy": {
66
"rules": [
77
{
88
"id": "76356d81-6231-4128-9be7-2c549fc505f5",
99
"condition": {
10-
"expression": "classification_level in [\"2\"]",
10+
"expression": "resource.classification_level in [2]",
1111
"title": "",
1212
"description": ""
1313
},
@@ -16,7 +16,7 @@
1616
{
1717
"id": "1ddc47c9-6ab6-4760-accd-947bc1a5f155",
1818
"condition": {
19-
"expression": "classification_level in [\"4\"]",
19+
"expression": "resource.classification_level in [4]",
2020
"title": "",
2121
"description": ""
2222
},

masking/global-masking-rule.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"name": "policies/masking_rule",
2+
"name": "workspaces/-/policies/masking_rule",
33
"inheritFromParent": false,
44
"type": "MASKING_RULE",
55
"maskingRulePolicy": {
66
"rules": [
77
{
88
"id": "76356d81-6231-4128-9be7-2c549fc505f5",
99
"condition": {
10-
"expression": "environment_id == \"prod\"",
10+
"expression": "resource.environment_id == \"prod\"",
1111
"title": "",
1212
"description": ""
1313
},

masking/projects/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Project-level masking exception
1+
# Project-level masking exemption
22

3-
Masking exception is defined at the project level. It's considered as the exception to the masking
3+
Masking exemption is defined at the project level. It's considered as the exemption to the masking
44
policies defined at the [workspace level](https://github.com/bytebase/api-example/blob/main/data-security/masking).
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Masking exception
1+
# Masking exemption
22

33
Docs: https://www.bytebase.com/docs/security/data-masking/access-unmasked-data/
44

55
API: https://api.bytebase.com/#tag/orgpolicyservice/PATCH/v1/projects/{project}/policies/{policy}
66

77
```bash
88
export project_id=project-sample
9-
curl --request PATCH "${bytebase_url}/v1/projects/${project_id}/policies/masking_exception?allow_missing=true&update_mask=payload" \
9+
curl --request PATCH "${bytebase_url}/v1/projects/${project_id}/policies/masking_exemption?allow_missing=true&update_mask=payload" \
1010
--header 'Authorization: Bearer '${bytebase_token} \
11-
--data @masking-exception.json
11+
--data @masking-exemption.json
1212
```

masking/projects/project-sample/masking-exception.json renamed to masking/projects/project-sample/masking-exemption.json

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,26 @@
11
{
22
"inheritFromParent": false,
3-
"type": "MASKING_EXCEPTION",
4-
"maskingExceptionPolicy": {
5-
"maskingExceptions": [
3+
"type": "MASKING_EXEMPTION",
4+
"maskingExemptionPolicy": {
5+
"exemptions": [
66
{
7-
"action": "EXPORT",
8-
"member": "user:dev@example.com",
7+
"members": ["user:dev@example.com"],
98
"condition": {
109
"expression": "resource.instance_id == \"prod-sample-instance\" && resource.database_name == \"hr_prod\" && resource.schema_name == \"public\" && resource.table_name == \"salary\" && resource.column_name == \"amount\"",
1110
"title": "",
1211
"description": ""
1312
}
1413
},
1514
{
16-
"action": "QUERY",
17-
"member": "user:dev2@example.com",
15+
"members": ["user:dev2@example.com"],
1816
"condition": {
1917
"expression": "resource.instance_id == \"prod-sample-instance\" && resource.database_name == \"hr_prod\" && resource.schema_name == \"public\" && resource.table_name == \"salary\" && resource.column_name == \"amount\"",
2018
"title": "",
2119
"description": ""
2220
}
2321
},
2422
{
25-
"action": "QUERY",
26-
"member": "group:contractor@example.com",
23+
"members": ["group:contractor@example.com"],
2724
"condition": {
2825
"expression": "resource.instance_id == \"prod-sample-instance\" && resource.database_name == \"hr_prod\" && resource.schema_name == \"public\" && resource.table_name == \"salary\" && resource.column_name == \"amount\"",
2926
"title": "",

0 commit comments

Comments
 (0)