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
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
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 that provides a public network address to access Bytebase. We use ngrok here for demonstration purposes.
-
Run Bytebase in Docker with the following command:
-
Once Bytebase is running in Docker, you can access it at
localhost:8080. -
Log in to the ngrok Dashboard and complete the Getting Started steps to install and configure ngrok. To use a consistent domain, navigate to Universal Gateway > Endpoints to find your assigned domain:
<<YOURS>>.ngrok-free.app. -
Start ngrok with your domain by running:
You should see output similar to this:

-
You can now access Bytebase at
https://<<YOURS>>.ngrok-free.app. -
(Optional) To configure SSO (Entra/SCIM), log in to Bytebase, click Settings > General in the left sidebar. Scroll to the Network section, set
https://<<YOURS>>.ngrok-free.appas the External URL and click Confirm and update.
Step 2 - Create Service Account
-
Log in as
Workspace Admin, and go to IAM & Admin > Users & Groups. Click + Add User, fill in withapi-sample, choose theWorkspace DBArole sufficient for this tutorial and click Confirm.
-
Find the newly created service account and 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 Projectwith two databasehr_testandhr_prod. - Click IAM & Admin > Users & Groups on the left sidebar. Add users:
dev@example.com,dev2@example.comanddev3@example.comwith no roles. - Add a group
contractor@example.comwithdev3@example.comas a member. - Go to project
Sample Project, click Manage > Members on the left sidebar. - Click Grant Access and select users
dev@example.comanddev2@example.comwithDeveloperrole and groupcontractor@example.comwithQuerierrole.
Step 4 - Configure GitHub Actions
- Fork Database Security GitHub Actions Example.
-
Click Settings and then click Secrets and variables > Actions. Add the following secrets:
BYTEBASE_URL: ngrok external URLBYTEBASE_SERVICE_KEY:api-example@service.bytebase.comBYTEBASE_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 Bytebasewill 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 fileswill monitor the changed files in the pull request. For this workflow, we only care about semantic type and global masking rule. Somasking/semantic-type.jsonandmasking/global-masking-rule.jsonare filtered out. -
PR Feedback: The step
Comment on PRwill 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 typebirth_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 stepApply 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.
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 stepApply 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:
masking/global-masking-rule.json, creating a PR and merge, you can apply the global masking rules.

