You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: PRIVACY.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ PolicyChecks is a free, read-only GitHub App that reports selected repository se
6
6
7
7
When someone requests a badge, Shields JSON response, details JSON response, or repository `info.json` response, PolicyChecks uses the requested repository owner/name to query GitHub for the supported repository settings. PolicyChecks does not request repository write permissions and does not read repository source code.
8
8
9
-
PolicyChecks may temporarily cache API-derived claim results in memory for up to the configured cache TTL, currently one hour by default. This cache is used only to reduce repeated GitHub API requests.
9
+
PolicyChecks may temporarily cache API-derived badge evaluation results in memory for up to the configured cache TTL, currently one hour by default. This cache is used only to reduce repeated GitHub API requests.
10
10
11
11
PolicyChecks may receive GitHub Marketplace lifecycle webhooks for Marketplace listing administration. These deliveries are verified and acknowledged, but PolicyChecks does not create customer accounts or store Marketplace webhook payloads.
Copy file name to clipboardExpand all lines: README.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -58,16 +58,16 @@ If the GitHub API provides an endpoint that reliably tracks a specific repo sett
58
58
59
59
## Endpoints
60
60
61
-
Each claim supports the same endpoint shape:
61
+
Each supported badge has a stable badge ID, such as `sha-pinning-required` or `community-health`, and supports the same endpoint shape:
62
62
63
63
```text
64
-
GET /github/{owner}/{repo}/{setting}.svg # Returns an SVG badge with status `enabled`, `disabled`, or `unknown` for a given setting
65
-
GET /github/{owner}/{repo}/{setting}.json # Returns a Shields-compatible JSON result for use in custom badge tooling
66
-
GET /github/{owner}/{repo}/{setting}/details.json # Returns the PolicyChecks evaluation record and selected response-derived details for a given setting
64
+
GET /github/{owner}/{repo}/{badge-id}.svg # Returns an SVG badge with status `enabled`, `disabled`, or `unknown`
65
+
GET /github/{owner}/{repo}/{badge-id}.json # Returns a Shields-compatible JSON result for use in custom badge tooling
66
+
GET /github/{owner}/{repo}/{badge-id}/details.json # Returns the PolicyChecks evaluation record and selected response-derived details
67
67
GET /github/{owner}/{repo}/info.json # A general JSON response that provides collective information about multiple different settings
68
68
```
69
69
70
-
Use the SVG endpoint for badges, the Shields-compatible JSON endpoint for badge tooling, and the details endpoint for the underlying PolicyChecks evaluation record. README badges can link directly to their details JSON:
70
+
Use the SVG endpoint for badges, the Shields-compatible JSON endpoint for badge tooling, and the details endpoint for the underlying PolicyChecks evaluation record. Details JSON identifies the badge as `badgeId` and omits internal classification fields. README badges can link directly to their details JSON:
Copy file name to clipboardExpand all lines: docs/adr/0001-badge-publication-consent.md
+27-27Lines changed: 27 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ That creates a consent mismatch:
16
16
17
17
- Installing the GitHub App grants PolicyChecks read access to selected repository administration settings.
18
18
- Public badge endpoints disclose the result of any supported setting check to anyone who knows or guesses the endpoint URL.
19
-
- The aggregate `info.json` endpoint exposes all supported check results together, which makes the service look more like a public audit surface than a maintainer-selected badge service.
19
+
- The aggregate `info.json` endpoint exposes all supported badge results together, which makes the service look more like a public audit surface than a maintainer-selected badge service.
20
20
21
21
This is especially sensitive because these settings are not all publicly available through the unauthenticated GitHub API. A maintainer may want to publish one badge, such as immutable releases, without also making every other supported repository setting easy to query.
22
22
@@ -62,20 +62,20 @@ Both proposals require removing or disabling the public aggregate `info.json` en
62
62
63
63
Restrict PolicyChecks to public repositories and serve a badge only when the canonical badge URL appears in the repository's preferred README on the default branch.
64
64
65
-
Under this proposal, publication is controlled by the repository itself. A maintainer publishes a claim by committing the badge URL to the public repository README. If the badge URL is not present, PolicyChecks does not serve the badge or details endpoint for that claim.
65
+
Under this proposal, publication is controlled by the repository itself. A maintainer publishes a badge by committing the badge URL to the public repository README. If the badge URL is not present, PolicyChecks does not serve the badge or details endpoint for that badge ID.
66
66
67
67
Example publication check:
68
68
69
69
```text
70
-
GET /github/{owner}/{repo}/{claim}.svg
70
+
GET /github/{owner}/{repo}/{badge-id}.svg
71
71
```
72
72
73
73
PolicyChecks verifies:
74
74
75
75
1. The repository is public.
76
76
2. The GitHub App is installed on the repository.
77
-
3. The repository's preferred README on the default branch contains the canonical badge URL for that claim.
78
-
4. The requested claim can be evaluated from GitHub API data.
77
+
3. The repository's preferred README on the default branch contains the canonical badge URL for that badge ID.
78
+
4. The requested badge can be evaluated from GitHub API data.
79
79
80
80
If any publication check fails, PolicyChecks returns a generic unavailable response, such as `404`. It should not return `disabled`, because `disabled` is the privileged information the publication check is meant to protect.
81
81
@@ -114,20 +114,20 @@ This proposal is accepted because it keeps the project small and keeps the publi
114
114
115
115
Use tokenized public badge URLs and remove the public aggregate `info.json` endpoint.
116
116
117
-
Public badge and details endpoints would require a per-repository, per-claim token. A token authorizes disclosure of exactly one claim for exactly one repository installation. PolicyChecks can derive these tokens deterministically from a private server-side signing secret rather than storing each token in a database.
117
+
Public badge and details endpoints would require a per-repository, per-badge token. A token authorizes disclosure of exactly one badge result for exactly one repository installation. PolicyChecks can derive these tokens deterministically from a private server-side signing secret rather than storing each token in a database.
118
118
119
119
Example endpoint shapes:
120
120
121
121
```text
122
-
GET /github/{owner}/{repo}/{claim}.svg?token={token}
123
-
GET /github/{owner}/{repo}/{claim}.json?token={token}
124
-
GET /github/{owner}/{repo}/{claim}/details.json?token={token}
122
+
GET /github/{owner}/{repo}/{badge-id}.svg?token={token}
123
+
GET /github/{owner}/{repo}/{badge-id}.json?token={token}
124
+
GET /github/{owner}/{repo}/{badge-id}/details.json?token={token}
125
125
```
126
126
127
-
The token should be computed from stable GitHub identifiers and the claim identifier:
127
+
The token should be computed from stable GitHub identifiers and the badge ID:
`BADGE_TOKEN_SECRET` is a private PolicyChecks runtime secret. It is never shown to installers. The public token derived from it is safe to place in README badge Markdown because it authorizes only a single public badge result.
@@ -136,7 +136,7 @@ Including `installation_id` means uninstalling and reinstalling the GitHub App r
136
136
137
137
## Publication Model
138
138
139
-
Under this model, "published" means that a maintainer has chosen to use the tokenized URL for a specific repository and claim. PolicyChecks does not need to detect where the URL is embedded.
139
+
Under this model, "published" means that a maintainer has chosen to use the tokenized URL for a specific repository and badge ID. PolicyChecks does not need to detect where the URL is embedded.
140
140
141
141
Anyone can view a badge once they have the tokenized URL, but they cannot derive other badge URLs from it. For example, a token for `immutable-releases` on repository A cannot be used to query `sha-pinning-required` on repository A or `immutable-releases` on repository B.
142
142
@@ -154,7 +154,7 @@ This preserves the practical workflow:
154
154
2. Copy the badge snippets you want.
155
155
3. Paste them where you want the badges to appear.
156
156
157
-
No per-claim database state is required for the initial version.
157
+
No per-badge database state is required for the initial version.
158
158
159
159
### Consequences
160
160
@@ -166,7 +166,7 @@ Positive:
166
166
- The product remains close to "install and paste a badge."
167
167
- No repository contents permission is required.
168
168
- No committed configuration file is required.
169
-
- No durable per-claim publication database is required.
169
+
- No durable per-badge publication database is required.
170
170
- Tokens can be regenerated for authorized maintainers because they are deterministic.
171
171
172
172
Negative:
@@ -181,7 +181,7 @@ Negative:
181
181
182
182
### Option A: Keep the current public endpoint model
183
183
184
-
Installation continues to expose every supported claim endpoint for an installed repository.
184
+
Installation continues to expose every supported badge endpoint for an installed repository.
185
185
186
186
Benefits:
187
187
@@ -200,7 +200,7 @@ This option conflicts with the desired consent model.
200
200
201
201
### Option B: Remove `info.json` only
202
202
203
-
Delete or disable the aggregate endpoint, but leave individual claim endpoints public and guessable.
203
+
Delete or disable the aggregate endpoint, but leave individual badge endpoints public and guessable.
204
204
205
205
Benefits:
206
206
@@ -210,14 +210,14 @@ Benefits:
210
210
211
211
Costs:
212
212
213
-
- Anyone can still query every individual supported claim for an installed repository.
214
-
- Maintainers still cannot selectively publish one claim without exposing the rest.
213
+
- Anyone can still query every individual supported badge for an installed repository.
214
+
- Maintainers still cannot selectively publish one badge without exposing the rest.
215
215
216
216
This is a useful immediate mitigation, but it does not fully solve the disclosure model.
217
217
218
-
### Option C: Store a per-repository, per-claim publication allowlist
218
+
### Option C: Store a per-repository, per-badge publication allowlist
219
219
220
-
Add a small configuration store that records which claims are publicly enabled for each repository.
220
+
Add a small configuration store that records which badges are publicly enabled for each repository.
221
221
222
222
Example:
223
223
@@ -226,7 +226,7 @@ repository_id
226
226
installation_id
227
227
owner
228
228
repo
229
-
published_claims
229
+
published_badges
230
230
updated_by
231
231
updated_at
232
232
```
@@ -275,14 +275,14 @@ This option is not recommended unless PolicyChecks intentionally expands into re
275
275
276
276
### Option E: Use tokenized per-badge URLs
277
277
278
-
Generate unguessable badge URLs for every repository and claim, and require the matching token on public badge and details endpoints.
278
+
Generate unguessable badge URLs for every repository and badge ID, and require the matching token on public badge and details endpoints.
279
279
280
280
Benefits:
281
281
282
282
- Maintainers choose what to publish by choosing which badge URL to use.
283
283
- No durable publication database is required.
284
284
- No repository contents permission is required.
285
-
- Public callers cannot enumerate unpublished claims.
285
+
- Public callers cannot enumerate unpublished badges.
286
286
- Tokens can be regenerated for authorized maintainers.
287
287
- Keeps the product close to a no-configuration badge workflow.
288
288
@@ -302,14 +302,14 @@ The public aggregate endpoint should be removed or disabled:
302
302
GET /github/{owner}/{repo}/info.json
303
303
```
304
304
305
-
If an aggregate endpoint is later reintroduced, it should return only claims that the maintainer has explicitly published. It should not act as a public repository policy profile.
305
+
If an aggregate endpoint is later reintroduced, it should return only badges that the maintainer has explicitly published. It should not act as a public repository policy profile.
306
306
307
-
Badge, Shields JSON, and details JSON endpoints should all use the same publication rule. Under the README-presence proposal, the details endpoint is available only when the corresponding badge URL is present in the preferred README. Under the tokenized URL proposal, the details endpoint requires the same per-repository, per-claim token as the badge. Details JSON can disclose more context than a badge, so it should not remain available through an unauthenticated, guessable URL. The details endpoint is supporting evaluation context derived from GitHub API responses, not an audit report, guarantee, or independent compliance attestation.
307
+
Badge, Shields JSON, and details JSON endpoints should all use the same publication rule. Under the README-presence proposal, the details endpoint is available only when the corresponding badge URL is present in the preferred README. Under the tokenized URL proposal, the details endpoint requires the same per-repository, per-badge token as the badge. Details JSON can disclose more context than a badge, so it should not remain available through an unauthenticated, guessable URL. The details endpoint is supporting evaluation context derived from GitHub API responses, not an audit report, guarantee, or independent compliance attestation.
308
308
309
309
For failed publication checks, responses should avoid distinguishing:
310
310
311
311
- GitHub App not installed.
312
-
-Claim not published.
312
+
-Badge not published.
313
313
- Token invalid.
314
314
- Repository not found.
315
315
- Repository is private.
@@ -352,4 +352,4 @@ This keeps PolicyChecks closest to its core value: a small public badge service
352
352
353
353
Tokenized badge URLs remain the leading alternative if private repository support or non-README publication becomes important enough to justify the extra setup and authorization surface.
354
354
355
-
If schedule pressure requires a smaller immediate change, remove `info.json` first. The current all-claims-public posture should not be treated as the intended long-term model.
355
+
If schedule pressure requires a smaller immediate change, remove `info.json` first. The current all-badges-public posture should not be treated as the intended long-term model.
Copy file name to clipboardExpand all lines: docs/operations.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ PolicyChecks is a current-state badge and details service. Operational safety de
6
6
7
7
## Cache Policy
8
8
9
-
The internal claim-result cache defaults to `CACHE_TTL_SECONDS=3600`. This is intentionally conservative because the checked settings are low-volatility repository administration/security settings, not fast-changing CI state.
9
+
The internal badge-result cache defaults to `CACHE_TTL_SECONDS=3600`. This is intentionally conservative because the checked settings are low-volatility repository administration/security settings, not fast-changing CI state.
10
10
11
11
Public badge, Shields JSON, details JSON, and `info.json` responses use `Cache-Control: public, max-age=300, stale-while-revalidate=300`. This keeps externally visible badge staleness modest while allowing the Worker to serve repeated requests from its longer internal cache when the same isolate remains warm.
12
12
@@ -16,7 +16,7 @@ Tune cache settings with this policy:
16
16
- Keep `CACHE_TTL_SECONDS` at least as large as the public `max-age` value, otherwise external clients can revalidate faster than the Worker cache can absorb.
17
17
- Use `3600` seconds as the default.
18
18
- Consider `21600` seconds for high-traffic public badges if rate-limit logs show repeated cache misses for the same repositories.
19
-
- Do not lower below `300` seconds unless actively debugging a claim mapping.
19
+
- Do not lower below `300` seconds unless actively debugging a badge mapping.
20
20
21
21
Current limitation: the cache is in-memory per Worker isolate. It is a quota reducer, not durable storage. Cold starts and separate isolates may still call GitHub for the same repository.
0 commit comments