Skip to content

Commit 712d70e

Browse files
authored
docs: update readme + schema update ahead of v1.0.0 release (#5)
Refresh README with v1.0.0 response schema, example payload, and deployment notes. Extend shared privacy label schema with app metadata and error field. Bump package versions to 1.0.0 across workspace.
1 parent e5c15ad commit 712d70e

5 files changed

Lines changed: 99 additions & 25 deletions

File tree

README.md

Lines changed: 82 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<img src="https://img.shields.io/github/license/zapdev360/PermLens?style=for-the-badge" alt="Repo license" >
88
</p>
99

10-
1110
# PermLens 🔍
1211

1312
Permission transparency and privacy labeling for GitHub Apps.
@@ -23,13 +22,19 @@ PermLens helps developers and reviewers understand what data a GitHub App *decla
2322
- [❓ How it works](#-how-it-works)
2423
- [⚙ API](#-api)
2524
- [Get privacy label for a GitHub App](#get-privacy-label-for-a-github-app)
25+
- [Response schema](#response-schema)
2626
- [📘 API Response Reference](#-api-response-reference)
2727
- [Response fields](#response-fields)
2828
- [Resolution behavior](#resolution-behavior)
2929
- [Cache behavior](#cache-behavior)
3030
- [API request behavior](#api-request-behavior)
3131
- [Rate limiting behavior](#rate-limiting-behavior)
32-
- [🚧 Project status](#-project-status)
32+
- [🚀 Deployment](#-deployment)
33+
- [Environment variables](#environment-variables)
34+
- [Vercel backend API deployment](#vercel-backend-api-deployment)
35+
- [Vercel frontend deployment](#vercel-frontend-deployment)
36+
- [🟢 Project status](#-project-status)
37+
- [✨ Release highlights (v1.0.0)](#-release-highlights-v100)
3338
- [🔐 Security and privacy](#-security-and-privacy)
3439
- [🏷️ Branding](#️-branding)
3540
- [⚖️ License](#️-license)
@@ -39,7 +44,7 @@ PermLens helps developers and reviewers understand what data a GitHub App *decla
3944

4045
PermLens provides human-readable visibility into **GitHub App permissions** and the types of data an app may access.
4146

42-
It generates a structured, privacy-label-style summary based on an apps declared permissions, helping users reason about permission scope at a glance.
47+
It generates a structured, privacy-label-style summary based on an app's declared permissions, helping users reason about permission scope at a glance.
4348

4449
PermLens is an **informational transparency tool**, not a security scanner.
4550

@@ -73,10 +78,11 @@ PermLens reflects **what an app declares**, not what it actually does at runtime
7378
## ❓ How it works
7479

7580
1. Attempts to resolve a GitHub App by its marketplace slug
76-
2. Fetches the app’s declared permissions using the GitHub API
77-
3. Maps permissions to predefined data access categories
78-
4. Computes an overall sensitivity level
79-
5. Returns a privacy-label-style summary
81+
2. Fetches the app's declared permissions using the GitHub API
82+
3. Captures public app metadata (id, slug, name, owner)
83+
4. Maps permissions to predefined data access categories
84+
5. Computes an overall sensitivity level
85+
6. Returns a privacy-label-style summary
8086

8187
If an app cannot be resolved by slug, PermLens safely falls back to its own declared permissions. In this case, PermLens authenticates as a GitHub App using JWT to fetch its metadata and explicitly reports the resolution status in the response.
8288

@@ -91,7 +97,7 @@ Only public GitHub App metadata is used.
9197
GET /api/app/:slug/label
9298
```
9399

94-
Response schema:
100+
### Response schema
95101

96102
```json
97103
{
@@ -109,6 +115,18 @@ Response schema:
109115
"hit": "boolean",
110116
"cached_at": "ISO_8601 string | null"
111117
},
118+
"app": {
119+
"id": "number",
120+
"client_id": "string",
121+
"slug": "string",
122+
"name": "string",
123+
"html_url": "string",
124+
"owner": {
125+
"login": "string",
126+
"id": "number",
127+
"type": "string"
128+
}
129+
},
112130
"label": {
113131
"data_categories": [
114132
{
@@ -126,11 +144,11 @@ Response schema:
126144
}
127145
],
128146
"notes": ["string"]
129-
}
147+
},
148+
"error": "string | null"
130149
}
131150
```
132151

133-
134152
## 📘 API Response Reference
135153

136154
### Response fields
@@ -140,11 +158,21 @@ Response schema:
140158
| `resolved` | Whether the requested GitHub App slug was successfully resolved via the GitHub API | `true` \| `false` |
141159
| `fallback` | Whether PermLens fell back to its own GitHub App permissions | `true` \| `false` |
142160
| `rate_limits.unauthenticated` | Whether the unauthenticated GitHub API rate limit was exceeded | `true` \| `false` |
143-
| `rate_limits.authenticated` | Whether the GitHub Appauthenticated API rate limit was exceeded | `true` \| `false` |
161+
| `rate_limits.authenticated` | Whether the GitHub App-authenticated API rate limit was exceeded | `true` \| `false` |
144162
| `api.unauthenticated_hit` | Whether an unauthenticated GitHub API request was made | `true` \| `false` |
145-
| `api.authenticated_hit` | Whether a GitHub Appauthenticated request was made (typically fallback) | `true` \| `false` |
163+
| `api.authenticated_hit` | Whether a GitHub App-authenticated request was made (typically fallback) | `true` \| `false` |
146164
| `cache.hit` | Whether the response was served from cache | `true` \| `false` |
147165
| `cache.cached_at` | Timestamp of cached response generation | ISO 8601 timestamp \| `null` |
166+
| `app` | GitHub App metadata included with the label | object |
167+
| `app.id` | GitHub App numeric identifier | number |
168+
| `app.client_id` | GitHub App client id | string |
169+
| `app.slug` | GitHub App marketplace slug | string |
170+
| `app.name` | GitHub App display name | string |
171+
| `app.html_url` | GitHub App marketplace URL | string |
172+
| `app.owner` | GitHub App owner metadata | object |
173+
| `app.owner.login` | Owner login | string |
174+
| `app.owner.id` | Owner numeric identifier | number |
175+
| `app.owner.type` | Owner type | `User` \| `Organization` \| other string |
148176
| `label.data_categories` | Data access categories derived from declared permissions | array of objects |
149177
| `label.data_categories[].key` | Internal category identifier | string |
150178
| `label.data_categories[].label` | Human-readable category name | string |
@@ -155,7 +183,7 @@ Response schema:
155183
| `label.permissions[].name` | Permission name | string |
156184
| `label.permissions[].access` | Permission access level | `read` \| `write` |
157185
| `label.notes` | Informational notes about label generation | array of strings |
158-
| `error` | Error message when label generation fails | string \| absent |
186+
| `error` | Error message when label generation fails | string \| `null` |
159187

160188
### Resolution behavior
161189

@@ -182,18 +210,51 @@ Response schema:
182210
- if both are `true`, no app data can be fetched
183211

184212

185-
## 🚧 Project status
213+
## 🚀 Deployment
214+
215+
PermLens ships with Vercel-ready configuration for both the backend API and the frontend. You can deploy them independently or front the backend API with your own reverse proxy.
216+
217+
### Environment variables
218+
219+
Backend API:
220+
221+
- `GH_APP_KEY` (required): GitHub App private key (PEM). Newlines can be escaped as `\n`.
222+
- `GH_APP_ID` (required): GitHub App id.
223+
- `GH_INSTALL_ID` (required): GitHub App installation id.
224+
- `GH_USER_AGENT` (optional): User agent string for GitHub API requests.
225+
- `PORT` (optional for local dev): API port (defaults to `3000`).
226+
227+
Frontend:
228+
229+
- `VITE_API_URL` (required): Base URL of the deployed API (example: `https://api.example.com`).
230+
231+
### Vercel backend API deployment
232+
233+
- Deploy from the repository root so the serverless function at `api/[...path].js` can mount the Express app.
234+
- Configure the environment variables listed above.
235+
- The API is served under `/api/*`.
236+
237+
### Vercel frontend deployment
238+
239+
- Deploy the `frontend` folder as a separate Vercel project.
240+
- Build command: `npm run build`
241+
- Output directory: `dist`
242+
- Configure `VITE_API_URL` to point at your API deployment.
243+
244+
245+
## 🟢 Project status
246+
247+
PermLens is in stable release **v1.0.0**.
186248

187-
PermLens is in **early development**.
249+
The API response schema is stable, and deployments are ready for production use. Future releases will extend capabilities while preserving the v1 contract.
188250

189-
Version **v0.3.0** introduces:
190251

191-
- In-memory caching for label lookups
192-
- Explicit cache and API metadata in response payloads
193-
- Clear unauthenticated vs authenticated rate limit reporting
194-
- Improved frontend UX for cached, fallback, and rate-limited cases
252+
## ✨ Release highlights (v1.0.0)
195253

196-
APIs and schemas may evolve as the project matures.
254+
- Stable v1 schema with full app identity fields for audits and tooling
255+
- Response envelope now surfaces cache hits and rate-limit status explicitly
256+
- Predictable fallback + error signaling when a slug cannot be resolved
257+
- Vercel-ready deployment split for backend API and frontend with env guidance
197258

198259

199260
## 🔐 Security and privacy

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "permlens-backend",
3-
"version": "0.3.0",
3+
"version": "1.0.0",
44
"description": "Backend API for resolving GitHub App permissions and generating privacy-label-style summaries using public GitHub metadata",
55
"keywords": [
66
"github",

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "permlens-frontend",
33
"private": true,
4-
"version": "0.3.0",
4+
"version": "1.0.0",
55
"description": "Web interface for inspecting GitHub App permissions and visualizing privacy labels generated by PermLens",
66
"type": "module",
77
"scripts": {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "permlens",
33
"private": true,
4-
"version": "0.3.0",
4+
"version": "1.0.0",
55
"description": "PermLens monorepo",
66
"license": "Apache-2.0",
77
"author": "Diptodeep Biswas",

shared/privacy-label.schema.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
"hit": "boolean",
1414
"cached_at": "ISO_8601 string | null"
1515
},
16+
"app": {
17+
"id": "number",
18+
"client_id": "string",
19+
"slug": "string",
20+
"name": "string",
21+
"html_url": "string",
22+
"owner": {
23+
"login": "string",
24+
"id": "number",
25+
"type": "string"
26+
}
27+
},
1628
"label": {
1729
"data_categories": [
1830
{
@@ -30,5 +42,6 @@
3042
}
3143
],
3244
"notes": ["string"]
33-
}
45+
},
46+
"error": "string | null"
3447
}

0 commit comments

Comments
 (0)