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
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.
@@ -39,7 +44,7 @@ PermLens helps developers and reviewers understand what data a GitHub App *decla
39
44
40
45
PermLens provides human-readable visibility into **GitHub App permissions** and the types of data an app may access.
41
46
42
-
It generates a structured, privacy-label-style summary based on an app’s 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.
43
48
44
49
PermLens is an **informational transparency tool**, not a security scanner.
45
50
@@ -73,10 +78,11 @@ PermLens reflects **what an app declares**, not what it actually does at runtime
73
78
## ❓ How it works
74
79
75
80
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
80
86
81
87
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.
82
88
@@ -91,7 +97,7 @@ Only public GitHub App metadata is used.
91
97
GET /api/app/:slug/label
92
98
```
93
99
94
-
Response schema:
100
+
### Response schema
95
101
96
102
```json
97
103
{
@@ -109,6 +115,18 @@ Response schema:
109
115
"hit": "boolean",
110
116
"cached_at": "ISO_8601 string | null"
111
117
},
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
+
},
112
130
"label": {
113
131
"data_categories": [
114
132
{
@@ -126,11 +144,11 @@ Response schema:
126
144
}
127
145
],
128
146
"notes": ["string"]
129
-
}
147
+
},
148
+
"error": "string | null"
130
149
}
131
150
```
132
151
133
-
134
152
## 📘 API Response Reference
135
153
136
154
### Response fields
@@ -140,11 +158,21 @@ Response schema:
140
158
|`resolved`| Whether the requested GitHub App slug was successfully resolved via the GitHub API |`true`\|`false`|
141
159
|`fallback`| Whether PermLens fell back to its own GitHub App permissions |`true`\|`false`|
142
160
|`rate_limits.unauthenticated`| Whether the unauthenticated GitHub API rate limit was exceeded |`true`\|`false`|
143
-
|`rate_limits.authenticated`| Whether the GitHub App–authenticated API rate limit was exceeded |`true`\|`false`|
161
+
|`rate_limits.authenticated`| Whether the GitHub App-authenticated API rate limit was exceeded |`true`\|`false`|
144
162
|`api.unauthenticated_hit`| Whether an unauthenticated GitHub API request was made |`true`\|`false`|
145
-
|`api.authenticated_hit`| Whether a GitHub App–authenticated request was made (typically fallback) |`true`\|`false`|
163
+
|`api.authenticated_hit`| Whether a GitHub App-authenticated request was made (typically fallback) |`true`\|`false`|
146
164
|`cache.hit`| Whether the response was served from cache |`true`\|`false`|
147
165
|`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 |
|`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`|
159
187
160
188
### Resolution behavior
161
189
@@ -182,18 +210,51 @@ Response schema:
182
210
- if both are `true`, no app data can be fetched
183
211
184
212
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`.
-`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**.
186
248
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.
188
250
189
-
Version **v0.3.0** introduces:
190
251
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)
195
253
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
0 commit comments