Skip to content

Commit e97b57b

Browse files
committed
Add proxy cache filter proposal
Signed-off-by: stonezdj <stonezdj@gmail.com>
1 parent 1836be0 commit e97b57b

1 file changed

Lines changed: 153 additions & 0 deletions

File tree

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
Proposal: Limit proxy cache repositories by filter
2+
3+
Author: stonezdj
4+
5+
## Abstract
6+
7+
Harbor proxy cache projects currently allow pulling any repository from the configured upstream registry. This proposal introduces a repository filter on proxy cache projects so administrators can explicitly allow only selected repositories. Requests that do not match the configured filter are denied before Harbor proxies content from upstream.
8+
9+
## Motivation
10+
11+
Many organizations use Harbor as the only approved image source for runtime environments, while direct access to public registries is restricted for security and compliance reasons. Proxy cache simplifies image consumption, but without repository filtering it also opens access to unintended or untrusted content.
12+
13+
Today users commonly work around this by creating many replication rules for individual repositories and tags. This is operationally expensive and hard to maintain at scale.
14+
15+
With proxy cache filters, administrators can define an allowlist such as:
16+
17+
- `library/**` -- doublestar matching for all repositories under `library`
18+
- `goharbor/**` -- doublestar matching for all repositories under `goharbor`
19+
- `myorg/.*` -- regex matching for all repositories under `myorg`
20+
21+
This keeps the proxy cache workflow while preserving repository governance.
22+
23+
## Issues
24+
25+
[Limit Proxy Cache Images - by adding filter](https://github.com/goharbor/harbor/issues/13231)
26+
27+
## Goals and Non-Goals
28+
29+
1. Add per-project proxy cache repository filter configuration.
30+
2. Enforce filter matching before upstream proxy pull behavior is executed.
31+
3. Keep backward compatibility: if no filter is configured, current behavior remains unchanged.
32+
4. Provide API and UI support for creating and updating filter configuration as part of proxy cache project configuration.
33+
34+
1. This proposal does not add denylist precedence rules. Initial scope is allowlist-only.
35+
2. This proposal does not introduce global/system-level proxy filter policy.
36+
3. This proposal does not support tag-based filtering in this phase, because pull requests by tag are often converted to pull requests by digest in client side.
37+
4. This proposal does not perform content trust or vulnerability policy evaluation as part of filter matching.
38+
39+
## Solution
40+
41+
Add a new optional setting for proxy cache projects: `repository_filter`.
42+
43+
Matching semantics:
44+
45+
1. If `repository_filter` is empty or not set, all repositories are allowed (same as today).
46+
2. If `repository_filter` is configured, Harbor allows the pull only when the requested repository matches the configured pattern.
47+
3. The filter format is JSON: `{"filter":"<pattern>","kind":"regex"|"doublestar"}`.
48+
4. `kind` is optional. If omitted, Harbor uses `regex` matching by default.
49+
5. If the repository does not match, Harbor returns `404 Not Found` and does not request content from upstream.
50+
51+
Pattern format:
52+
53+
- `regex`: regular expression matching against repository path.
54+
- `doublestar`: glob-style matching with doublestar support (`*`, `**`, `{a,b}`, and related glob features).
55+
56+
## Implementation Details
57+
58+
### Request enforcement point
59+
60+
Enforcement should happen in proxy middleware before upstream manifest proxy operations:
61+
62+
- Entry point: proxy pre-check logic in `src/server/middleware/repoproxy/proxy.go`.
63+
- After project and proxy configuration are resolved.
64+
- Before issuing upstream manifest requests.
65+
66+
Processing flow:
67+
68+
1. Resolve current project and verify it is a proxy cache project.
69+
2. Load project proxy filter configuration.
70+
3. Build artifact request context (repository).
71+
4. Evaluate against repository filter.
72+
5. If not matched, return `404 Not Found`.
73+
6. If matched, continue existing proxy logic unchanged.
74+
75+
Notes on behavior:
76+
77+
1. Invalid `repository_filter` JSON or invalid pattern is treated as non-match at runtime.
78+
2. In project metadata API validation, invalid JSON or unsupported `kind` value is rejected with `400 Bad Request`.
79+
80+
### Data model
81+
82+
Store filter as project metadata, consistent with existing proxy project settings.
83+
84+
Proposed metadata key:
85+
86+
- `repository_filter`
87+
88+
Proposed JSON value:
89+
90+
```json
91+
{
92+
"filter": "^library/.*",
93+
"kind": "regex"
94+
}
95+
```
96+
97+
Validation:
98+
99+
1. `filter` can be empty (empty means match all).
100+
2. `kind` must be `regex` or `doublestar` when specified.
101+
3. Invalid JSON is rejected during project metadata validation.
102+
103+
### API changes
104+
105+
Extend project APIs for proxy cache configuration:
106+
107+
1. `POST /api/v2.0/projects`
108+
2. `PUT /api/v2.0/projects/{project_name_or_id}`
109+
3. `GET /api/v2.0/projects/{project_name_or_id}` and list APIs should include configured filters in response.
110+
111+
`repository_filter` is metadata for proxy cache projects only. For non-proxy projects, this metadata is ignored on create/update and omitted from response.
112+
113+
Request example:
114+
115+
```json
116+
{
117+
"project_name": "dockerhub-proxy",
118+
"registry_id": 1,
119+
"metadata": {
120+
"repository_filter": "{"filter":"library/**","kind":"doublestar"}"
121+
}
122+
}
123+
```
124+
125+
### UI changes
126+
127+
In proxy cache project create view, add a new configuration item:
128+
129+
- Label: `Repository filter`
130+
- A text input for filter pattern -- input the pattern for repository filtering.
131+
- A kind selector with options: `Regex` and `Doublestar`
132+
133+
Validation should happen both client-side and server-side.
134+
135+
### Audit and observability
136+
137+
1. Record project update audit entries when filter set is changed.
138+
2. Add log item for blocked proxy pulls (project, repository, reason) to help operators tune filters.
139+
140+
## Database Schema Changes
141+
142+
No new table is required for initial implementation when storing as project metadata.
143+
144+
145+
## Compatibility
146+
147+
1. Existing proxy cache projects without filters keep current behavior (allow all).
148+
2. New behavior is opt-in by configuring `repository_filter`.
149+
3. Clients receive `404 Not Found` for repositories that do not match the configured filter.
150+
151+
## Open issues
152+
153+
N/A

0 commit comments

Comments
 (0)