github-license-scanner 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- github_license_scanner-0.1.0.dist-info/METADATA +307 -0
- github_license_scanner-0.1.0.dist-info/RECORD +24 -0
- github_license_scanner-0.1.0.dist-info/WHEEL +4 -0
- github_license_scanner-0.1.0.dist-info/entry_points.txt +3 -0
- github_license_scanner-0.1.0.dist-info/licenses/LICENSE +21 -0
- gls/__init__.py +1 -0
- gls/auth.py +229 -0
- gls/cli.py +358 -0
- gls/config.py +161 -0
- gls/dependency_scanner.py +621 -0
- gls/deploy_advisor.py +286 -0
- gls/docs/LEGAL_DISCLAIMER.md +57 -0
- gls/docs/PRIVACY.md +69 -0
- gls/docs/TERMS.md +52 -0
- gls/github_api.py +514 -0
- gls/history_store.py +177 -0
- gls/i18n.py +530 -0
- gls/license_analyzer.py +855 -0
- gls/models.py +148 -0
- gls/rate_limit.py +64 -0
- gls/report.py +150 -0
- gls/sbom_export.py +312 -0
- gls/spdx_engine.py +441 -0
- gls/webui.py +1828 -0
gls/deploy_advisor.py
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Deploy platform recommender.
|
|
3
|
+
|
|
4
|
+
Inspects repository language, dependency names, and Dockerfile presence
|
|
5
|
+
to suggest where the application is easiest to host (Vercel, Railway, etc.).
|
|
6
|
+
|
|
7
|
+
This is heuristic guidance for developers — not a production capacity plan.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from .models import Dependency, DeployAdvice
|
|
13
|
+
|
|
14
|
+
# ---------------------------------------------------------------------------
|
|
15
|
+
# Platform catalog
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
PLATFORMS: dict[str, dict[str, str]] = {
|
|
19
|
+
"Vercel": {
|
|
20
|
+
"docs_url": "https://vercel.com/docs",
|
|
21
|
+
"blurb": "Frontend and serverless-first hosting",
|
|
22
|
+
},
|
|
23
|
+
"Cloudflare Pages": {
|
|
24
|
+
"docs_url": "https://developers.cloudflare.com/pages/",
|
|
25
|
+
"blurb": "Static sites and Pages Functions at the edge",
|
|
26
|
+
},
|
|
27
|
+
"Netlify": {
|
|
28
|
+
"docs_url": "https://docs.netlify.com/",
|
|
29
|
+
"blurb": "JAMstack and static site hosting",
|
|
30
|
+
},
|
|
31
|
+
"Railway": {
|
|
32
|
+
"docs_url": "https://docs.railway.app/",
|
|
33
|
+
"blurb": "Simple full-stack deploys from Git",
|
|
34
|
+
},
|
|
35
|
+
"Render": {
|
|
36
|
+
"docs_url": "https://render.com/docs",
|
|
37
|
+
"blurb": "Web services, workers, and static sites",
|
|
38
|
+
},
|
|
39
|
+
"Fly.io": {
|
|
40
|
+
"docs_url": "https://fly.io/docs/",
|
|
41
|
+
"blurb": "Global app VMs close to users",
|
|
42
|
+
},
|
|
43
|
+
"Google Cloud Run": {
|
|
44
|
+
"docs_url": "https://cloud.google.com/run/docs",
|
|
45
|
+
"blurb": "Containerized services that scale to zero",
|
|
46
|
+
},
|
|
47
|
+
"GitHub Pages": {
|
|
48
|
+
"docs_url": "https://docs.github.com/pages",
|
|
49
|
+
"blurb": "Free static hosting from the repo",
|
|
50
|
+
},
|
|
51
|
+
"Hugging Face / RunPod / GPU VPS": {
|
|
52
|
+
"docs_url": "https://huggingface.co/docs/hub/spaces-sdks-docker",
|
|
53
|
+
"blurb": "GPU-oriented hosts for ML workloads",
|
|
54
|
+
},
|
|
55
|
+
"Any VPS (Docker)": {
|
|
56
|
+
"docs_url": "https://docs.docker.com/get-started/",
|
|
57
|
+
"blurb": "Full control with Docker on a VPS",
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Frontend framework package names (lowercase)
|
|
62
|
+
FRONTEND_FRAMEWORKS = {
|
|
63
|
+
"next": "Next.js",
|
|
64
|
+
"nuxt": "Nuxt",
|
|
65
|
+
"vite": "Vite",
|
|
66
|
+
"react": "React",
|
|
67
|
+
"react-dom": "React",
|
|
68
|
+
"vue": "Vue",
|
|
69
|
+
"@angular/core": "Angular",
|
|
70
|
+
"svelte": "Svelte",
|
|
71
|
+
"astro": "Astro",
|
|
72
|
+
"gatsby": "Gatsby",
|
|
73
|
+
"@remix-run/react": "Remix",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Backend / full-stack Python & similar
|
|
77
|
+
BACKEND_PYTHON = {
|
|
78
|
+
"fastapi",
|
|
79
|
+
"flask",
|
|
80
|
+
"django",
|
|
81
|
+
"nicegui",
|
|
82
|
+
"starlette",
|
|
83
|
+
"uvicorn",
|
|
84
|
+
"gunicorn",
|
|
85
|
+
"streamlit",
|
|
86
|
+
"gradio",
|
|
87
|
+
"dash",
|
|
88
|
+
"tornado",
|
|
89
|
+
"sanic",
|
|
90
|
+
"aiohttp",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
BACKEND_NODE = {
|
|
94
|
+
"express",
|
|
95
|
+
"fastify",
|
|
96
|
+
"koa",
|
|
97
|
+
"nestjs",
|
|
98
|
+
"@nestjs/core",
|
|
99
|
+
"hono",
|
|
100
|
+
"hapi",
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
ML_HEAVY = {
|
|
104
|
+
"torch",
|
|
105
|
+
"pytorch",
|
|
106
|
+
"tensorflow",
|
|
107
|
+
"keras",
|
|
108
|
+
"transformers",
|
|
109
|
+
"diffusers",
|
|
110
|
+
"langchain",
|
|
111
|
+
"scikit-learn",
|
|
112
|
+
"sklearn",
|
|
113
|
+
"xgboost",
|
|
114
|
+
"opencv-python",
|
|
115
|
+
"opencv-python-headless",
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def recommend_deploy(
|
|
120
|
+
*,
|
|
121
|
+
primary_language: str | None,
|
|
122
|
+
topics: list[str] | None,
|
|
123
|
+
dependencies: list[Dependency],
|
|
124
|
+
dependency_files: list[str] | None = None,
|
|
125
|
+
has_dockerfile: bool = False,
|
|
126
|
+
description: str | None = None,
|
|
127
|
+
) -> list[DeployAdvice]:
|
|
128
|
+
"""
|
|
129
|
+
Score deploy platforms and return them sorted by score (descending).
|
|
130
|
+
|
|
131
|
+
Only platforms with score > 0 are returned (plus a sensible default if none).
|
|
132
|
+
"""
|
|
133
|
+
scores: dict[str, int] = {name: 0 for name in PLATFORMS}
|
|
134
|
+
reasons: dict[str, list[str]] = {name: [] for name in PLATFORMS}
|
|
135
|
+
|
|
136
|
+
dep_names = {d.name.lower() for d in dependencies}
|
|
137
|
+
ecosystems = {d.ecosystem for d in dependencies}
|
|
138
|
+
files = [f.replace("\\", "/").lower() for f in (dependency_files or [])]
|
|
139
|
+
lang = (primary_language or "").lower()
|
|
140
|
+
topic_set = {t.lower() for t in (topics or [])}
|
|
141
|
+
desc = (description or "").lower()
|
|
142
|
+
|
|
143
|
+
def bump(platform: str, points: int, reason: str) -> None:
|
|
144
|
+
scores[platform] += points
|
|
145
|
+
if reason not in reasons[platform]:
|
|
146
|
+
reasons[platform].append(reason)
|
|
147
|
+
|
|
148
|
+
# --- Dockerfile signal ---
|
|
149
|
+
if has_dockerfile:
|
|
150
|
+
bump("Fly.io", 25, "Dockerfile detected — container-friendly hosts fit well")
|
|
151
|
+
bump("Railway", 22, "Dockerfile detected — Railway deploys containers easily")
|
|
152
|
+
bump("Render", 20, "Dockerfile detected — Render supports Docker web services")
|
|
153
|
+
bump("Google Cloud Run", 22, "Dockerfile detected — Cloud Run is container-native")
|
|
154
|
+
bump("Any VPS (Docker)", 18, "Dockerfile present — any Docker host works")
|
|
155
|
+
|
|
156
|
+
# --- Frontend frameworks ---
|
|
157
|
+
found_fe: list[str] = []
|
|
158
|
+
for pkg, label in FRONTEND_FRAMEWORKS.items():
|
|
159
|
+
if pkg in dep_names:
|
|
160
|
+
found_fe.append(label)
|
|
161
|
+
if found_fe:
|
|
162
|
+
labels = ", ".join(sorted(set(found_fe)))
|
|
163
|
+
bump("Vercel", 35, f"Frontend stack detected ({labels})")
|
|
164
|
+
bump("Netlify", 28, f"Frontend stack detected ({labels})")
|
|
165
|
+
bump("Cloudflare Pages", 26, f"Frontend stack detected ({labels})")
|
|
166
|
+
if "next" in dep_names or "Next.js" in found_fe:
|
|
167
|
+
bump("Vercel", 15, "Next.js is first-class on Vercel")
|
|
168
|
+
if "nuxt" in dep_names:
|
|
169
|
+
bump("Vercel", 10, "Nuxt deploys cleanly on Vercel / Node hosts")
|
|
170
|
+
bump("Railway", 8, "Nuxt can run as a Node service on Railway")
|
|
171
|
+
|
|
172
|
+
# --- Backend Python ---
|
|
173
|
+
py_hits = sorted(BACKEND_PYTHON & dep_names)
|
|
174
|
+
if py_hits:
|
|
175
|
+
bump("Railway", 32, f"Python backend packages: {', '.join(py_hits)}")
|
|
176
|
+
bump("Render", 30, f"Python backend packages: {', '.join(py_hits)}")
|
|
177
|
+
bump("Fly.io", 24, f"Python backend packages: {', '.join(py_hits)}")
|
|
178
|
+
if "nicegui" in dep_names:
|
|
179
|
+
bump("Railway", 8, "NiceGUI needs a long-running Python process (not pure static hosts)")
|
|
180
|
+
bump("Render", 8, "NiceGUI needs a long-running Python process")
|
|
181
|
+
if "streamlit" in dep_names or "gradio" in dep_names:
|
|
182
|
+
bump("Railway", 6, "Streamlit/Gradio apps need a process host")
|
|
183
|
+
bump("Hugging Face / RunPod / GPU VPS", 10, "ML demo UIs often ship on HF Spaces")
|
|
184
|
+
|
|
185
|
+
# --- Backend Node ---
|
|
186
|
+
node_hits = sorted(BACKEND_NODE & dep_names)
|
|
187
|
+
if node_hits:
|
|
188
|
+
bump("Railway", 28, f"Node backend packages: {', '.join(node_hits)}")
|
|
189
|
+
bump("Render", 26, f"Node backend packages: {', '.join(node_hits)}")
|
|
190
|
+
bump("Fly.io", 22, f"Node backend packages: {', '.join(node_hits)}")
|
|
191
|
+
bump("Vercel", 12, "API routes / serverless Node can run on Vercel")
|
|
192
|
+
|
|
193
|
+
# --- ML heavy ---
|
|
194
|
+
ml_hits = sorted(ML_HEAVY & dep_names)
|
|
195
|
+
if ml_hits:
|
|
196
|
+
bump(
|
|
197
|
+
"Hugging Face / RunPod / GPU VPS",
|
|
198
|
+
40,
|
|
199
|
+
f"Heavy ML libraries detected: {', '.join(ml_hits)}",
|
|
200
|
+
)
|
|
201
|
+
bump("Any VPS (Docker)", 15, "ML stacks often need custom GPU/CPU sizing")
|
|
202
|
+
bump("Google Cloud Run", 8, "Possible if containerized and within memory limits")
|
|
203
|
+
|
|
204
|
+
# --- Ecosystem files ---
|
|
205
|
+
if any(f.endswith("go.mod") for f in files) or "go" in ecosystems:
|
|
206
|
+
bump("Fly.io", 30, "Go module project — Fly.io is excellent for Go binaries")
|
|
207
|
+
bump("Google Cloud Run", 26, "Go services containerize well for Cloud Run")
|
|
208
|
+
bump("Railway", 18, "Go apps deploy on Railway")
|
|
209
|
+
|
|
210
|
+
if any(f.endswith("cargo.toml") for f in files) or "cargo" in ecosystems:
|
|
211
|
+
bump("Fly.io", 28, "Rust (Cargo) project — compile to a binary on Fly.io")
|
|
212
|
+
bump("Railway", 20, "Rust projects can build on Railway")
|
|
213
|
+
bump("Any VPS (Docker)", 16, "Rust binaries run well on a VPS")
|
|
214
|
+
|
|
215
|
+
if any("composer.json" in f for f in files) or "composer" in ecosystems:
|
|
216
|
+
bump("Railway", 20, "PHP (Composer) project")
|
|
217
|
+
bump("Render", 18, "PHP (Composer) project")
|
|
218
|
+
bump("Any VPS (Docker)", 15, "Classic PHP stack on VPS")
|
|
219
|
+
|
|
220
|
+
if any(f.endswith("gemfile") for f in files) or "rubygems" in ecosystems:
|
|
221
|
+
bump("Railway", 22, "Ruby (Bundler) project")
|
|
222
|
+
bump("Render", 22, "Ruby (Bundler) project")
|
|
223
|
+
bump("Fly.io", 16, "Ruby app on Fly.io")
|
|
224
|
+
|
|
225
|
+
if any(f.endswith("pom.xml") or "build.gradle" in f for f in files):
|
|
226
|
+
bump("Google Cloud Run", 22, "JVM project — containerize and run on Cloud Run")
|
|
227
|
+
bump("Railway", 18, "JVM project")
|
|
228
|
+
bump("Render", 18, "JVM project")
|
|
229
|
+
bump("Any VPS (Docker)", 16, "JVM services commonly run via Docker on a VPS")
|
|
230
|
+
|
|
231
|
+
# --- Language fallback signals ---
|
|
232
|
+
if lang in {"javascript", "typescript"}:
|
|
233
|
+
bump("Vercel", 12, f"Primary language is {primary_language}")
|
|
234
|
+
bump("Cloudflare Pages", 10, f"Primary language is {primary_language}")
|
|
235
|
+
bump("Netlify", 10, f"Primary language is {primary_language}")
|
|
236
|
+
elif lang == "python":
|
|
237
|
+
bump("Railway", 14, "Primary language is Python")
|
|
238
|
+
bump("Render", 12, "Primary language is Python")
|
|
239
|
+
elif lang == "go":
|
|
240
|
+
bump("Fly.io", 14, "Primary language is Go")
|
|
241
|
+
bump("Google Cloud Run", 12, "Primary language is Go")
|
|
242
|
+
elif lang in {"html", "css"}:
|
|
243
|
+
bump("GitHub Pages", 25, "Looks like a static site (HTML)")
|
|
244
|
+
bump("Cloudflare Pages", 22, "Looks like a static site (HTML)")
|
|
245
|
+
bump("Netlify", 20, "Looks like a static site (HTML)")
|
|
246
|
+
elif lang == "rust":
|
|
247
|
+
bump("Fly.io", 14, "Primary language is Rust")
|
|
248
|
+
|
|
249
|
+
# Topics / description hints
|
|
250
|
+
if topic_set & {"static-site", "documentation", "docs", "github-pages"}:
|
|
251
|
+
bump("GitHub Pages", 20, "Topics suggest a documentation / static site")
|
|
252
|
+
bump("Cloudflare Pages", 15, "Topics suggest a static site")
|
|
253
|
+
if "docker" in topic_set or "docker" in desc:
|
|
254
|
+
bump("Fly.io", 8, "Docker mentioned in topics/description")
|
|
255
|
+
bump("Google Cloud Run", 8, "Docker mentioned in topics/description")
|
|
256
|
+
|
|
257
|
+
# Pure static: only package.json missing backend, or no deps at all
|
|
258
|
+
has_backend = bool(py_hits or node_hits or ml_hits)
|
|
259
|
+
has_frontend = bool(found_fe)
|
|
260
|
+
if has_frontend and not has_backend and not has_dockerfile:
|
|
261
|
+
bump("Cloudflare Pages", 10, "Frontend-heavy with no clear backend process")
|
|
262
|
+
bump("Netlify", 8, "Frontend-heavy with no clear backend process")
|
|
263
|
+
|
|
264
|
+
# Default polyglot fallback so we always return something useful
|
|
265
|
+
if max(scores.values(), default=0) == 0:
|
|
266
|
+
bump("Railway", 10, "General-purpose Git deploy (no strong stack signals)")
|
|
267
|
+
bump("Render", 9, "General-purpose Git deploy (no strong stack signals)")
|
|
268
|
+
bump("Fly.io", 8, "General-purpose container/VM host")
|
|
269
|
+
|
|
270
|
+
# Build sorted advice list
|
|
271
|
+
advice: list[DeployAdvice] = []
|
|
272
|
+
for platform, score in sorted(scores.items(), key=lambda x: (-x[1], x[0])):
|
|
273
|
+
if score <= 0:
|
|
274
|
+
continue
|
|
275
|
+
meta = PLATFORMS[platform]
|
|
276
|
+
advice.append(
|
|
277
|
+
DeployAdvice(
|
|
278
|
+
platform=platform,
|
|
279
|
+
score=score,
|
|
280
|
+
reasons=reasons[platform] or [meta["blurb"]],
|
|
281
|
+
docs_url=meta["docs_url"],
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Cap to top 5 recommendations for UI clarity
|
|
286
|
+
return advice[:5]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Legal disclaimer — GitHub License Scanner
|
|
2
|
+
|
|
3
|
+
**Effective date:** 2026-07-24
|
|
4
|
+
|
|
5
|
+
## Not legal advice
|
|
6
|
+
|
|
7
|
+
GitHub License Scanner (“the Tool”) provides **automated heuristics** about open-source licenses detected in public (or token-accessible) GitHub repositories and package registries.
|
|
8
|
+
|
|
9
|
+
The Tool:
|
|
10
|
+
|
|
11
|
+
- is **not** a law firm, attorney, or licensed legal service;
|
|
12
|
+
- does **not** create an attorney–client relationship;
|
|
13
|
+
- does **not** issue formal license-compatibility opinions;
|
|
14
|
+
- does **not** warrant non-infringement, fitness for purpose, or merchantability;
|
|
15
|
+
- may produce **false positives and false negatives**.
|
|
16
|
+
|
|
17
|
+
**You must consult a qualified attorney** before commercial closed-source distribution, M&A diligence, or any high-stakes compliance decision.
|
|
18
|
+
|
|
19
|
+
## What the Tool does not fully model
|
|
20
|
+
|
|
21
|
+
Among other things, results may be incomplete or wrong regarding:
|
|
22
|
+
|
|
23
|
+
| Topic | Why it matters |
|
|
24
|
+
|-------|----------------|
|
|
25
|
+
| Static vs dynamic linking | GPL obligations often depend on how code is combined |
|
|
26
|
+
| SaaS / network use | AGPL and SSPL may impose duties without traditional “distribution” |
|
|
27
|
+
| Dual licensing / additional permissions | “MIT OR GPL” choice and exceptions change outcomes |
|
|
28
|
+
| Private patches & internal forks | History and LICENSE files may not reflect reality |
|
|
29
|
+
| System libraries & OS exceptions | Some jurisdictions/license texts have special rules |
|
|
30
|
+
| Patent, trademark, export, privacy law | Outside license text classification |
|
|
31
|
+
| Contracts / CLAs / ToS | Can override or add to open-source license terms |
|
|
32
|
+
| Transitive / lockfile-only deps | Not fully resolved from lockfiles in all ecosystems |
|
|
33
|
+
| Maven/Gradle/Go registry licenses | Often unresolved (unknown) |
|
|
34
|
+
|
|
35
|
+
## “Can sell closed” / “Forces open source”
|
|
36
|
+
|
|
37
|
+
These UI labels are **risk signals**, not legal conclusions. A green or “OK” result still requires:
|
|
38
|
+
|
|
39
|
+
1. Attribution and notice preservation (MIT, BSD, Apache-2.0, etc.).
|
|
40
|
+
2. Compliance with Apache-2.0 patent and NOTICE rules where applicable.
|
|
41
|
+
3. Review of each dependency’s full license text and any third-party notices.
|
|
42
|
+
4. Confirmation that build pipelines do not ship “dev-only” copyleft code.
|
|
43
|
+
|
|
44
|
+
## Copyright notice templates
|
|
45
|
+
|
|
46
|
+
Generated notices are **templates only**. The GitHub **owner or organization name is not proof of copyright ownership** (forks, employers, multi-author projects, work-for-hire). Always verify LICENSE, NOTICE, and authorship before use.
|
|
47
|
+
|
|
48
|
+
## No warranty / limitation of liability
|
|
49
|
+
|
|
50
|
+
THE TOOL IS PROVIDED “AS IS” AND “AS AVAILABLE”, WITHOUT WARRANTY OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE AUTHORS AND COPYRIGHT HOLDERS SHALL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM USE OF THE TOOL OR RELIANCE ON ITS OUTPUT.
|
|
51
|
+
|
|
52
|
+
See also the project [MIT License](../LICENSE).
|
|
53
|
+
|
|
54
|
+
## Related documents
|
|
55
|
+
|
|
56
|
+
- [Privacy](PRIVACY.md)
|
|
57
|
+
- [Terms of use](TERMS.md)
|
gls/docs/PRIVACY.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Privacy policy — GitHub License Scanner
|
|
2
|
+
|
|
3
|
+
**Effective date:** 2026-07-24
|
|
4
|
+
**Data controller (self-hosted):** the operator who runs this instance.
|
|
5
|
+
|
|
6
|
+
This Tool is primarily designed for **local / self-hosted** use. If you deploy it as a multi-user service, **you** become responsible for providing a complete privacy notice to your users under applicable law (e.g. GDPR, CCPA/CPRA, UK GDPR).
|
|
7
|
+
|
|
8
|
+
## Data we process
|
|
9
|
+
|
|
10
|
+
| Data | Purpose | Storage | Retention |
|
|
11
|
+
|------|---------|---------|-----------|
|
|
12
|
+
| GitHub repo URLs you submit | Run license analysis | In memory during scan; may be written to local history | See history settings |
|
|
13
|
+
| Scan results (owner/repo, license ids, risk flags, short verdict text) | History UI / CLI | `history.json` in the user data directory on the host | Max entries + optional max age (default 90 days) |
|
|
14
|
+
| UI preferences (language, theme) | UX | Browser cookie / NiceGUI user storage (signed) | Browser session / cookie lifetime |
|
|
15
|
+
| Rate-limit counters | Abuse prevention | In-process memory | Rolling window (default 1 hour) |
|
|
16
|
+
| Optional `GITHUB_TOKEN` | Higher GitHub API limits / private repos | Environment of the host process only | Until you remove it |
|
|
17
|
+
|
|
18
|
+
The Tool **does not intentionally collect** names, emails, payment data, or government IDs.
|
|
19
|
+
|
|
20
|
+
## Third-party processing
|
|
21
|
+
|
|
22
|
+
When you run a scan, the host machine sends requests to:
|
|
23
|
+
|
|
24
|
+
- **api.github.com** — repository metadata and file contents
|
|
25
|
+
- Package registries as needed (e.g. **registry.npmjs.org**, **pypi.org**, **crates.io**, **rubygems.org**, **repo.packagist.org**)
|
|
26
|
+
|
|
27
|
+
Those services process the request under **their** privacy policies and terms. Do not submit private repository URLs unless you are authorized and understand that API tokens and network logs may retain metadata.
|
|
28
|
+
|
|
29
|
+
## History isolation
|
|
30
|
+
|
|
31
|
+
| Mode | Path | Visibility |
|
|
32
|
+
|------|------|------------|
|
|
33
|
+
| Auth **disabled** (default) | `history.json` in the user data directory | Shared by everyone on the instance |
|
|
34
|
+
| Auth **enabled** (`GLS_AUTH_ENABLED=1`) | `history/<username>.json` in the user data directory | Isolated per logged-in user |
|
|
35
|
+
|
|
36
|
+
On a multi-user deployment **without** authentication, any user of that instance can see others’ recent scans. Enable auth (create users with `gls user-add …`) for per-user isolation.
|
|
37
|
+
|
|
38
|
+
## Your rights (GDPR / CCPA-style)
|
|
39
|
+
|
|
40
|
+
If EU/UK GDPR or similar laws apply to **your** deployment:
|
|
41
|
+
|
|
42
|
+
| Right | How to exercise on this Tool |
|
|
43
|
+
|-------|------------------------------|
|
|
44
|
+
| Access | Read `history.json` in the user data directory / History tab |
|
|
45
|
+
| Erasure | Use **Clear history** in the UI, or delete `history.json` in the user data directory |
|
|
46
|
+
| Restriction / objection | Stop using the service; operator may disable history |
|
|
47
|
+
| Portability | Export Markdown report from a scan result |
|
|
48
|
+
|
|
49
|
+
Cookie/local storage for language and theme is used for **strictly necessary / preference** purposes on this self-hosted UI.
|
|
50
|
+
|
|
51
|
+
## Security measures (baseline)
|
|
52
|
+
|
|
53
|
+
- Default bind address `127.0.0.1` (local only)
|
|
54
|
+
- Configurable session signing secret (`GLS_STORAGE_SECRET`)
|
|
55
|
+
- Scan rate limiting
|
|
56
|
+
- Batch size caps
|
|
57
|
+
- History retention limits
|
|
58
|
+
- No hardcoded production secrets (see `.env.example`)
|
|
59
|
+
|
|
60
|
+
Operators should still place TLS, access control, and log hygiene in front of any public deployment.
|
|
61
|
+
|
|
62
|
+
## Children
|
|
63
|
+
|
|
64
|
+
The Tool is not directed at children under 16 (or the age required in your jurisdiction).
|
|
65
|
+
|
|
66
|
+
## Contact
|
|
67
|
+
|
|
68
|
+
For the public open-source project, open an issue on the GitHub repository.
|
|
69
|
+
For a **self-hosted** instance, contact the organization that runs the server.
|
gls/docs/TERMS.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Terms of use — GitHub License Scanner
|
|
2
|
+
|
|
3
|
+
**Effective date:** 2026-07-24
|
|
4
|
+
|
|
5
|
+
By using this software (web UI or CLI), you agree to these terms. If you do not agree, do not use the Tool.
|
|
6
|
+
|
|
7
|
+
## License of the Tool itself
|
|
8
|
+
|
|
9
|
+
The source code of GitHub License Scanner is released under the **MIT License** (see `LICENSE` in the repository root). That license governs the Tool’s code, **not** the licenses of repositories or packages you scan.
|
|
10
|
+
|
|
11
|
+
## Acceptable use
|
|
12
|
+
|
|
13
|
+
You agree to:
|
|
14
|
+
|
|
15
|
+
1. Only scan repositories and private resources you are **authorized** to access.
|
|
16
|
+
2. Comply with the [GitHub Terms of Service](https://docs.github.com/site-policy/github-terms/github-terms-of-service) and API rate limits.
|
|
17
|
+
3. Not use the Tool to overwhelm third-party APIs, bypass access controls, or harass others.
|
|
18
|
+
4. Not present Tool output as formal legal advice to third parties without independent legal review.
|
|
19
|
+
5. Not remove or obscure the Tool’s disclaimers when redistributing reports.
|
|
20
|
+
|
|
21
|
+
## No professional services
|
|
22
|
+
|
|
23
|
+
Output is **informational only**. You remain solely responsible for license compliance, intellectual property clearance, and commercial decisions.
|
|
24
|
+
|
|
25
|
+
## Accounts and tokens
|
|
26
|
+
|
|
27
|
+
If you supply a `GITHUB_TOKEN` (or similar), you are responsible for:
|
|
28
|
+
|
|
29
|
+
- keeping it secret;
|
|
30
|
+
- using least-privilege scopes;
|
|
31
|
+
- rotating it if leaked;
|
|
32
|
+
- ensuring your use of private repository data is lawful and authorized.
|
|
33
|
+
|
|
34
|
+
## Availability
|
|
35
|
+
|
|
36
|
+
The Tool is provided without uptime guarantees. APIs (GitHub, npm, PyPI, etc.) may fail, throttle, or change without notice.
|
|
37
|
+
|
|
38
|
+
## Indemnity (where enforceable)
|
|
39
|
+
|
|
40
|
+
To the extent permitted by law, you agree to indemnify and hold harmless the authors and contributors from claims arising from your misuse of the Tool or reliance on its output in commercial or legal contexts.
|
|
41
|
+
|
|
42
|
+
## Limitation of liability
|
|
43
|
+
|
|
44
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE AUTHORS AND COPYRIGHT HOLDERS SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS OR DATA, ARISING FROM USE OF THE TOOL.
|
|
45
|
+
|
|
46
|
+
## Changes
|
|
47
|
+
|
|
48
|
+
Self-hosted operators may present additional terms. Upstream project terms may be updated in this repository; continued use of a newer version constitutes acceptance of updated docs shipped with that version.
|
|
49
|
+
|
|
50
|
+
## Governing note
|
|
51
|
+
|
|
52
|
+
These terms are a practical baseline for an open-source developer tool. They are not a substitute for counsel-drafted SaaS terms if you offer the Tool as a commercial multi-tenant service.
|