GitProxy 2.3 配置参数详解
逐键拆解 GitProxy 2.3 的 proxy.config.json:端口、会话与安全、推送检查规则、审批问卷、仓库白名单、存储后端、SCM 供应商与 TLS,每个参数均附真实修改与验证回显。
GitProxy 2.3 配置参数详解
目标:逐项讲清 GitProxy v2.3.0 的
proxy.config.json参数体系(服务监听、会话安全、限流、三类推送策略、审批问卷、仓库白名单、数据存储、插件链、TLS),每个关键参数都给出「修改 → 重启 → 实测验证」闭环回显。已在 Ubuntu 22.04(x86_64)+ GitProxy v2.3.0 实测通过。
GitProxy 是 FINOS 的 Git 推送审批网关,全部行为由单个 proxy.config.json 驱动:端口、账号体系、推送检查规则、审批问卷、仓库白名单、持久化后端都在这一个文件里。组件定位与架构见《GitProxy 2.3 介绍与选型指南》,从零部署见《GitProxy 2.3 Docker Compose 部署指南》;本篇面向已经跑起来的实例,回答「每个参数是什么、怎么改、改完怎么验证」。
一、环境信息
| 项目 | 取值 |
|---|---|
| 操作系统 | Ubuntu 22.04(x86_64) |
| GitProxy 版本 | v2.3.0 |
| 配置文件(服务器侧) | /opt/gitproxy-2.3/config/proxy.config.json |
| 配置文件(服务进程视角) | /app/proxy.config.json(启动日志 Setting config file to: 行所显示的路径) |
| 服务端口 | 8149(Git 代理 HTTP)、8150(管理台 HTTP)、8151(Git 代理 HTTPS)、8152(管理台 HTTPS) |
| 数据目录 | /opt/gitproxy-2.3/data/gitproxy/(挂载为服务进程的 /app/.data) |
| 演示账号 | admin / reviewer(密码均为 q1w2e3r4) |
| 上游 Git 服务 | Gitea 1.23.8(https://gitea.local:3000) |
服务启动日志(实测节选,展示配置加载全过程):
Configuration sources are disabled
Configuration loaded successfully
Setting config file to: /app/proxy.config.json
Validating config
Setting up the proxy and Service
Loading neDB database adaptor
No plugins configured
Found 0 plugin modules
Service Listening on 8150
HTTPS Service Listening on 8152
HTTP Proxy Listening on 8149
HTTPS Proxy Listening on 8151
Validating config 表示服务启动时会对配置文件做类型校验,Setting config file to: 后面的路径即服务进程实际加载的文件(服务器侧配置文件挂载后的运行时路径)。
二、前置条件
- 已按《GitProxy 2.3 Docker Compose 部署指南》完成部署,
GET /api/v1/healthcheck返回{"message":"ok"}; - 服务器侧配置文件可编辑(本篇演示环境位于
/opt/gitproxy-2.3/config/proxy.config.json); - 会用 curl 调用管理台 API(登录与 CSRF Token 获取流程见《GitProxy 2.3 常用 CLI 命令与 REST API 详解》);
- 修改配置前先备份:
cp proxy.config.json proxy.config.json.bak; - 能查看服务日志(排障与验证的主要证据来源)。
三、参数查看与修改方式
3.1 查看当前配置
配置就是服务器侧那个 JSON 文件,直接查看(实测命令与节选):
# 查看配置文件(节选前 20 行)
head -20 /opt/gitproxy-2.3/config/proxy.config.json
{
"cookieSecret": "gitproxy-2.3-demo-cookie-secret-2026",
"sessionMaxAgeHours": 12,
"serverPort": 8149,
"httpsServerPort": 8151,
"uiHost": "http://gitproxy.local:8150",
"uiPort": 8150,
"httpsUiPort": 8152,
"rateLimit": {
"windowMs": 60000,
"limit": 1000
},
"tempPassword": {
"sendEmail": false,
"emailConfig": {}
},
"authorisedList": [
{
"project": "admin",
"name": "hello-gitproxy",
管理台侧另有一组只读的运行时配置接口(/api/v1/config/ 前缀,无需登录会话):GET /api/v1/config/attestation 返回当前生效的审批问卷,GET /api/v1/config/scmProviders 返回 SCM 供应商清单,GET /api/v1/config/contactEmail(纯文本)、/api/v1/config/urlShortener 与 /api/v1/config/uiRouteAuth 同理。实测:
curl -s http://gitproxy.local:8150/api/v1/config/attestation
{"questions":[{"label":"I have checked every commit in this push","tooltip":{"text":"Please confirm you have checked every commit in this push","links":[]}},{"label":"I am authorised to make this push","tooltip":{"text":"Please confirm you are authorised to make this push","links":[]}}]}
用于核对「文件里写的」与「进程里跑的」关键项是否一致;完整配置仍以配置文件为准(访问不存在的子端点会落到管理台页面兜底路由,返回 HTML 而非 JSON)。
3.2 修改方式与生效时机
GitProxy v2.3.0 没有配置热加载端点。修改 JSON 后必须重启服务进程。实测:向热加载端点发请求会得到 404:
# 尝试热加载端点(v2.3.0 不存在该路由)
curl -s -X POST http://localhost:8150/api/v1/admin/reload-config
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /api/v1/admin/reload-config</pre>
</body>
</html>
标准的修改流程(每类参数的验证手段见对应小节):
编辑 proxy.config.json → 重启 GitProxy 服务进程 → curl 健康检查确认恢复 → 按参数类型做业务验证
⚠️ 注意:重启命令与部署形态有关(systemd 托管、Compose 部署等),本文不展开;具体命令见《GitProxy 2.3 Docker Compose 部署指南》。本文所有「重启后」的验证回显均来自真实重启后的服务。
重启完成后先做健康检查再验证业务(实测回显):
curl -s http://localhost:8150/api/v1/healthcheck
{"message":"ok"}
3.3 配置校验:改错值会怎样
服务启动时校验配置类型,非法值会让进程直接启动失败。实测把 serverPort 改成字符串 "abc" 后重启,进程立即报错退出(实测日志节选):
Error: Invalid value for key "serverPort" on GitProxyConfig. Expected an optional number but got "abc"
at invalidValue (/app/dist/src/config/generated/config.js:47:11)
at transformUnion (/app/dist/src/config/generated/config.js:101:16)
at transform (/app/dist/src/config/generated/config.js:161:15)
at cast (/app/dist/src/config/generated/config.js:174:12)
at Convert.toGitProxyConfig (/app/dist/src/config/generated/config.js:36:16)
at validate (/app/dist/src/config/file.js:45:22)
端口 8149 等待连接会失败、管理台 8150 无响应。处理:恢复备份或把值改回正确类型后重启。因此 3.2 节的备份一步不可省。
3.4 环境变量优先于配置文件
部分参数支持用环境变量覆盖,且优先级高于 JSON 文件。实测:配置文件 uiPort: 8150 不变,仅注入环境变量 GIT_PROXY_UI_PORT=8199 再启动服务进程,日志显示(实测回显):
Setting config file to: /app/dist/proxy.config.json
Validating config
Service Listening on 8199
HTTPS Service Listening on 8152
Service Listening on 8199 证明环境变量压过了配置文件的 8150(该次实验用临时实例验证,未改正式服务)。
⚠️ 注意:上例还暴露了一个易错点——没有显式传
--config启动参数时,服务读的是镜像内置默认路径/app/dist/proxy.config.json,而不是你挂载的配置文件。Compose 部署篇正是靠启动命令里的--config /app/proxy.config.json指定配置文件的。另实测环境变量CONFIG_FILE不改变该路径(日志依旧显示/app/dist/proxy.config.json),即CONFIG_FILE环境变量在 v2.3.0 无效,指定配置文件必须用--config命令行参数。
四、参数总览
按功能域分类(均为 v2.3.0 实际生效键,取自实测配置文件与启动校验):
| 功能域 | 键 | 本篇小节 |
|---|---|---|
| 服务监听 | serverPort、httpsServerPort、uiPort、httpsUiPort、uiHost | 5.1 |
| 会话与安全 | cookieSecret、sessionMaxAgeHours、csrfProtection、authentication、tempPassword | 5.2 |
| 请求限流 | rateLimit(windowMs/limit) | 5.3 |
| 推送策略-提交消息 | commitConfig.message.block(literals/patterns) | 5.4 |
| 推送策略-作者邮箱 | commitConfig.author.email(domain.allow/local.block) | 5.5 |
| 推送策略-diff 内容 | commitConfig.diff.block(literals/patterns) | 5.6 |
| 审批问卷 | attestationConfig.questions | 5.7 |
| 仓库白名单 | authorisedList、domains(对外地址)、privateOrganizations | 5.8、5.11 |
| 数据存储 | sink(fs/mongo/postgres) | 5.9 |
| 插件链 | plugins、api(api.gitleaks) | 5.10 |
| SCM 供应商 | scmProviders(github/gitlab/codeberg/gitea/local-gitea) | 5.12 |
| TLS | tls(enabled/key/cert)、ssh | 5.13 |
| 其他 | contactEmail、urlShortener、uiRouteAuth、sidebandProgress、upstreamProxy、configurationSources、apiAuthentication、cookieSecret | 5.14 |
💡 技术拓展:推送策略不止 GitProxy 内置的三类检查。业界同类方案对比——
方案 检查机制 扩展方式 GitProxy 内置 消息黑名单/作者邮箱/diff 扫描,纯规则即时判定 plugins自定义检查器服务端 pre-receive 钩子 仓库侧脚本,阻塞式 各仓库独立维护脚本 gitleaks 等外部扫描器 内容级密钥/凭据检测,能力更强 作为外部二进制被网关调用 GitProxy 的优势是把规则集中到网关一层、并叠加审批流;本篇 5.4–5.6 实测的即内置三类,5.10 演示插件与外部扫描器接入点。
五、核心参数分类详解
5.1 服务监听:serverPort / httpsServerPort / uiPort / httpsUiPort / uiHost
四个端口把「Git 代理」与「管理台」的 HTTP/HTTPS 流量分开:git push 走 8149/8151,人与 REST API 走 8150/8152。实测配置为 8149/8151/8150/8152,启动日志四行监听确认(见一节)。
修改-验证闭环:把 uiPort 改为 8250(其他不动),重启后验证(实测回显):
# 新端口健康检查
curl -s http://localhost:8250/api/v1/healthcheck
{"message":"ok"}
旧端口已无监听(实测回显):
curl -s -o /dev/null -w '%{http_code}\n' --connect-timeout 3 http://localhost:8150/api/v1/healthcheck
000
000 表示连接被拒绝(无监听),验证端口切换真实生效。服务器侧也可用 ss -ltn | grep -E '82|81' 复核监听清单。改完记得还原为 8150 并重启。
⚠️ 注意:
uiHost用于管理台对外地址的生成(审批分享链接等),镜像内置默认值为http://localhost。本篇部署环境取完整 URL 形式http://gitproxy.local:8150(与domains的对外地址一致,见 5.11 节);仅本机访问时可改127.0.0.1收窄暴露面,生产环境通常配合反向代理对外发布。各端口键还支持同名大写环境变量覆盖(如GIT_PROXY_UI_PORT),环境变量优先于配置文件。
5.2 会话与安全:cookieSecret / sessionMaxAgeHours / csrfProtection
cookieSecret:管理台会话 Cookie 的签名密钥(本文部署环境取值gitproxy-2.3-demo-cookie-secret-2026,为演示值),生产必须替换为独立随机串(openssl rand -hex 64生成);sessionMaxAgeHours: 12:会话有效期 12 小时,超时重新登录;csrfProtection: true:管理台所有写操作(POST/PUT/PATCH/DELETE)必须携带X-CSRF-Token请求头,Token 从GET /api/auth/csrf-token获取。
csrfProtection 的修改-验证闭环实测:true 时,不带 Token 直接 POST 登录会被拒(实测回显节选):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Forbidden</pre>
</body>
</html>
先取 Token 再 POST 则成功(实测回显):
{"message":"success","user":{"username":"admin","displayName":"","email":"admin@place.com","title":"","scmIdentities":{"local-gitea":"admin"},"admin":true}}
关闭 csrfProtection(改 false 重启)后,同样不带 Token 的 POST 直接成功。验证后恢复 true。
⚠️ 注意:GitProxy v2.3.0 的 CLI(
@finos/git-proxy-cli)未实现 CSRF 获取流程,csrfProtection: true时 CLI 登录实测返回Error: Login 'admin': '403'。需要用 CLI 的环境要么临时关掉该开关(用完恢复),要么改用 REST API(curl 流程自带 Token 获取,见《GitProxy 2.3 常用 CLI 命令与 REST API 详解》)。
5.3 请求限流:rateLimit
"rateLimit": {
"windowMs": 60000,
"limit": 1000
}
逐项说明:windowMs(统计窗口,毫秒)、limit(窗口内最大请求数,按来源地址计数)。默认 60 秒 1000 次;429 响应自带 X-RateLimit-* 与 Retry-After 响应头(见下方实测)。
修改-验证闭环:把 limit 改为 5 并重启,连续请求 7 次(实测回显,前 5 次正常、第 6 次起 429):
req1: 200
req2: 200
req3: 200
req4: 200
req5: 200
req6: 429
req7: 429
429 响应的完整头信息(实测回显节选):
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 54
Retry-After: 54
X-RateLimit-Limit: 5 证明新阈值生效,Retry-After: 54 告知客户端 54 秒后窗口重置。恢复 limit: 1000 并重启后同样请求回到 200。
⚠️ 注意:限流对象是「管理台 HTTP 服务」整体(含 API 与网页),Git 代理端口(8149/8151)不受该参数影响。生产建议保持 1000 以上,避免审批高峰误伤。
5.4 推送策略-提交消息:commitConfig.message.block
"message": {
"block": {
"literals": [],
"patterns": []
}
}
逐项说明:literals(禁止出现的完整字面量数组,按字符串精确匹配)、patterns(禁止出现的正则表达式数组)。检查范围覆盖所有提交与标签消息,命中任一即整次推送被拒。
literals 闭环实测:配置 literals: ["WIP"] 重启后,推送一条消息含 WIP 的提交(实测回显):
remote: Your push has been blocked.
remote: Please ensure your commit/tag message(s) does not contain sensitive information or URLs.
remote:
remote: The following messages are illegal: ["wip: WIP entry"]
remote:
To http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git
! [remote rejected] main -> main (rejected by GitProxy)
error: failed to push some refs to 'http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git'
消息 wip: WIP entry 因包含字面量 WIP 被精确命中。改用不含 WIP 的消息推送则正常进入审批队列(Checking commit messages... 后无报错)。
patterns 闭环实测:配置 patterns: ["^draft:"] 重启后,推送一条 draft: pattern probe 提交(实测回显):
remote: Your push has been blocked.
remote: The following messages are illegal: ["draft: pattern probe"]
! [remote rejected] main -> main (rejected by GitProxy)
正则 ^draft: 命中以 draft: 开头的消息。两类规则可叠加:命中任一即整次推送被拒。
⚠️ 注意:被拒的提交仍留在本地分支,删除或改写(
git commit --amend/git rebase -i)后重推即可。API 视角被拒推送的状态为error: true, allowPush: false(GET /api/v1/push/可查),不会出现在待审批列表。
5.5 推送策略-作者邮箱:commitConfig.author.email.domain
"author": {
"email": {
"local": {
"block": ""
},
"domain": {
"allow": ".*"
}
}
}
domain.allow 是邮箱域名的正则白名单(默认 .* 即不限制),local.block 是对邮箱 @ 前缀部分的黑名单正则(默认空即不拦截)。生产上常用 domain.allow 强制「提交必须使用公司邮箱」。验证确认提示可配合 contactEmail 生效。
修改-验证闭环:allow 改为 example\\.com$(只放行 example.com 域)重启,推送一条作者邮箱为 dev@corp.com 的提交(实测回显):
remote: Your push has been blocked. Please verify your Git configured e-mail address is valid (e.g. john.smith@example.com)
remote:
To http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git
! [remote rejected] main -> main (rejected by GitProxy)
error: failed to push some refs to 'http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git'
admin@example.com 的提交则正常通过检查(Checking author emails... 后无报错)。生产环境把 allow 设为如 company\\.com$ 即可强制公司邮箱。验证后恢复默认 .*。
5.6 推送策略-diff 内容:commitConfig.diff.block
"diff": {
"block": {
"literals": [],
"patterns": []
}
}
对本次推送的 diff 内容做字面量/正则黑名单扫描(scanDiff 步骤),是防止把密码、Token、内网地址写进代码的最后一道规则闸门。
修改-验证闭环:literals: ["SECRET_MARKER"] 重启后,推送一个内容含 SECRET_MARKER: supersecret 的文件(实测回显,输出节选):
remote: Your push has been blocked.
remote:
remote: Please ensure your code does not contain sensitive information or URLs.
remote:
remote: ---------------------------------- #1 Offending Literal ------------------------------
remote: Policy Exception Type: Offending Literal
remote: DETECTED: SECRET_MARKER
remote: FILE(S) LOCATED: s.txt
remote: Line(s) of code: 1
To http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git
! [remote rejected] main -> main (rejected by GitProxy)
error: failed to push some refs to 'http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git'
回显直接给出命中类型(Offending Literal)、命中字面量、所在文件与行号,定位非常直接。patterns 同理支持正则(如 BEGIN.*PRIVATE KEY 匹配私钥块)。
5.7 审批问卷:attestationConfig.questions
"attestationConfig": {
"questions": [
{
"label": "I have checked every commit in this push",
"tooltip": { "text": "Please confirm you have checked every commit in this push", "links": [] }
},
{
"label": "I am authorised to make this push",
"tooltip": { "text": "Please confirm you are authorised to make this push", "links": [] }
}
]
}
审批人批准推送时必须逐项勾选的确认问卷,tooltip 支持附说明与链接。关键约束:审批 API 提交的 label 必须与配置逐字一致,否则拒绝。
修改-验证闭环实测:审批 API 提交的 label 与配置不匹配时返回 400(实测回显):
Error: Authorise: '400': Attestation is not complete
把 label 逐字对齐后(如按 CLI 场景把问卷改为 Authorising via GitProxy CLI),同一请求返回成功(实测回显):
Authorise: ID: 'e8197a30ccdc247103b6c8b91007097c128c8228080fc36048e66149fb140abd': OK
⚠️ 注意:修改
questions后,未完成的旧推送按新问卷校验。生产环境调整问卷措辞时,先处理完队列里的待审批推送。
5.8 仓库白名单:authorisedList
"authorisedList": [
{
"project": "admin",
"name": "hello-gitproxy",
"url": "https://gitea.local:3000/admin/hello-gitproxy.git",
"proxyURL": "http://gitproxy.local:8149"
}
]
只有出现在白名单里的仓库才允许经网关推送。配置文件里的 authorisedList 在首次初始化时写入数据库;运行期的增删走 REST API(POST /api/v1/repo/),写入 repos.db 后即时生效,无需重启。
三段闭环实测:
- 推送一个不在白名单的仓库
second-repo,连 ref 协商阶段都被拒(git 客户端实测回显):
fatal: http://gitproxy.local:8149/gitea.local:3000/admin/second-repo.git/info/refs not valid: is this a git repository?
服务日志同步出现(实测节选):
Parse action fallback calculated repo URL: https://github.com/gitea.local:3000/admin/second-repo.git for inbound URL path: /gitea.local:3000/admin/second-repo.git/info/refs?service=git-receive-pack
checkRepoInAuthorisedList - repo https://github.com/gitea.local:3000/admin/second-repo.git is not in the authorised whitelist, ending
checkRepoInAuthorisedList - Rejecting repo https://github.com/gitea.local:3000/admin/second-repo.git not in the authorised whitelist
- 调
POST /api/v1/repo/把 second-repo 加入白名单(实测回显):
{"project":"admin","name":"second-repo","url":"https://gitea.local:3000/admin/second-repo.git","users":{"canPush":[],"canAuthorise":[]},"dateCreated":"2026-10-26T02:33:51.585Z","lastModified":"2026-10-26T02:33:51.585Z","_id":"eoe5s1nmyjFFmN71","proxyURL":"http://gitproxy.local:8149","message":"created"}
- 不重启直接重推:检查链推进到推送权限一步(白名单已放行,实测回显):
remote: Your push has been blocked (admin is not allowed to push on repo https://gitea.local:3000/admin/second-repo.git)
再调 PATCH /api/v1/repo/eoe5s1nmyjFFmN71/user/push 给 admin 加 canPush 后重推,全部检查通过并进入审批队列(Checking approval status... → Requesting approval...)。整条链验证了白名单「配置初始化 + API 动态生效」的双通道行为。
5.9 数据存储:sink
"sink": [
{
"type": "fs",
"enabled": true
},
{
"type": "mongo",
"connectionString": "mongodb://localhost:27017/gitproxy",
"options": { "tlsAllowInvalidCertificates": false },
"enabled": false
},
{
"type": "postgres",
"connectionString": "postgresql://localhost:5432/gitproxy",
"enabled": false
}
]
sink 是后端数组(type + enabled),决定推送审批记录、仓库与账号数据落在哪里。fs 即本地文件后端(NeDB),本篇环境 enabled: true,启动日志 Loading neDB database adaptor 确认加载。落盘验证(实测回显):
ls -la /opt/gitproxy-2.3/data/gitproxy/db/
total 124
drwxr-xr-x 2 root root 4096 Oct 26 10:52 .
drwxr-xr-x 4 root root 4096 Oct 26 09:29 ..
-rw-r--r-- 1 root root 20480 Oct 26 10:52 migrations.db
-rw-r--r-- 1 root root 36864 Oct 26 10:52 pushes.db
-rw-r--r-- 1 root root 12288 Oct 26 10:52 repos.db
-rw-r--r-- 1 root root 36864 Oct 26 10:52 users.db
四个文件各司其职:pushes.db(推送审批记录)、repos.db(白名单与授权矩阵)、users.db(账号)、migrations.db(迁移记录)。
💡 技术拓展:
sink支持三种后端,选型对比——
后端 特点 适用场景 fs(NeDB 文件) 零依赖、单机、直接备份目录 单节点部署、小团队(本文实测采用) mongo 独立 MongoDB,多实例共享 多副本/高并发审批 postgres 独立 PostgreSQL,事务与审计能力强 企业级部署、需 SQL 查询审计数据 切换方式:把对应数组项的
enabled改为true并补齐连接串(如 mongo 项的connectionString),其余后端保持false,重启生效;首次切换建议空库启动。
5.10 插件链:plugins 与 api.gitleaks
plugins 指向自定义检查插件的加载目录,空数组 [] 表示不加载。启动日志(实测回显):
No plugins configured
Found 0 plugin modules
插件的形态是「检查动作包」,加载后会被并入推送处理链(与内置的 checkMessages、checkAuthorEmails、scanDiff 等步骤串行执行),适合注入企业专属规则(如工单号校验)。
api.gitleaks 是外部扫描器接入点:
"api": {
"gitleaks": {
"enabled": true,
"ignoreGitleaksAllow": true,
"noColor": false
}
}
开启后推送链会多出 gitleaks 扫描步骤。实测开启并推送(服务日志实测回显):
gitleaks - Scanning range with gitleaks: 648a4ca...:243aa1d0... in ./.remote/.../second-repo.git
gitleaks - Failed to spawn gitleaks: spawn gitleaks ENOENT
spawn gitleaks ENOENT 说明运行环境缺少 gitleaks 二进制——镜像不内置该工具,需要自行安装后才能生效;未安装前保持 api 缺省(关闭),走 5.6 节的内置 diff 扫描即可。
5.11 对外地址:domains 与 privateOrganizations
"domains": {
"proxy": "http://gitproxy.local:8149",
"service": "http://gitproxy.local:8150"
}
domains 是对外地址覆盖(schema 描述:当 GitProxy 无法自判定对外 URL 时,用它自定义两个界面的地址):proxy 是网关(Git 代理)对外地址,service 是管理台对外地址。它们会被拼进推送被拦回显、审批分享链接等对外文案(5.4/5.8 节的 gitproxy.local 链接即由此生成)。本篇部署环境与 uiHost 保持一致。
注意它不是路由放行表。启动日志里的路由注册来源于 authorisedList 里各仓库 URL 的主机部分(实测回显):
Initializing proxy router for origins: '["gitea.local:3000"]'
setting up origin: 'gitea.local:3000'
setting up catch-all route (github.com) for backwards compatibility
proxy keys registered: ["/gitea.local:3000/"]
表外主机走 catch-all(github.com)回退并被白名单检查拦截(5.8 节实测)。新增上游 Git 服务只需调 POST /api/v1/repo/ 把仓库 URL 加入白名单(无需改 domains,5.8 节验证过即时生效)。
privateOrganizations(字符串数组)用于 GitHub 场景:列出后这些组织下的仓库推送会被强制额外校验,私有组织管控用,本篇环境无 GitHub 上游未启用。
5.12 SCM 供应商:scmProviders
"scmProviders": [
{ "name": "github", "type": "github", "host": "github.com" },
{ "name": "gitlab", "type": "gitlab", "host": "gitlab.com" },
{ "name": "codeberg", "type": "forgejo", "host": "codeberg.org" },
{ "name": "gitea", "type": "forgejo", "host": "gitea.com" },
{ "name": "local-gitea", "type": "forgejo", "host": "gitea.local",
"apiUrl": "https://gitea.local:3000/api/v1" }
]
管理台用它对接 SCM 供应商的 API,实现「推送人 ↔ SCM 账号」身份绑定(SCM Identity)。每项键为 name(身份键名)、type(供应商协议:github/gitlab/forgejo)、host(推送 URL 中的主机);对接自建 Gitea 时再加 apiUrl 指向其 REST API(如 local-gitea 项)。绑定成功后用户对象里出现对应身份(实测回显节选):
"scmIdentities":{"local-gitea":"admin"}
推送时网关据绑定关系把 GitProxy 用户映射到 SCM 凭据(服务日志 resolveUserFromToken - Mapped local-gitea:admin to git-proxy user 'admin')。未绑定身份的用户推送会在 Resolving user from token 阶段失败。管理台还提供只读的供应商清单接口 GET /api/v1/config/scmProviders(无需会话,见 3.1 节),返回同名清单(节选):
[{"name":"github","type":"github","host":"github.com"},{"name":"gitlab","type":"gitlab","host":"gitlab.com"},{"name":"codeberg","type":"forgejo","host":"codeberg.org"},{"name":"gitea","type":"forgejo","host":"gitea.com"},{"name":"local-gitea","type":"forgejo","host":"gitea.local"}]
5.13 TLS:tls 与 ssh
"tls": {
"enabled": true,
"key": "/app/certs/gitproxy.key",
"cert": "/app/certs/gitproxy.crt"
}
tls.enabled 打开后 8151/8152(HTTPS 端口)才真正提供 TLS 服务,证书路径为服务进程视角路径(对应服务器侧 certs/ 目录)。验证(实测回显):
curl -sk -o /dev/null -w '%{http_code}\n' https://localhost:8152/
200
ssh 键用于 SSH 协议推送的代理场景(ssh.enabled、port、knownHosts 等子键),本篇环境走 Smart HTTP 未启用;混合协议需求时参照官方 schema 同步开启。
5.14 其他常用参数
| 键 | 实测值 | 说明 |
|---|---|---|
contactEmail | admin@example.com | 推送被拦时回显里的联系邮箱(5.5 节回显中的提示语即含示例邮箱);另有 GET /api/v1/config/contactEmail 只读接口 |
tempPassword | {"sendEmail": false, "emailConfig": {}} | 临时密码/首次登录策略的邮件发送开关与邮件服务配置(本篇环境未接邮件服务,发送关闭) |
authentication | [{ "type": "local", "enabled": true }, …] | 登录方式数组;local 为内置账号密码(启用),ActiveDirectory、openidconnect 项预留且默认关闭 |
urlShortener | "" | 短链服务地址,把审批分享链接转短链,未启用 |
uiRouteAuth | {"enabled": false, "rules": [ … ]} | 管理台前端路由登录/管理员强校验规则表,enabled: false 未启用 |
sidebandProgress | true | 推送时把网关检查进度以 sideband 通道回传客户端(镜像默认即开启) |
upstreamProxy | {"enabled": false, …} | 网关访问上游 Git 服务时经过的出网代理(内网无直连场景),未启用 |
configurationSources | 禁用 | 外部配置源(HTTP/文件轮询),日志 Configuration sources are disabled 即它未启用 |
apiAuthentication | [{ "type": "jwt", "enabled": false, … }] | API 层 JWT 认证数组(机器对机器调用免会话的方案),未启用;启用前 REST 调用统一走登录会话(见 CLI 命令与 REST API 详解篇) |
六、生产配置模板
适用场景:单节点部署、50 人以下团队、内网自托管 Git(Gitea/GitLab),磁盘 ≥ 20GB(推送记录与临时 pack 会增长),内存 2GB 起步。在部署篇初始配置基础上做生产化收紧(关键差异逐条标注):
{
"cookieSecret": "<openssl rand -hex 64 生成的独立随机串>",
"sessionMaxAgeHours": 8,
"rateLimit": { "windowMs": 60000, "limit": 1000 },
"contactEmail": "gitproxy-admin@company.com",
"csrfProtection": true,
"authentication": [
{ "type": "local", "enabled": true }
],
"commitConfig": {
"message": { "block": { "literals": [], "patterns": [] } },
"author": { "email": { "local": { "block": "" }, "domain": { "allow": "company\\.com$" } } },
"diff": { "block": { "literals": ["SECRET_MARKER"], "patterns": ["BEGIN.*PRIVATE KEY"] } }
},
"authorisedList": [],
"sink": [
{ "type": "fs", "enabled": true }
],
"plugins": [],
"domains": {
"proxy": "https://gitproxy.company.com:8149",
"service": "https://gitproxy.company.com:8150"
},
"tls": { "enabled": true, "key": "/app/certs/gitproxy.key", "cert": "/app/certs/gitproxy.crt" }
}
模板要点:会话缩到 8 小时;作者邮箱强制公司域(domain.allow);diff 黑名单加私钥正则;authorisedList 留空、仓库全部走 API 动态授权(5.8 节验证过的即时生效通道);domains 换成公司对外域名(proxy 为网关地址、service 为管理台地址);cookieSecret 必换。serverPort 等端口键按部署篇保持一致,此处省略;登录方式、存储后端等数组键的完整形态见 5.14 节与部署篇。
七、常见问题(FAQ)
Q1:改了配置为什么不生效?
v2.3.0 无热加载(3.2 节 404 实测),必须重启服务进程。另外确认启动命令带了 --config 指向挂载的配置文件——否则进程读的是内置默认配置(3.4 节实测日志 Setting config file to: /app/dist/proxy.config.json 即此情形)。
Q2:服务起不来,日志报 Invalid value for key ... on GitProxyConfig?
配置类型校验失败(3.3 节实测,如 serverPort 传了字符串)。按报错里的键名回改类型,或直接用备份文件覆盖后重启。
Q3:POST /api/auth/login 返回 403 Forbidden?
csrfProtection: true 时所有写请求都要先 GET /api/auth/csrf-token 取 Token 并随 X-CSRF-Token 头提交(5.2 节实测对比)。CLI 用户见 5.2 节 ⚠️。
Q4:审批 API 返回 Attestation is not complete?
请求体里 params.attestation 数组的 label 必须与 attestationConfig.questions 逐字一致(5.7 节实测)。
Q5:推送报 Your push has been blocked (… is not allowed to push on repo …)?
账号不在该仓库 canPush 列表。用仓库 _id 调 PATCH /api/v1/repo/<id>/user/push 加授权即可(5.8 节实测回显 {"message":"created"})。
Q6:日志出现 spawn gitleaks ENOENT?
api.gitleaks.enabled=true 但运行环境没有 gitleaks 二进制(5.10 节实测)。安装 gitleaks 或关闭该开关走内置 diff 扫描。
Q7:多实例部署时 authorisedList 怎么管?
白名单持久化在 repos.db(5.9 节),API 增删对所有实例生效的前提是共享同一数据库后端;单机 fs 模式下实例间不共享,多实例请切换 sink 到 mongo/postgres。
八、参考链接
- GitProxy 官方文档(配置说明):https://finos.github.io/git-proxy/
- GitProxy 源码(配置定义):https://github.com/finos/git-proxy/tree/main/src/config
- GitProxy v2.3.0 Release:https://github.com/finos/git-proxy/releases/tag/v2.3.0
- 本系列姊妹篇:《GitProxy 2.3 介绍与选型指南》、《GitProxy 2.3 Docker Compose 部署指南》、《GitProxy 2.3 常用 CLI 命令与 REST API 详解》