The complete guide to risk levels (riskLevel)
This page explains the risk control mechanism of Rabetbase CLI (dev mode) in detail. riskLevel is a built-in permission guardrail that prevents mistakes from causing irreversible changes — such as accidentally deploying scripts, deleting dataset metadata, or overwriting live menu resources.
What riskLevel is
riskLevel is the **command execution permission guardrail ** of Rabetbase CLI. Every command has a preset risk level, and before executing, the CLI compares the configured riskLevel against what the command requires — if the configured permission is insufficient, the command is blocked with a clear error.
**Important security design **:
- riskLevel **cannot be changed through CLI commands ** (including config set). It can only be set by a human manually editing the .rabetbase.json config file. This prevents AI Agents or automation scripts from escalating their own privileges — every permission change must be a deliberate human act.
- riskLevel has no environment variable override, preventing AI from temporarily tweaking environment variables to bypass security controls.
The three-level risk system
The CLI defines three risk levels, from low to high:
| Risk level | Value | Meaning | Typical commands |
|---|---|---|---|
| read | 0 | Read-only operations; no data is modified | dataset list/detail, sql list/detail/exec, bff list/detail/status, api list, codegen sql/sdk, doctor, run |
| write | 1 | Write operations; data is created or modified | dataset rename/field-update/extend-update, bff create/pull, sql pull, api pull, app add/use, config set, project init/upgrade, menu sync |
| high-risk-write | 2 | Irreversible, overwriting, or deleting operations | dataset delete/link-delete, menu update, bff push/delete, sql create/push/delete, db delete, app remove |
The core decision logic
Internally, the CLI compares numeric values to decide whether permission is sufficient:
read(0) < write(1) < high-risk-write(2)The default riskLevel of Rabetbase CLI is high-risk-write (unrestricted). Dev mode targets developers who routinely deploy, delete, or overwrite resources. If you want tighter control for AI Agent or CI scenarios, set it manually in the config file.
Recommended configuration strategy:
- **Local development (human at the keyboard) **: leave it unset or use
high-risk-write— unrestricted - **AI Agent-assisted development **: set to
write, so the AI cannot directly push or delete BFF scripts - **CI/CD pipelines **: set as the process requires; pushing needs
high-risk-write
How to set riskLevel
**Changing it via the CLI is forbidden **: running
rabetbase config set --key riskLevel --value writeis rejected with the error: "riskLevel" cannot be changed via the CLI. This is a deliberate security restriction.
The only way: edit the config file manually
Open .rabetbase.json in the project root and edit the riskLevel field directly:
**Single-app config **:
{
"appcode": "app-xxxxxxxx",
"riskLevel": "write"
}**Multi-app config ** (recommended, differentiated by environment):
{
"apps": {
"prod": {
"appcode": "app-xxxxxxxx",
"env": "production",
"riskLevel": "write"
},
"daily": {
"appcode": "app-yyyyyyyy",
"env": "daily",
"riskLevel": "high-risk-write"
}
},
"defaultApp": "prod"
}**Config precedence **: riskLevel in an app profile > riskLevel in the top-level config > the default (high-risk-write). Recommended practice: set the production profile to write so AI Agents cannot push straight to production; set the local daily environment to high-risk-write so development stays unrestricted.
Checking the current riskLevel
rabetbase config get --key riskLevelOr view the full config:
rabetbase config listPermission blocking in detail
Scenario 1: pushing a BFF script when riskLevel=write
With "riskLevel": "write" in .rabetbase.json:
rabetbase bff push --type ENDPOINT --name myFeatureOutput (interactive mode):
Command `rabetbase bff push` has risk level "high-risk-write", which exceeds the configured riskLevel "write".
Edit the config file manually and set riskLevel to "high-risk-write".A human must manually edit .rabetbase.json, change riskLevel to "high-risk-write", and run the command again.
Scenario 2: pushing SQL when riskLevel=write
rabetbase sql push --sqlcode xxxxxxxx-xxxxxxxxOutput (interactive mode):
Command `rabetbase sql push` has risk level "high-risk-write", which exceeds the configured riskLevel "write".
Edit the config file manually and set riskLevel to "high-risk-write".Scenario 3: trying to change riskLevel via the CLI
rabetbase config set --key riskLevel --value high-risk-writeOutput:
"riskLevel" cannot be changed via the CLI.This is by design. Even if an AI Agent or automation script knows the command, it cannot escalate privileges. Only a human who can directly edit the filesystem can change riskLevel.
Scenario 4: pushing a BFF script when riskLevel=high-risk-write
When the riskLevel is high enough, push is no longer blocked by riskLevel, but it triggers the **high-risk confirmation mechanism ** (see the next section).
The high-risk confirmation mechanism
high-risk-write commands have an extra confirmation layer. Even with riskLevel already set to high-risk-write, explicit confirmation is still required.
Interactive mode (local terminal)
rabetbase bff push --type ENDPOINT --name myFeatureOutput:
⚠ High-risk operation: rabetbase bff push
Deploy BFF script to production (overwrites existing)
Affected: type=ENDPOINT, name=myFeature
Continue? [y/N]:Enter y or yes to confirm; any other input (including pressing Enter) cancels the operation.
Non-interactive mode (CI/CD, scripts, pipes)
In non-interactive mode you must use the --yes flag:
rabetbase bff push --type ENDPOINT --name myFeature --yesIf you forget --yes:
High-risk operation `rabetbase bff push` requires --yes in non-interactive mode.What triggers non-interactive mode
The CLI enters non-interactive mode when any of these holds:
- The --non-interactive or --ci flag is used
- The environment variable RABETBASE_CI=true
- The environment variable CI=true (set automatically by GitHub Actions / GitLab CI)
- stdout is not a TTY (piped or redirected)
- stdin does not support raw mode
--dry-run preview: a safety net before execution
For commands that support dry-run, --dry-run previews the operation **without executing it **.
rabetbase bff push --type ENDPOINT --name myFeature --dry-runOutput:
{
"ok": true,
"command": "rabetbase bff push",
"risk": "high-risk-write",
"dryRun": true,
"data": {
"method": "POST",
"url": "/api/bff/deploy",
"body": { "code": "my-bff-script" }
}
}**Recommended workflow **: preview with --dry-run to confirm the parameters, then execute for real. This matters most in production.
Quick reference: risk levels of all commands
read (read-only, always allowed)
| Command | Description |
|---|---|
| dataset list / detail / operations / links | View datasets |
| sql list / detail / exec / validate | View and run SQL queries |
| bff list / detail / status | View BFF scripts |
| api list | View the API list |
| codegen sql / sdk | Generate code |
| app list / remote | View app profiles |
| config list / get | View configuration |
| auth login | Browser login (read-only authentication) |
| logs show | View command logs |
| doctor | Environment diagnostics |
| run | Run package.json scripts |
write (writes; requires riskLevel ≥ write)
| Command | Description |
|---|---|
| dataset rename / field-update / extend-update | Change a dataset's name, field display properties, or top-level extend |
| dataset link-create / link-update | Create or update dataset relations |
| bff create | Create a new BFF script |
| bff pull | Pull BFF scripts to local |
| sql pull | Pull SQL to local |
| api pull / generate | Pull or generate API definitions locally |
| api doc | Generate API documentation |
| app add / use | Add or switch app profiles |
| config set | Change config fields |
| project init / create / upgrade | Project initialization, creation, and upgrade migration |
| menu sync | Sync menu structure |
| page generate-start / sync / push | Smart list-page generation, sync, and push; generate-start previews by default and needs --apply to execute |
| db create / update / analyze-start / analyze-cancel | Database connection create/update and analysis task control |
| auth logout | Log out |
| logs clear | Clear command logs |
| update | Upgrade the CLI |
| skill | Install/manage Skills |
| issue report | Report CLI issues |
high-risk-write (high risk; requires riskLevel = high-risk-write)
| Command | Requires confirmation | dry-run | Description |
|---|---|---|---|
| bff push | Yes (interactive or --yes) | Yes | Deploy a BFF script to the platform (overwrites; irreversible) |
| bff delete | Yes (interactive or --yes) | No | Delete a BFF script (irreversible) |
| sql create / push / delete | Yes (interactive or --yes) | Depends on the command | Create, overwrite, or delete platform SQL |
| dataset delete | Yes (interactive or --yes) | Yes | Delete platform dataset metadata and related page/menu records; physical tables are not dropped; actual deletion also requires --confirm |
| dataset link-delete | Yes (interactive or --yes) | Yes | Delete a dataset relation |
| menu update | Yes (interactive or --yes) | Yes | Bulk-update live menu CDN resources |
| db delete | Yes (interactive or --yes) | Depends on the command | Delete a database connection config |
| app remove | Yes (interactive or --yes) | Depends on the command | Delete a local app profile |
Four layers of security, summarized
Rabetbase CLI layers four progressive protections over dangerous operations:
**第一层:riskLevel 只能手动设置** riskLevel 禁止通过 CLI 命令修改,只能由人类手动编辑 .rabetbase.json。AI Agent 和自动化脚本无法提权。这是最根本的防线。
**第二层:riskLevel 拦截** 配置级别的权限控制。当命令风险超过 riskLevel 时直接拒绝。适用于:所有 write 和 high-risk-write 命令。
**第三层:高危确认提示** 交互模式下弹出确认提示,非交互模式要求 --yes flag。适用于:bff push、bff delete、dataset delete、menu update 等 high-risk-write 命令。
**第四层:--dry-run 预览** 执行前预览完整的请求内容,不实际发送。适用于:bff push、dataset delete、menu update 等支持 dry-run 的命令。Real-world scenarios
Scenario 1: AI Agent-assisted development (recommended config)
// .rabetbase.json
{
"apps": {
"prod": { "appcode": "app-xxxxxxxx", "env": "production", "riskLevel": "write" },
"daily": { "appcode": "app-yyyyyyyy", "env": "daily", "riskLevel": "high-risk-write" }
},
"defaultApp": "daily"
}# AI Agent 可以:查询、新建 BFF、拉取代码或 SQL(daily 环境不限)
rabetbase bff list
rabetbase bff create --type ENDPOINT --name myFeature
rabetbase sql pull --sqlcode xxxxxxxx-xxxxxxxx
# AI Agent 无法(prod 环境 riskLevel=write 阻止):
rabetbase bff push --type ENDPOINT --name myFeature # 被拦截,需人类手动改配置Scenario 2: the full safety flow for a BFF deployment
# 1. 人类手动将 .rabetbase.json 中 riskLevel 设为 "high-risk-write"
# 2. 查看当前 BFF 状态
rabetbase bff status
# 3. dry-run 预览部署
rabetbase bff push --type ENDPOINT --name myFeature --dry-run
# 4. 确认无误后实际部署(交互模式下会弹出确认)
rabetbase bff push --type ENDPOINT --name myFeatureScenario 3: safe configuration in CI/CD pipelines
# .gitlab-ci.yml
deploy:
script:
# riskLevel 已在 .rabetbase.json 中预设为 high-risk-write
# 该文件由人类审核后提交,AI Agent 无法通过 CLI 动态提权
- rabetbase bff push --type ENDPOINT --name "$BFF_NAME" --yes --non-interactiveIn CI, CI=true is set automatically by GitLab/GitHub, and the CLI enters non-interactive mode automatically. High-risk operations must carry --yes. riskLevel should be preset in the CI environment's config file rather than modified dynamically in scripts.
FAQ
Q: Why can't riskLevel be changed with rabetbase config set? To prevent AI Agents or automation scripts from escalating their own privileges. If the CLI could change it, an Agent would need a single command to go from write to high-risk-write, bypassing every protection. Requiring manual config edits ensures only humans with direct filesystem access can change permissions.
Q: What is the default riskLevel? high-risk-write (unrestricted). Dev mode targets developers who operate frequently. To restrict it, set it manually in the config file.
Q: What should an AI Agent do when it hits insufficient permissions? The Agent should ask a human to manually edit .rabetbase.json and set riskLevel to the required level. The Agent itself should not — and cannot — change this config.
Q: How do I set different riskLevels for different environments in a multi-app config? Set riskLevel per profile in the apps section of .rabetbase.json. Recommended: write for the production profile, high-risk-write for daily.
Q: Which commands are high-risk-write? Commands that overwrite live runtime resources, delete platform metadata, bulk-update live menu resources, or delete local app profiles — for example bff push/delete, sql push/delete, dataset delete/link-delete, menu update, db delete, and app remove.
Q: How do I quickly check the current riskLevel?
rabetbase config get --key riskLevelKey takeaways
- riskLevel has three levels: read < write < high-risk-write
- Config precedence: riskLevel in an app profile > top-level config > default (high-risk-write)
- Four layers of CLI security: manual setting → riskLevel blocking → high-risk confirmation → dry-run preview
- For AI Agent scenarios, set the production profile to write to prevent accidental pushes
- In CI, preset riskLevel in the config file; high-risk operations must carry --yes