Skip to content

Commit 63e5dfc

Browse files
coopernetesclaude
andcommitted
docs: overhaul README with getting started, current features, and roadmap links
- Fix module names (jgit-proxy-server/jgit-proxy-dashboard, not jgit-proxy-jetty/jgit-proxy-spring) - Add Getting Started section: clone, build, run server, run dashboard, configure - Add Proxy Modes URL explanation and both mode descriptions - Add Validation Features table reflecting implemented capabilities - Add Roadmap section linking the four design/tracking gists - Remove stale demo GIFs (to be re-recorded) - Remove references to non-existent CONFIGURATION.md in jgit-proxy-jetty Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 895c218 commit 63e5dfc

1 file changed

Lines changed: 147 additions & 71 deletions

File tree

README.md

Lines changed: 147 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,162 @@
11
[![CI](https://github.com/coopernetes/jgit-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/coopernetes/jgit-proxy/actions/workflows/ci.yml)
22
[![CVE Scanning](https://github.com/coopernetes/jgit-proxy/actions/workflows/cve.yml/badge.svg)](https://github.com/coopernetes/jgit-proxy/actions/workflows/cve.yml)
33

4-
# git-proxy in Java
5-
This is a simple implementation of a git proxy in Java. This is a possible successor to [finos/git-proxy](https://github.com/finos/git-proxy) which is written in Node.
4+
# jgit-proxy
65

7-
## Project Structure
6+
A Java-based git proxy implementing the same compliance and security controls as [finos/git-proxy](https://github.com/finos/git-proxy). Designed for OSS contribution gateways (employees in regulated industries contributing code to public upstream repos) and private-to-private code exchange (M&A scenarios between two or more git providers). Built on [JGit](https://github.com/eclipse-jgit/jgit), [Jetty](https://github.com/jetty/jetty.project) and [Spring](https://spring.io/).
7+
8+
## Getting Started
9+
10+
### Prerequisites
11+
12+
- Java 21+
13+
- Gradle (wrapper included)
14+
15+
### Clone and build
16+
17+
```shell
18+
git clone https://github.com/coopernetes/jgit-proxy.git
19+
cd jgit-proxy
20+
./gradlew build
21+
```
22+
23+
### Run the proxy server
24+
25+
The standalone proxy server (no dashboard, no management API) listens on port 8080 by default:
26+
27+
```shell
28+
./gradlew :jgit-proxy-server:run
29+
```
30+
31+
Logs are written to `jgit-proxy-server/logs/application.log`. Stop with:
832

9-
This project is a multi-module Gradle project:
33+
```shell
34+
./gradlew :jgit-proxy-server:stop
35+
```
1036

11-
### jgit-proxy-core
12-
Shared library containing all proxy logic:
13-
- Servlet filters for the transparent proxy path (`/proxy/...`)
14-
- Store-and-forward push pipeline using JGit ReceivePack hooks (`/push/...`)
15-
- Provider interfaces and implementations (GitHub, GitLab, Bitbucket)
16-
- Push audit store abstraction with JDBC and MongoDB backends
17-
- Git protocol utilities and commit inspection
37+
### Run the dashboard application
1838

19-
### jgit-proxy-jetty
20-
Standalone Jetty server — the primary runnable module. No Spring dependency.
39+
The dashboard module adds a Spring MVC web UI and REST API for reviewing and approving blocked pushes:
2140

2241
```shell
23-
./gradlew :jgit-proxy-jetty:run
24-
./gradlew :jgit-proxy-jetty:stop
42+
./gradlew :jgit-proxy-dashboard:run
2543
```
2644

27-
### jgit-proxy-spring
28-
Placeholder for a future Spring Boot variant.
45+
Open `http://localhost:8080/` in a browser to access the approval dashboard. Stop with:
46+
47+
```shell
48+
./gradlew :jgit-proxy-dashboard:stop
49+
```
50+
51+
### Configure the proxy
52+
53+
Configuration is YAML-based. Copy `git-proxy.yml` from `jgit-proxy-server/src/main/resources/` and create `git-proxy-local.yml` in the same directory (or `/app/conf/` for Docker). The local file takes priority over the bundled defaults.
54+
55+
Minimal example — allow pushes to a specific GitHub repo:
56+
57+
```yaml
58+
server:
59+
port: 8080
60+
61+
database:
62+
type: h2-mem # default; data lost on restart
63+
64+
git-proxy:
65+
providers:
66+
github:
67+
enabled: true
68+
69+
filters:
70+
whitelists:
71+
- enabled: true
72+
order: 1100
73+
operations: [FETCH, PUSH]
74+
providers: [github]
75+
slugs:
76+
- owner/repo
77+
```
78+
79+
Environment variable overrides use the `GITPROXY_` prefix:
80+
- `GITPROXY_SERVER_PORT=9090`
81+
- `GITPROXY_PROVIDERS_GITHUB_ENABLED=false`
2982

3083
## Proxy Modes
3184

85+
### URLs
86+
87+
jgit-proxy is capable of proxying arbitrary & multiple upstream Git repositories over HTTPS. For each upstream provider (for example, https://github.com & https://gitlab.com), a distinct URL is mapped for proxying by hostname. The remainder of the URL is the specific git repository you wish to connect to. For example:
88+
89+
- Original repository: https://github.com/finos/git-proxy
90+
- Proxy: http[s]://{jgit-proxy-server}/{proxy,push*}/github.com/finos/git-proxy
91+
92+
This makes it simple for a developer to simply add a new [git remote](https://git-scm.com/docs/git-remote) and start pushing code through jgit-proxy.
93+
94+
```
95+
git clone https://github.com/finos/git-proxy && cd git-proxy
96+
git remote add proxy http://localhost:8080/push/github.com/finos/git-proxy
97+
```
98+
99+
> \*Note: the base URL determines which proxying mode is in use. See below for details.
100+
32101
### Transparent proxy (`/proxy/<host>/...`)
33-
HTTP request is forwarded to the upstream Git server. Servlet filters validate commits inline and reject the push before it reaches the upstream. Client receives a git sideband error message.
102+
103+
HTTP requests are forwarded to the upstream Git server via Jetty's `ProxyServlet`. A servlet filter chain validates commits inline and rejects the push with a git client error before it reaches the upstream. It is designed for simple proxying usage where immediate feedback is preferred and clients re-push upon resolving any validation failures.
34104
35105
```shell
36106
git clone http://localhost:8080/proxy/github.com/owner/repo.git
37107
git push http://localhost:8080/proxy/github.com/owner/repo.git
38108
```
39109

40-
### Store-and-forward push (`/push/<host>/...`)
41-
Push objects are received locally using JGit's `ReceivePack`. A hook chain validates the commits and streams real-time feedback via git sideband before forwarding to the upstream. Each state transition is persisted as an event-log entry.
110+
### Store-and-forward (`/push/<host>/...`)
111+
112+
Push objects are received locally using JGit's `ReceivePack`. A hook chain validates commits and streams real-time progress via git sideband (with real-time feedback and a nicer UX in the terminal with emoji & ANSI color support) before forwarding to the upstream. Each state transition is persisted as an event-log entry in the configured database.
42113

43114
```shell
44115
git clone http://localhost:8080/push/github.com/owner/repo.git
45116
git push http://localhost:8080/push/github.com/owner/repo.git
46117
```
47118

119+
## Validation Features
120+
121+
Both proxy modes enforce the same set of configurable validation rules:
122+
123+
| Feature | Status |
124+
|---------|--------|
125+
| Repository allowlist (owner/slug) | Implemented |
126+
| Author email domain allow/block list | Implemented |
127+
| Commit message validation (literal + regex) | Implemented |
128+
| Diff generation | Implemented |
129+
| Diff content scanning | Implemented |
130+
| Aggregate failure reporting (all errors at once) | Implemented |
131+
| GPG/SSH commit signature verification | Implemented |
132+
| Approval gate with full lifecycle (RECEIVED → APPROVED → FORWARDED) | Implemented |
133+
| Real-time sideband progress with ANSI color | Implemented |
134+
135+
## Configuration
136+
137+
This is currently a work in progress. Similar to git-proxy, it's intended that jgit-proxy's validation & filtering functionality is fully configurable to match each organization's requirements. While certain functions are not configurable (such as parsing git payloads, enforcing git clients & setting request attributes), all the "security business logic" is intended to be fully customizable.
138+
139+
It is part of the roadmap that these features can be externalized in multiple ways such as integrating with external APIs for approval flows, configurable and pluggable sources for permitted users/repositories/providers and other core features.
140+
141+
You can find the [current documentation here](jgit-proxy-server/CONFIGURATION.md) but just know it is still under active development.
142+
48143
## Push Audit Database
49144

50-
All pushes through the store-and-forward path are recorded as an event log. Each state transition (RECEIVED → APPROVED → FORWARDED, or BLOCKED/ERROR) is written as a separate row, enabling full push history and reporting.
145+
All pushes through the store-and-forward path are recorded as an event log. Each state transition (RECEIVED → APPROVED → FORWARDED, or BLOCKED/ERROR) is written as a separate row, enabling full push history and audit reporting.
51146

52147
### Supported backends
53148

54149
| Type | Config value | Notes |
55150
|------|-------------|-------|
56-
| In-memory (simple) | `memory` | No SQL schema, data lost on restart |
151+
| In-memory | `memory` | No SQL schema, data lost on restart |
57152
| H2 in-memory | `h2-mem` | SQL schema, data lost on restart. Default. |
58153
| H2 file | `h2-file` | Persistent, zero external dependencies |
59154
| SQLite | `sqlite` | Persistent, zero external dependencies |
60155
| PostgreSQL | `postgres` | Production-grade |
61-
| MongoDB | `mongo` | Compatible with git-proxy Node.js data model |
156+
| MongoDB | `mongo` | Compatible with finos/git-proxy data model |
62157

63158
### Database configuration
64159

65-
Set in `git-proxy.yml` (or override in `git-proxy-local.yml`):
66-
67160
```yaml
68161
# H2 in-memory (default)
69162
database:
@@ -102,76 +195,59 @@ docker compose up -d postgres # port 5432, Adminer on 8082
102195
docker compose up -d mongo # port 27017, Mongo Express on 8081
103196
```
104197

105-
## Configuration
106-
107-
### Jetty Module
108-
YAML-based configuration loaded from `git-proxy.yml` and `git-proxy-local.yml` (local file takes priority):
109-
110-
```yaml
111-
server:
112-
port: 8080
198+
## Project Structure
113199

114-
database:
115-
type: h2-mem
200+
This is a multi-module Gradle project:
116201

117-
git-proxy:
118-
providers:
119-
github:
120-
enabled: true
121-
gitlab:
122-
enabled: true
123-
bitbucket:
124-
enabled: true
202+
| Module | Purpose |
203+
|--------|---------|
204+
| `jgit-proxy-core` | Shared library: filter chain, JGit hooks, push store, provider model, approval abstraction |
205+
| `jgit-proxy-server` | Standalone proxy-only server — no dashboard, no Spring |
206+
| `jgit-proxy-dashboard` | Dashboard + REST API — Spring MVC, approval UI, depends on `jgit-proxy-server` |
125207

126-
filters:
127-
whitelists:
128-
- enabled: true
129-
order: 1100
130-
operations: [FETCH, PUSH]
131-
providers: [github]
132-
slugs:
133-
- owner/repo
134-
```
208+
## Roadmap
135209

136-
Environment variable overrides use the `GITPROXY_` prefix:
137-
- `GITPROXY_SERVER_PORT=9090`
138-
- `GITPROXY_PROVIDERS_GITHUB_ENABLED=false`
210+
The following gists track the project's direction and open design questions:
139211

140-
See [`jgit-proxy-jetty/CONFIGURATION.md`](jgit-proxy-jetty/CONFIGURATION.md) for full configuration reference.
212+
| Document | Description |
213+
|----------|-------------|
214+
| [Project vision & design](https://gist.github.com/coopernetes/d02d48efa759282ff8187da0d5dcae64) | High-level goals and priority tracks: sideband streaming UX, checkpoint-based resumption, lifecycle hooks, DAG pipeline execution, SCM OAuth integration, SSH support |
215+
| [Implementation progress](https://gist.github.com/coopernetes/3a6c83690164a8a60a10524ef24e35eb) | Feature-by-feature comparison against finos/git-proxy with current status (implemented / in-progress / gap) |
216+
| [Framework rationale](https://gist.github.com/coopernetes/626541b83a148f4ae21ae2c62c57edea) | Why Java/Jetty + JGit over Node.js/Express: native git protocol handling, in-process pack inspection, sideband streaming |
217+
| [JGit server-side abstractions](https://gist.github.com/coopernetes/96ce03ca5795ca9dc78367f064c20596) | Reference guide for `RepositoryResolver`, `ReceivePackFactory`, and pre/post-receive hooks — the building blocks of the store-and-forward pipeline |
141218

142219
## Development
143220

144-
### Building
145-
```shell
146-
./gradlew build
147-
./gradlew :jgit-proxy-jetty:build
148-
```
221+
### Build
149222

150-
### Running
151223
```shell
152-
./gradlew :jgit-proxy-jetty:run # starts server (PID tracked for stop)
153-
./gradlew :jgit-proxy-jetty:stop # graceful stop via PID file
224+
./gradlew build # compile + unit tests
225+
./gradlew spotlessApply # fix formatting (palantir-java-format)
154226
```
155227

156228
### Integration tests
157229

158-
Test scripts in the repo root exercise both proxy modes end-to-end. They require a running server and a `~/.github-pat` file with a GitHub personal access token.
230+
Test scripts in the repo root exercise both proxy modes end-to-end against a running server. They require a `~/.github-pat` file with a GitHub personal access token.
159231

160232
```shell
161233
# Store-and-forward mode
162234
bash test-push-pass.sh # pushes that should succeed
163-
bash test-push-fail.sh # pushes that should be rejected by validation
235+
bash test-push-fail.sh # pushes that should be rejected
164236
165237
# Transparent proxy mode
166238
bash test-proxy-pass.sh
167239
bash test-proxy-fail.sh
168240
```
169241

170-
## Demo
242+
### E2E tests (Docker/Podman required)
171243

172-
![demo 1](./static/jgit-proxy-demo.gif)
244+
```shell
245+
./gradlew e2eTest
246+
```
173247

174-
![demo 2](./static/jgit-proxy-demo2.gif)
248+
### Docker Compose
175249

176-
Running the server
177-
![demo 3](./static/jgit-proxy-demo3.gif)
250+
```shell
251+
docker compose up -d # jgit-proxy + Gitea (h2-mem database)
252+
bash docker/setup.sh # one-time: create admin user + test repo in Gitea
253+
```

0 commit comments

Comments
 (0)