Add cerbos app

Maintainer-workflow: appstore-pr-maintainer
This commit is contained in:
okxlin
2026-07-15 05:29:02 +08:00
parent 85bed915f0
commit 5dfd3185e0
19 changed files with 435 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
PANEL_APP_PORT_HTTP=3592
PANEL_APP_PORT_GRPC=3593
APP_DATA_DIR=./data
CONTAINER_NAME=cerbos
+52
View File
@@ -0,0 +1,52 @@
additionalProperties:
formFields:
- default: 3592
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP API Port
labelZh: HTTP API 端口
label:
en: HTTP API Port
zh: HTTP API 端口
zh-Hant: HTTP API 連接埠
ja: HTTP API ポート
ko: HTTP API 포트
ru: Порт HTTP API
ms: Port API HTTP
pt-br: Porta da API HTTP
required: true
rule: paramPort
type: number
- default: 3593
edit: true
envKey: PANEL_APP_PORT_GRPC
labelEn: gRPC API Port
labelZh: gRPC API 端口
label:
en: gRPC API Port
zh: gRPC API 端口
zh-Hant: gRPC API 連接埠
ja: gRPC API ポート
ko: gRPC API 포트
ru: Порт gRPC API
ms: Port API gRPC
pt-br: Porta da API gRPC
required: true
rule: paramPort
type: number
- default: ./data
edit: true
envKey: APP_DATA_DIR
labelEn: Data Directory
labelZh: 数据目录
label:
en: Data Directory
zh: 数据目录
zh-Hant: 資料目錄
ja: データディレクトリ
ko: 데이터 디렉터리
ru: Каталог данных
ms: Direktori Data
pt-br: Diretório de dados
required: true
type: text
View File
+26
View File
@@ -0,0 +1,26 @@
services:
cerbos:
image: "cerbos/cerbos:0.53.0"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:3592"
- "${PANEL_APP_PORT_GRPC}:3593"
environment:
- CERBOS_NO_TELEMETRY=1
volumes:
- "${APP_DATA_DIR}/policies:/policies"
healthcheck:
test: ["CMD", "/cerbos", "healthcheck"]
interval: 10s
timeout: 2s
start_period: 10s
retries: 5
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
View File
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
fail() {
printf '%s\n' "$1" >&2
exit 1
}
strip_matching_quotes() {
local value="$1"
if [[ ${#value} -ge 2 ]]; then
if [[ "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
value="${value:1:${#value}-2}"
elif [[ "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
value="${value:1:${#value}-2}"
fi
fi
printf '%s\n' "$value"
}
read_env_value() {
local key="$1"
local value=""
if [[ -f "$ENV_FILE" ]]; then
value="$(grep -E "^${key}=" "$ENV_FILE" | tail -n 1 | cut -d '=' -f 2- || true)"
fi
strip_matching_quotes "$value"
}
path_is_dotenv_safe() {
local value="$1"
case "$value" in
*$'\n'* | *$'\r'* | *\\* | *'$'* | *'#'* | *'"'* | *"'"*) return 1 ;;
*) return 0 ;;
esac
}
[[ -f "$ENV_FILE" ]] || fail "$ENV_FILE not found"
[[ ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must not be a symbolic link"
if [[ ${APP_DATA_DIR+x} ]]; then
APP_DATA_DIR_RAW="$APP_DATA_DIR"
else
APP_DATA_DIR_RAW="$(read_env_value APP_DATA_DIR)"
fi
APP_DATA_DIR_RAW="$(strip_matching_quotes "${APP_DATA_DIR_RAW:-./data}")"
[[ -n "$APP_DATA_DIR_RAW" ]] || fail "APP_DATA_DIR must not be empty"
path_is_dotenv_safe "$APP_DATA_DIR_RAW" || fail "APP_DATA_DIR contains unsupported dotenv characters"
case "$APP_DATA_DIR_RAW" in
/*)
APP_DATA_DIR_ABS="$(realpath -m -- "$APP_DATA_DIR_RAW")"
;;
*)
APP_DATA_DIR_ABS="$(realpath -m -- "${ROOT_DIR}/${APP_DATA_DIR_RAW#./}")"
case "$APP_DATA_DIR_ABS" in
"${ROOT_DIR}" | "${ROOT_DIR}"/*) ;;
*) fail "Relative APP_DATA_DIR must stay inside the application directory" ;;
esac
;;
esac
[[ "$APP_DATA_DIR_ABS" != "/" ]] || fail "APP_DATA_DIR must not be the filesystem root"
if [[ -e "$APP_DATA_DIR_ABS" && ! -d "$APP_DATA_DIR_ABS" ]]; then
fail "APP_DATA_DIR must be a directory"
fi
POLICY_DIR="${APP_DATA_DIR_ABS}/policies"
[[ ! -L "$POLICY_DIR" ]] || fail "Cerbos policy directory must not be a symbolic link"
if [[ -e "$POLICY_DIR" && ! -d "$POLICY_DIR" ]]; then
fail "Cerbos policy path must be a directory"
fi
mkdir -p -- "$POLICY_DIR"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
if command -v docker-compose >/dev/null 2>&1; then
docker-compose down --volumes --remove-orphans
else
docker compose down --volumes --remove-orphans
fi
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
exec bash "${SCRIPT_DIR}/init.sh"
+54
View File
@@ -0,0 +1,54 @@
# Cerbos
## 产品介绍
Cerbos 是一个开源的策略决策点(PDP),用于把应用中的授权规则集中定义为 YAML 策略,并通过 HTTP 或 gRPC API 返回访问决策。
## 主要功能
- 使用资源策略、派生角色和主体策略表达 RBAC/ABAC 规则
- 提供 HTTP 与 gRPC 授权决策 API
- 监听策略目录变更并自动重新加载磁盘策略
- 提供内置 API 浏览器、健康检查与策略编译工具
## 访问说明
- HTTP API 和内置 API 浏览器默认使用 `3592` 端口。
- gRPC API 默认使用 `3593` 端口。
- Cerbos 不是用户登录系统,也不提供业务管理后台;业务应用需要通过 SDK、HTTP 或 gRPC 调用授权接口。
- 授权接口不应直接暴露到不受信任的公网。建议通过防火墙、内网或反向代理限制访问范围。
## 策略与安全
- 本应用使用 Cerbos 官方镜像的默认磁盘存储配置,把安装表单选择目录下的 `policies` 子目录挂载到容器 `/policies`
- 初始策略目录为空时服务可以正常启动,但没有匹配策略的请求会被拒绝。请按官方格式为每个策略创建独立的 YAML 或 JSON 文件。
- 匿名遥测通过 `CERBOS_NO_TELEMETRY=1` 默认关闭。
- 默认配置未启用 Cerbos Admin API,也不联动 1Panel 数据库、Redis 或网站 Runtime。
- 如需 Git、数据库、Cerbos Hub、审计日志或 Admin API 存储驱动,应在独立测试后自定义配置,不应直接复用本包的默认磁盘模式结论。
## 升级说明
- 升级前备份完整数据目录,尤其是 `policies` 子目录。
- 固定版与 `latest` 使用相同的策略挂载路径,可通过 1Panel 执行跨版本升级。
- 发布前应先使用 `cerbos compile` 或测试套件检查策略,并阅读目标版本的升级说明;策略语义变化需要人工审查。
## Introduction
Cerbos is an open-source policy decision point for application authorization. This package runs the official image as one service, exposes the HTTP and gRPC APIs, and persists disk-backed policies under the selected data directory.
## Features
- YAML/JSON policies for RBAC and ABAC authorization decisions
- HTTP and gRPC decision APIs
- Automatic reload of disk-backed policy changes
- Official binary health check and telemetry disabled by default
Back up the policy directory before upgrades. Keep the decision APIs on a trusted network, and validate policies against the target Cerbos release before production rollout.
## 参考资料
- 容器安装:<https://docs.cerbos.dev/cerbos/latest/installation/container.html>
- 快速开始:<https://docs.cerbos.dev/cerbos/latest/quickstart.html>
- 配置参考:<https://docs.cerbos.dev/cerbos/latest/configuration/index.html>
- 源码仓库:<https://github.com/cerbos/cerbos>
- 官方镜像:<https://hub.docker.com/r/cerbos/cerbos>
+31
View File
@@ -0,0 +1,31 @@
name: Cerbos
tags:
- 安全
title: 面向应用的开源策略授权决策服务
description: 面向应用的开源策略授权决策服务
additionalProperties:
key: cerbos
name: Cerbos
tags:
- Security
shortDescZh: 面向应用的开源策略授权决策服务
shortDescEn: An open-source policy decision service for application authorization
description:
en: An open-source policy decision service for application authorization
zh: 面向应用的开源策略授权决策服务
zh-Hant: 面向應用程式的開源策略授權決策服務
ja: アプリケーション認可向けのオープンソースポリシー決定サービス
ko: 애플리케이션 권한 부여를 위한 오픈 소스 정책 결정 서비스
ru: Сервис принятия решений по политикам с открытым исходным кодом для авторизации приложений
ms: Perkhidmatan keputusan dasar sumber terbuka untuk kebenaran aplikasi
pt-br: Serviço de decisão de políticas de código aberto para autorização de aplicações
type: middleware
crossVersionUpdate: true
limit: 0
recommend: 0
website: https://cerbos.dev/
github: https://github.com/cerbos/cerbos
document: https://docs.cerbos.dev/cerbos/latest/
architectures:
- amd64
- arm64
+4
View File
@@ -0,0 +1,4 @@
PANEL_APP_PORT_HTTP=3592
PANEL_APP_PORT_GRPC=3593
APP_DATA_DIR=./data
CONTAINER_NAME=cerbos
+52
View File
@@ -0,0 +1,52 @@
additionalProperties:
formFields:
- default: 3592
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP API Port
labelZh: HTTP API 端口
label:
en: HTTP API Port
zh: HTTP API 端口
zh-Hant: HTTP API 連接埠
ja: HTTP API ポート
ko: HTTP API 포트
ru: Порт HTTP API
ms: Port API HTTP
pt-br: Porta da API HTTP
required: true
rule: paramPort
type: number
- default: 3593
edit: true
envKey: PANEL_APP_PORT_GRPC
labelEn: gRPC API Port
labelZh: gRPC API 端口
label:
en: gRPC API Port
zh: gRPC API 端口
zh-Hant: gRPC API 連接埠
ja: gRPC API ポート
ko: gRPC API 포트
ru: Порт gRPC API
ms: Port API gRPC
pt-br: Porta da API gRPC
required: true
rule: paramPort
type: number
- default: ./data
edit: true
envKey: APP_DATA_DIR
labelEn: Data Directory
labelZh: 数据目录
label:
en: Data Directory
zh: 数据目录
zh-Hant: 資料目錄
ja: データディレクトリ
ko: 데이터 디렉터리
ru: Каталог данных
ms: Direktori Data
pt-br: Diretório de dados
required: true
type: text
View File
+26
View File
@@ -0,0 +1,26 @@
services:
cerbos:
image: "cerbos/cerbos:latest"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:3592"
- "${PANEL_APP_PORT_GRPC}:3593"
environment:
- CERBOS_NO_TELEMETRY=1
volumes:
- "${APP_DATA_DIR}/policies:/policies"
healthcheck:
test: ["CMD", "/cerbos", "healthcheck"]
interval: 10s
timeout: 2s
start_period: 10s
retries: 5
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
View File
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
fail() {
printf '%s\n' "$1" >&2
exit 1
}
strip_matching_quotes() {
local value="$1"
if [[ ${#value} -ge 2 ]]; then
if [[ "${value:0:1}" == '"' && "${value: -1}" == '"' ]]; then
value="${value:1:${#value}-2}"
elif [[ "${value:0:1}" == "'" && "${value: -1}" == "'" ]]; then
value="${value:1:${#value}-2}"
fi
fi
printf '%s\n' "$value"
}
read_env_value() {
local key="$1"
local value=""
if [[ -f "$ENV_FILE" ]]; then
value="$(grep -E "^${key}=" "$ENV_FILE" | tail -n 1 | cut -d '=' -f 2- || true)"
fi
strip_matching_quotes "$value"
}
path_is_dotenv_safe() {
local value="$1"
case "$value" in
*$'\n'* | *$'\r'* | *\\* | *'$'* | *'#'* | *'"'* | *"'"*) return 1 ;;
*) return 0 ;;
esac
}
[[ -f "$ENV_FILE" ]] || fail "$ENV_FILE not found"
[[ ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must not be a symbolic link"
if [[ ${APP_DATA_DIR+x} ]]; then
APP_DATA_DIR_RAW="$APP_DATA_DIR"
else
APP_DATA_DIR_RAW="$(read_env_value APP_DATA_DIR)"
fi
APP_DATA_DIR_RAW="$(strip_matching_quotes "${APP_DATA_DIR_RAW:-./data}")"
[[ -n "$APP_DATA_DIR_RAW" ]] || fail "APP_DATA_DIR must not be empty"
path_is_dotenv_safe "$APP_DATA_DIR_RAW" || fail "APP_DATA_DIR contains unsupported dotenv characters"
case "$APP_DATA_DIR_RAW" in
/*)
APP_DATA_DIR_ABS="$(realpath -m -- "$APP_DATA_DIR_RAW")"
;;
*)
APP_DATA_DIR_ABS="$(realpath -m -- "${ROOT_DIR}/${APP_DATA_DIR_RAW#./}")"
case "$APP_DATA_DIR_ABS" in
"${ROOT_DIR}" | "${ROOT_DIR}"/*) ;;
*) fail "Relative APP_DATA_DIR must stay inside the application directory" ;;
esac
;;
esac
[[ "$APP_DATA_DIR_ABS" != "/" ]] || fail "APP_DATA_DIR must not be the filesystem root"
if [[ -e "$APP_DATA_DIR_ABS" && ! -d "$APP_DATA_DIR_ABS" ]]; then
fail "APP_DATA_DIR must be a directory"
fi
POLICY_DIR="${APP_DATA_DIR_ABS}/policies"
[[ ! -L "$POLICY_DIR" ]] || fail "Cerbos policy directory must not be a symbolic link"
if [[ -e "$POLICY_DIR" && ! -d "$POLICY_DIR" ]]; then
fail "Cerbos policy path must be a directory"
fi
mkdir -p -- "$POLICY_DIR"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
if command -v docker-compose >/dev/null 2>&1; then
docker-compose down --volumes --remove-orphans
else
docker compose down --volumes --remove-orphans
fi
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
exec bash "${SCRIPT_DIR}/init.sh"
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB