diff --git a/docs/tutorials/manage-data-masking-with-terraform.mdx b/docs/tutorials/manage-data-masking-with-terraform.mdx
index a8b98d12..f285c74b 100644
--- a/docs/tutorials/manage-data-masking-with-terraform.mdx
+++ b/docs/tutorials/manage-data-masking-with-terraform.mdx
@@ -229,7 +229,7 @@ resource "bytebase_policy" "global_masking_policy" {
bytebase_setting.environments
]
- # parent defaults to workspace when not specified.
+ # parent defaults to the current workspace when omitted.
type = "MASKING_RULE"
enforce = true
inherit_from_parent = false
@@ -350,8 +350,8 @@ Verify in Bytebase:
Create `8-5-masking-exemption.tf` to grant bypass permissions:
-- Workspace Admin (`admin@example.com`) and QA Tester (`qa1@example.com`) have masking exemptions for `birth_date` and `last_name` in table `employee`
-- Developer 1 (`dev1@example.com`) has exemption for specific columns via CEL expression
+- Workspace Admin (`admin@example.com`) and QA Tester (`qa1@example.com`) have masking exemptions for `birth_date` and `last_name` in the `employee` table (expires 2027-07-30).
+- Developer 1 (`dev1@example.com`) has exemptions for specific columns via CEL `raw_expression` (no expiry).
```hcl 8-5-masking-exemption.tf
resource "bytebase_policy" "masking_exemption_policy" {
@@ -410,14 +410,10 @@ terraform apply
Verify the masking exemptions are working:
-1. Log in as Workspace Admin (`admin@example.com`), then go to **SQL Editor** to access `hr_prod`, double-click `employee` table on the left. You may notice the `birth_date` is not masked any longer.
+1. Log in as Workspace Admin (`admin@example.com`), then go to **SQL Editor** to access `hr_prod` and double-click the `employee` table. Both `birth_date` and `last_name` are now unmasked for both query and export.

-1. Click **Export**, and then open the file. You should notice the `birth_date` is still masked while `last_name` is no longer masked.
-
- 
-
1. You may go to **Manage > Masking Exemptions** to view current exemptions. They will expire automatically after the expiration time.

diff --git a/docs/tutorials/manage-database-access-control-with-terraform.mdx b/docs/tutorials/manage-database-access-control-with-terraform.mdx
index 54668a07..155b4d37 100644
--- a/docs/tutorials/manage-database-access-control-with-terraform.mdx
+++ b/docs/tutorials/manage-database-access-control-with-terraform.mdx
@@ -79,7 +79,7 @@ resource "bytebase_iam_policy" "workspace_iam" {
bytebase_group.qa
]
- # parent defaults to workspace when not specified.
+ # parent defaults to the current workspace when omitted.
iam_policy {
@@ -119,6 +119,10 @@ resource "bytebase_iam_policy" "workspace_iam" {
}
```
+
+Service accounts use the `serviceAccount:` member prefix, workload identities use `workloadIdentity:`, users use `user:`, and groups use `group:`.
+
+
`allUsers` is a special member representing everyone in the workspace. Without it, users may be
unable to access the workspace.
diff --git a/docs/tutorials/manage-environments-with-terraform.mdx b/docs/tutorials/manage-environments-with-terraform.mdx
index 84761e49..c5038426 100644
--- a/docs/tutorials/manage-environments-with-terraform.mdx
+++ b/docs/tutorials/manage-environments-with-terraform.mdx
@@ -198,12 +198,7 @@ Let's add rollout and data protection policies, for more details, see: [Environm
| Terraform resource | [bytebase_policy](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/policy) |
| Sample file | [1-2-env-policy-rollout.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/1-2-env-policy-rollout.tf) |
-When no rollout policy is found for an environment, Bytebase applies a default rollout policy with the following checkers:
-
-- **Required Issue Approval**: Changes must be approved before deployment
-- **Plan Check Enforcement**: SQL plan checks must pass (errors only)
-
-You can explicitly configure these policies using Terraform. Create `1-2-env-policy-rollout.tf`:
+The rollout policy controls whether changes deploy automatically and which roles can manually roll out. Create `1-2-env-policy-rollout.tf`:
```hcl 1-2-env-policy-rollout.tf
# Test environment - automatic deployment
@@ -213,7 +208,7 @@ resource "bytebase_policy" "rollout_policy_test" {
type = "ROLLOUT_POLICY"
rollout_policy {
- automatic = true # Deploy changes automatically
+ automatic = true # Deploy changes automatically when all checks pass
roles = [
"roles/workspaceAdmin",
"roles/projectOwner"
@@ -239,8 +234,8 @@ resource "bytebase_policy" "rollout_policy_prod" {
**Key Configuration Options:**
-- `automatic`: When `true`, changes deploy automatically after approval. When `false`, requires manual click to deploy.
-- `roles`: List of roles allowed to manually deploy changes. Required even with automatic rollout, as manual approval is needed when checks fail.
+- `automatic`: When `true`, changes deploy automatically after all checks pass. When `false`, requires manual click to deploy.
+- `roles`: List of roles allowed to manually roll out changes. Required even with automatic rollout, as manual approval is needed when checks fail.
### Data Protection Policy
@@ -259,15 +254,20 @@ resource "bytebase_policy" "query_data_policy_prod" {
type = "DATA_QUERY"
query_data_policy {
- maximum_result_rows = 1000
- disable_copy_data = true # Block data copy
- disable_export = true # Block data export
- allow_admin_data_source = false # Restrict admin data source access
+ maximum_result_rows = 1000 # Cap rows returned per query
+ disable_copy_data = true # Block copy-to-clipboard
+ disable_export = true # Block export
+ allow_admin_data_source = false # Force read-only data source when configured
}
}
```
-- The data protection policy is only applied to the `Prod` environment. In the `Test` environment, by default, users may execute queries and copy data directly in SQL Editor.
+- The policy is only applied to the `Prod` environment. In `Test`, the defaults apply (no row cap, copy/export allowed, admin data source usable).
+
+- `allow_admin_data_source` controls [access to the data source](/sql-editor/settings/data-source-restriction):
+
+ - `true`: Admin data source is allowed.
+ - `false`: When a read-only data source is configured, users are forced onto it; otherwise falls back to admin.
## Step 6 - Apply Configuration
diff --git a/docs/tutorials/manage-general-settings-with-terraform.mdx b/docs/tutorials/manage-general-settings-with-terraform.mdx
index 9eb09c57..b228ea72 100644
--- a/docs/tutorials/manage-general-settings-with-terraform.mdx
+++ b/docs/tutorials/manage-general-settings-with-terraform.mdx
@@ -33,7 +33,7 @@ This tutorial is part of the **Bytebase Terraform Provider** series:
## What You'll Learn
- **Configure** workspace profile settings including signup controls and external URL
-- **Create** multi-step and risk-based approval flows for database changes
+- **Create** multi-step, risk-based approval flows for database changes using CEL conditions
## Prerequisites
@@ -84,10 +84,10 @@ This configuration:
### Step 2 - Approval Flow Settings
-| | |
-| --------------------- | ---------------------------------------------------------------------------------------------------------------------- |
-| Terraform resource | [bytebase_setting](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/setting) |
-| Sample file | [4-2-approval-flow.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/4-2-approval-flow.tf) |
+| | |
+| ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
+| Terraform resource | [bytebase_setting](https://registry.terraform.io/providers/bytebase/bytebase/latest/docs/resources/setting) |
+| Sample file | [4-2-approval-flow.tf](https://github.com/bytebase/terraform-provider-bytebase/blob/main/tutorials/4-2-approval-flow.tf) |
Create `4-2-approval-flow.tf` with approval flow configuration that requires multiple approvals for risky operations:
@@ -97,10 +97,12 @@ resource "bytebase_setting" "approval_flow" {
name = "settings/WORKSPACE_APPROVAL"
approval_flow {
+ # Rule 1: risky database changes need a three-step approval
rules {
flow {
title = "Project Owner → DBA → Admin"
description = "Need DBA and workspace admin approval"
+ # The steps of the flow are executed in the order of the roles list.
roles = [
"roles/projectOwner",
"roles/workspaceDBA",
@@ -111,10 +113,10 @@ resource "bytebase_setting" "approval_flow" {
condition = "request.risk >= 100"
}
+ # Rule 2: fallback — everything else only needs a DBA
rules {
flow {
title = "Fallback rule"
- # Approval flow following the step order.
roles = [
"roles/workspaceDBA"
]
@@ -125,10 +127,12 @@ resource "bytebase_setting" "approval_flow" {
}
```
-Each rule defines:
-- `flow.roles`: An ordered list of roles that form the approval chain
-- `source` (optional): The operation type to match for that rule (e.g., `CHANGE_DATABASE`, `CREATE_DATABASE`)
-- `condition`: A CEL expression that determines when the rule applies
+**Key Configuration Options:**
+
+- `flow.roles`: Ordered list of roles that must approve the issue, in sequence.
+- `source`: The activity source this rule matches — `CHANGE_DATABASE`, `CREATE_DATABASE`, `EXPORT_DATA`, `REQUEST_ROLE`, or `REQUEST_ACCESS`. Omit for a fallback rule.
+- `condition`: A CEL expression evaluated against the request. Common variables include `request.risk` (100 = LOW, 200 = MODERATE, 300 = HIGH) and `resource.project_id`. Use `"true"` for a catch-all fallback.
+- Rules are evaluated in order; the **first matching rule applies**, so place the most specific rules first and keep a fallback last.
### Step 3 - Apply Configuration
@@ -151,12 +155,17 @@ terraform apply

-1. Verify the `Project Owner → DBA → Admin` flow is configured.
+1. Verify the `Project Owner → DBA → Admin` flow is configured for the `CHANGE_DATABASE` source with `request.risk >= 100`, and the `Fallback rule` catches everything else.
+
+
+Risk levels (returned by `request.risk` in the CEL expression) are configured separately in **CI/CD > Risks** in the UI. Each risk rule maps an activity (DDL/DML/CREATE_DATABASE/EXPORT/REQUEST_ROLE) plus a CEL condition to a numeric level (100 LOW / 200 MODERATE / 300 HIGH), which is then evaluated against your approval-flow conditions here.
+
## Key Points
- **Workspace Profile**: Controls signup, domain restrictions, and external URL for your entire Bytebase workspace
-- **Approval Flows**: Define multi-step approval processes with CEL conditions for database change governance
+- **Approval Flows**: Define multi-step approval processes. Each rule binds a `source` + CEL `condition` to an ordered list of approver roles; rules are evaluated top-down, first match wins
+- **Fallback Rule**: Include a final rule with `condition = "true"` and no `source` so that every issue has a defined approval path
You can configure additional
@@ -165,7 +174,7 @@ terraform apply
+You created `tf@service.bytebase.com` manually in Part 1 to bootstrap the provider. The `bytebase_service_account` resource here adopts that existing account on first apply (you'll see a "Service account already exists" warning) — no manual import needed.
+
+
### Step 2 - Apply User Configuration
```bash
@@ -219,7 +225,7 @@ terraform apply
## Key Points
-- **User Types**: Regular users (`bytebase_user`) for team members, service accounts (`bytebase_service_account`) for API/automation, workload identities (`bytebase_workload_identity`) for CI/CD
+- **Resource Types**: Use `bytebase_user` for team members, `bytebase_service_account` for API/automation (returns a service key you can use as a Terraform `service_key`), and `bytebase_workload_identity` for secret-less federation (e.g., GitHub Actions OIDC)
- **Group Roles**: Each group has owners (manage membership) and members (inherit permissions)
- **Organization**: Groups simplify permission management - assign roles to groups instead of individual users
diff --git a/src/app/[locale]/(legal)/security/page.tsx b/src/app/[locale]/(legal)/security/page.tsx
index 45291f08..e29d6e24 100644
--- a/src/app/[locale]/(legal)/security/page.tsx
+++ b/src/app/[locale]/(legal)/security/page.tsx
@@ -163,8 +163,8 @@ export default function Page() {
How do I report a potential vulnerability or security concern?
Please contact us by e-mail at{' '}
- help@bytebase.com and we'll get back
- to you ASAP.
+ help@bytebase.com and we'll get back to
+ you ASAP.