Data Masking with GitHub Actions Part 1 - Semantic Type and Global Masking Rule
Bytebase is a database DevSecOps platform designed for developers, security, DBA, and platform engineering teams. While it offers an intuitive GUI for managing database schema changes and access control, some teams may want to integrate Bytebase into their existing DevOps platforms using the Bytebase API.
Bytebase provides database dynamic data masking in the Enterprise Plan, which can mask sensitive data in the SQL Editor query result based on the context on the fly. It helps organizations to protect sensitive data from being exposed to unauthorized users.
By using GitHub Actions with Bytebase API, you can implement policy-as-code to apply database masking policies via the GitOps workflow. This tutorial will guide you through the process.
This is Part 1 of our tutorial series on implementing automated database masking using GitHub Actions:
- Part 1: Semantic Type and Global Masking Rule
- Part 2: Column Masking and Masking Exemption
- Part 3: Data Classification
- Part 4: Data Export with Masking (TBD)
Overview
In this tutorial, you'll learn how to automate database masking policies using GitHub Actions and the Bytebase API. This integration allows you to:
- Manage data masking rules as code
- Automatically apply masking policies when PRs are merged
Here is a merged pull request as an example, for this tutorial, only "Semantic Type and Global Masking Rule" is covered.
Prerequisites
Before you begin, make sure you have:
- Docker installed
- A GitHub account
- An ngrok account
- Bytebase Enterprise Plan subscription (you can request a free trial)
Setup Instructions
Step 1 - Start Bytebase in Docker and set the External URL generated by ngrok
ngrok is a reverse proxy tunnel, and in our case, we need it for a public network address in order to receive webhooks from VCS. ngrok we used here is for demonstration purposes. For production use, we recommend using Caddy.
-
Run Bytebase in Docker with the following command:
-
Bytebase is running successfully in Docker, and you can visit it via
localhost:8080
. Register an admin account and it will be granted theworkspace admin
role automatically. -
Login to ngrok Dashboard and complete the Getting Started steps to install and configure. If you want to use the same domain each time you launch ngrok, go to Cloud Edge > Domains, where you'll find the domain
<<YOURS>>.ngrok-free.app
linked to your account. -
Run the ngrok command
ngrok http --domain=<<YOURS>>.ngrok-free.app 8080
to start ngrok with your specific domain, and you will see the output displayed below: -
Log in Bytebase and click the gear icon (Settings) on the top right. Click General under Workspace. Paste
<<YOURS>>.ngrok-free.app
as External URL under Network section and click Update. -
Now you can access Bytebase via
<<YOURS>>.ngrok-free.app
.
Step 2 - Create Service Account
-
Log in as the admin user, and go to Security & Policy > Users & Groups. Click + Add User, fill in with
api-example
, choose theDBA
role that is sufficient for this tutorial and click Confirm. -
Find the newly created service account and click on Copy Service Key. We will use this token to authenticate the API calls.
Step 3 - Prepare Test Data
- Bytebase by default provides a project
Sample Project
with two databasehr_test
andhr_prod
. - Click IAM & Admin > Users & Groups on the left sidebar. Add users:
dev@example.com
,dev2@example.com
anddev3@example.com
with no roles. - Add a group
contractor@example.com
withdev3@example.com
as a member. - Go to project
Sample Project
, click Manage > Members on the left sidebar. - Click Grant Access and select users
dev@example.com
anddev2@example.com
withDeveloper
role and groupcontractor@example.com
withQuerier
role.
Step 4 - Configure GitHub Actions
-
Click Settings and then click Secrets and variables > Actions. Add the following secrets:
BYTEBASE_URL
: ngrok external URLBYTEBASE_SERVICE_KEY
:api-example@service.bytebase.com
BYTEBASE_SERVICE_SECRET
: service key copied in the previous step
Step 5 - Understanding the GitHub Workflow
Let's dig into the GitHub Actions workflow code:
-
Trigger: Workflow runs when PRs are merged to
main
. -
Authentication: The step
Login Bytebase
will log in Bytebase using the official bytebase-login action. The variables you configured in the GitHub Secrets and variables are mapped to the variables in the action. -
File Detection: The step
Get changed files
will monitor the changed files in the pull request. For this workflow, we only care about semantic type and global masking rule. Somasking/semantic-type.json
andmasking/global-masking-rule.json
are filtered out. -
PR Feedback: The step
Comment on PR
will comment on the merged pull to notify the result.
Semantic Type
Masking algorithm is associated with Semantic Type. You define semantic types and apply them to global masking rule or table columns. For example, you may define a semantic type birth_date
with a masking algorithm to mask month and day.
In Bytebase Console
Go to Data Access > Semantic Types and click Add. You can create a new semantic type with a name and description, and customize the masking algorithm.
In GitHub Workflow
Find the step Apply semantic type
, which will apply the semantic type to the database via API. All the masking algorithms should be defined in one file in the root directory as masking/semantic-type.json
.
By changing file masking/semantic-type.json
, creating a PR and merging, the semantic types will be applied. Go to Bytebase console, click Data Access > Semantic Types, you can see the applied semantic types.
Global Masking Rule
Global Masking Rule is configured by the admin.
In Bytebase Console
Go to Data Access > Global Masking and click Add. You can create a new global masking rule mapping condition to a semantic type.
In GitHub Workflow
Find the step Apply global masking rule
, which will apply the global masking rule to the database via API. All the global masking rules should be defined in one file in the root directory as masking/global-masking-rule.json
. The code it calls Bytebase API is as follows:
By changing file masking/global-masking-rule.json
, creating a PR and merge, you can apply the global masking rules.