ossuary-risk 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.
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: ossuary-risk
3
+ Version: 0.1.0
4
+ Summary: OSS Supply Chain Risk Scoring - Where abandoned packages come to rest
5
+ Project-URL: Homepage, https://github.com/anicka-net/ossuary
6
+ Project-URL: Repository, https://github.com/anicka-net/ossuary
7
+ Project-URL: Documentation, https://github.com/anicka-net/ossuary/blob/main/docs/methodology.md
8
+ Author: Anicka
9
+ License-Expression: MIT
10
+ Keywords: oss,risk,scoring,security,supply-chain
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Security
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: alembic>=1.13.0
20
+ Requires-Dist: fastapi>=0.109.0
21
+ Requires-Dist: gitpython>=3.1.0
22
+ Requires-Dist: httpx>=0.26.0
23
+ Requires-Dist: psycopg2-binary>=2.9.0
24
+ Requires-Dist: pydantic-settings>=2.1.0
25
+ Requires-Dist: pydantic>=2.5.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Requires-Dist: sqlalchemy>=2.0.0
28
+ Requires-Dist: textblob>=0.18.0
29
+ Requires-Dist: typer>=0.9.0
30
+ Requires-Dist: uvicorn[standard]>=0.27.0
31
+ Requires-Dist: vadersentiment>=3.3.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: httpx>=0.26.0; extra == 'dev'
34
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
35
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
36
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
37
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
38
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # Ossuary
42
+
43
+ **OSS Supply Chain Risk Scoring** - Where abandoned packages come to rest.
44
+
45
+ Ossuary analyzes open source packages to identify governance-based supply chain risks before incidents occur. It calculates a risk score based on maintainer concentration, activity levels, and protective factors.
46
+
47
+ ## What It Detects
48
+
49
+ Ossuary focuses on **governance failures** - the type of vulnerability that enabled attacks like:
50
+
51
+ - **event-stream** (2018) - Abandoned package handed off to malicious maintainer
52
+ - **colors/faker** (2022) - Frustrated maintainer intentionally sabotaged packages
53
+
54
+ ### Detection Capabilities
55
+
56
+ | Can Detect | Cannot Detect |
57
+ |------------|---------------|
58
+ | Maintainer abandonment | Account compromise (like ua-parser-js) |
59
+ | High concentration risk | Dependency confusion attacks |
60
+ | Economic frustration signals | Typosquatting |
61
+ | Declining activity trends | Malicious code injection |
62
+ | Governance centralization | |
63
+
64
+ ## Quick Start
65
+
66
+ ```bash
67
+ # Install
68
+ pip install ossuary
69
+
70
+ # Initialize database (optional, for caching)
71
+ ossuary init
72
+
73
+ # Score a package
74
+ ossuary score event-stream --ecosystem npm
75
+
76
+ # Score with historical cutoff (T-1 analysis)
77
+ ossuary score event-stream --ecosystem npm --cutoff 2018-09-01
78
+
79
+ # Output as JSON
80
+ ossuary score requests --ecosystem pypi --json
81
+ ```
82
+
83
+ ## Risk Levels
84
+
85
+ | Score | Level | Semaphore | Action |
86
+ |-------|-------|-----------|--------|
87
+ | 0-20 | Very Low | 🟒 | Routine monitoring |
88
+ | 21-40 | Low | 🟒 | Quarterly review |
89
+ | 41-60 | Moderate | 🟑 | Monthly review |
90
+ | 61-80 | High | 🟠 | Weekly review + contingency plan |
91
+ | 81-100 | Critical | πŸ”΄ | Immediate action required |
92
+
93
+ ## Scoring Methodology
94
+
95
+ ```
96
+ Final Score = Base Risk + Activity Modifier + Protective Factors
97
+ (20-100) (-30 to +20) (-100 to +20)
98
+ ```
99
+
100
+ ### Base Risk (Maintainer Concentration)
101
+
102
+ | Concentration | Points |
103
+ |---------------|--------|
104
+ | <30% | 20 |
105
+ | 30-50% | 40 |
106
+ | 50-70% | 60 |
107
+ | 70-90% | 80 |
108
+ | >90% | 100 |
109
+
110
+ ### Activity Modifier
111
+
112
+ | Commits/Year | Points |
113
+ |--------------|--------|
114
+ | >50 | -30 |
115
+ | 12-50 | -15 |
116
+ | 4-11 | 0 |
117
+ | <4 | +20 |
118
+
119
+ ### Protective Factors
120
+
121
+ | Factor | Points |
122
+ |--------|--------|
123
+ | Tier-1 maintainer (500+ repos or 100K+ stars) | -25 |
124
+ | GitHub Sponsors enabled | -15 |
125
+ | Organization with 3+ admins | -15 |
126
+ | >50M weekly downloads | -20 |
127
+ | >10M weekly downloads | -10 |
128
+ | <40% concentration | -10 |
129
+ | >20 contributors | -10 |
130
+ | CII Best Practices badge | -10 |
131
+ | **Frustration signals detected** | **+20** |
132
+
133
+ ## API Usage
134
+
135
+ Start the API server:
136
+
137
+ ```bash
138
+ uvicorn ossuary.api.main:app --host 0.0.0.0 --port 8000
139
+ ```
140
+
141
+ Query a package:
142
+
143
+ ```bash
144
+ curl "http://localhost:8000/score/npm/event-stream"
145
+ ```
146
+
147
+ Response:
148
+
149
+ ```json
150
+ {
151
+ "package": "event-stream",
152
+ "ecosystem": "npm",
153
+ "score": 100,
154
+ "risk_level": "CRITICAL",
155
+ "semaphore": "πŸ”΄",
156
+ "explanation": "πŸ”΄ CRITICAL (100). Critical concentration (90%): single person controls nearly all commits. Project appears abandoned (<4 commits/year).",
157
+ "recommendations": [
158
+ "IMMEDIATE: Identify alternative packages or prepare to fork",
159
+ "Do not accept new versions without manual code review"
160
+ ]
161
+ }
162
+ ```
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ # Clone
168
+ git clone https://github.com/anicka/ossuary.git
169
+ cd ossuary
170
+
171
+ # Install with dev dependencies
172
+ pip install -e ".[dev]"
173
+
174
+ # Run tests
175
+ pytest
176
+
177
+ # Run linter
178
+ ruff check src/
179
+
180
+ # Type check
181
+ mypy src/
182
+ ```
183
+
184
+ ## Configuration
185
+
186
+ Environment variables:
187
+
188
+ ```bash
189
+ # Required for higher GitHub API rate limits
190
+ GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
191
+
192
+ # Database (defaults to SQLite)
193
+ DATABASE_URL=postgresql://user:pass@localhost/ossuary
194
+
195
+ # Repository storage
196
+ REPOS_PATH=./repos
197
+ ```
198
+
199
+ ## Architecture
200
+
201
+ ```
202
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
203
+ β”‚ API / CLI β”‚
204
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
205
+ β”‚
206
+ β–Ό
207
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
208
+ β”‚ Scoring Engine β”‚
209
+ β”‚ - Base risk (concentration) β”‚
210
+ β”‚ - Activity modifier β”‚
211
+ β”‚ - Protective factors β”‚
212
+ β”‚ - Sentiment analysis β”‚
213
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
214
+ β”‚
215
+ β–Ό
216
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
217
+ β”‚ Data Collectors β”‚
218
+ β”‚ GitCollector | GitHubCollector | NpmCollector | PyPICollectorβ”‚
219
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
220
+ ```
221
+
222
+ ## Validation
223
+
224
+ Validated on 93 packages (20 incidents + 73 controls):
225
+
226
+ - **Accuracy**: 91.4%
227
+ - **Precision**: 92.9%
228
+ - **Recall**: 65.0%
229
+ - **F1 Score**: 0.76
230
+
231
+ T-1 analysis confirms **100% predictive detection** of governance-detectable incidents before they occurred.
232
+
233
+ See [methodology documentation](docs/methodology.md) for details.
234
+
235
+ ## License
236
+
237
+ MIT
238
+
239
+ ## Academic Context
240
+
241
+ This project supports MBA thesis research on OSS supply chain risk. Key contribution: demonstrating that meaningful risk indicators are observable in public metadata before incidents occur.
@@ -0,0 +1,23 @@
1
+ ossuary/__init__.py,sha256=LBPIxjvA1VQ68JIe5jEHLM3k4olf6F-egSzmBwyl6gc,111
2
+ ossuary/cli.py,sha256=aK8C0caQExM2RZktx7wKruMqpsvsi2JRMxsGe6uL0ns,12016
3
+ ossuary/api/__init__.py,sha256=ZeoSK1LsObUCJjTBPuYIz9wPcsNdjcNyXjwV9Cm3nGo,30
4
+ ossuary/api/main.py,sha256=LCOnxh8XYBI5z9O-fTuczV5IP84LNCz0KKcZ18EBdDg,6094
5
+ ossuary/collectors/__init__.py,sha256=4RwxUTTH8GbEXIUYCxjl1RjkWcb748D-BO3jdiW_btM,324
6
+ ossuary/collectors/base.py,sha256=XiQ8qlrJOdDBbNt8yl7M0dMf5KDbDcpBAmzxaLdyCyo,637
7
+ ossuary/collectors/git.py,sha256=Ljy8i1lmLDz5KhCIYtczGM5AiRgs0tm-zPbhxdZ5RCo,7553
8
+ ossuary/collectors/github.py,sha256=D1abhZVuMAOWgHhnkpIWJ7rdrdIQ5Vwg64Ihq9yNdy4,16977
9
+ ossuary/collectors/npm.py,sha256=wBufJBrq52NGxjqHOInEtvlmw8NvwG39r3vuKGIHqgw,3586
10
+ ossuary/collectors/pypi.py,sha256=mwBbK5VFDGo3b6uKlr2dUqKwJoj-d11jiHSxEKYU91Y,3625
11
+ ossuary/db/__init__.py,sha256=kLmKsHlKXXsDHB7-gnV3BYJx5bkHc2qxQBJBt023gGI,321
12
+ ossuary/db/models.py,sha256=6n1XlYFG6Hud41FCZUFk54ZH2xAyu5gvDNAyInxL8uc,6919
13
+ ossuary/db/session.py,sha256=sUzk271Q0UrFHccu4m2Y1rGXcPC5Zgno0feT5j9Yrlg,1267
14
+ ossuary/scoring/__init__.py,sha256=IzcbPV5NugIa1luLg6YVoy8TPEcFjlKyvgqX16vKHds,454
15
+ ossuary/scoring/engine.py,sha256=jhWHkQ4V24osoNxhdWKUdptjLXCMZaIAPX2g3A_lC8E,11924
16
+ ossuary/scoring/factors.py,sha256=DSQBQyUeVgl9pX1pDysRChBPW_j7XUW-ZDRXx58IRvs,5921
17
+ ossuary/scoring/reputation.py,sha256=PABfHfZiRWGJxv-4q19qHIY0WmtTWQE-oIYTkffyiKE,9741
18
+ ossuary/sentiment/__init__.py,sha256=ouOTyAh9Z_GW2UBMH0h-qD-jYUJVyyZfP7rK3KlJu58,147
19
+ ossuary/sentiment/analyzer.py,sha256=ndlqVaKiM23P4yeFcOrRtOP7K0UCVY99Nqk9cvKVIro,7383
20
+ ossuary_risk-0.1.0.dist-info/METADATA,sha256=iw9KDkUbV6R629mjb8CJIVXosbFSFWZhpk3Im-ZxXmg,7608
21
+ ossuary_risk-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
22
+ ossuary_risk-0.1.0.dist-info/entry_points.txt,sha256=PorJvPUnbx9MTUHWHpypRK6N1Hra5Xcisk1aOtj443k,44
23
+ ossuary_risk-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ossuary = ossuary.cli:app