relintio-agent 0.9.5__tar.gz
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.
- relintio_agent-0.9.5/LICENSE +29 -0
- relintio_agent-0.9.5/PKG-INFO +144 -0
- relintio_agent-0.9.5/README.md +129 -0
- relintio_agent-0.9.5/pyproject.toml +27 -0
- relintio_agent-0.9.5/setup.cfg +4 -0
- relintio_agent-0.9.5/src/auraprotector_agent/__init__.py +18 -0
- relintio_agent-0.9.5/src/auraprotector_agent/asgi.py +3 -0
- relintio_agent-0.9.5/src/auraprotector_agent/auto.py +3 -0
- relintio_agent-0.9.5/src/relintio_agent.egg-info/PKG-INFO +144 -0
- relintio_agent-0.9.5/src/relintio_agent.egg-info/SOURCES.txt +18 -0
- relintio_agent-0.9.5/src/relintio_agent.egg-info/dependency_links.txt +1 -0
- relintio_agent-0.9.5/src/relintio_agent.egg-info/requires.txt +2 -0
- relintio_agent-0.9.5/src/relintio_agent.egg-info/top_level.txt +2 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/__init__.py +4 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/asgi.py +826 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/auto.py +66 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/client.py +607 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/obsidian.py +147 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/sitecustomize.py +0 -0
- relintio_agent-0.9.5/src/ultimateprotector_agent/utils.py +182 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
RelintioAgent / Relintio Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Relintio
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") are proprietary
|
|
8
|
+
and confidential. Unauthorized copying, modification, distribution, or use of the
|
|
9
|
+
Software, via any medium, is strictly prohibited.
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted to use the Software solely for the purpose of
|
|
12
|
+
integrating and operating the RelintioAgent service with a valid, active license
|
|
13
|
+
obtained from Relintio.
|
|
14
|
+
|
|
15
|
+
You may not:
|
|
16
|
+
- Copy, reproduce, or redistribute the Software or any portion of it;
|
|
17
|
+
- Modify, translate, reverse engineer, decompile, disassemble, or create
|
|
18
|
+
derivative works based on the Software;
|
|
19
|
+
- Remove or alter any proprietary notices.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
For licensing inquiries, contact Relintio.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: relintio-agent
|
|
3
|
+
Version: 0.9.5
|
|
4
|
+
Summary: RelintioAgent in-process agent for Python ASGI runtimes.
|
|
5
|
+
License-Expression: LicenseRef-Proprietary
|
|
6
|
+
Project-URL: Homepage, https://github.com/relintio/Relintio
|
|
7
|
+
Project-URL: Repository, https://github.com/relintio/Relintio
|
|
8
|
+
Project-URL: Issues, https://github.com/relintio/Relintio/issues
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: httpx>=0.26
|
|
13
|
+
Requires-Dist: cryptography>=42
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# relintio-agent (Python)
|
|
17
|
+
|
|
18
|
+
> **Note on Features & Quotas**: Advanced features (like Bot Challenge and Custom Shield Pages) are tied to your subscription plan. If you exceed your monthly API quota, the agent will operate in a degraded mode (basic protection) before ultimately failing-open to prevent locking you out of your own site. All configuration rules are centrally managed via the dashboard.
|
|
19
|
+
|
|
20
|
+
Python in-process agent for ASGI runtimes (FastAPI/Starlette/etc).
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install relintio-agent
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## FastAPI usage
|
|
29
|
+
|
|
30
|
+
```py
|
|
31
|
+
from fastapi import FastAPI
|
|
32
|
+
from relintio_agent.asgi import UltimateProtectorMiddleware
|
|
33
|
+
|
|
34
|
+
app = FastAPI()
|
|
35
|
+
|
|
36
|
+
app.add_middleware(
|
|
37
|
+
UltimateProtectorMiddleware,
|
|
38
|
+
license_key="UP_LIVE_...",
|
|
39
|
+
api_url="https://relintio.com/api",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Zero-code-ish usage (env wrapper)
|
|
45
|
+
|
|
46
|
+
If you can change *how* the app is created (but don't want to paste config into code),
|
|
47
|
+
wrap the ASGI app using env vars:
|
|
48
|
+
|
|
49
|
+
```py
|
|
50
|
+
import os
|
|
51
|
+
from fastapi import FastAPI
|
|
52
|
+
from relintio_agent import wrap_asgi_app
|
|
53
|
+
|
|
54
|
+
app = wrap_asgi_app(FastAPI())
|
|
55
|
+
|
|
56
|
+
# env:
|
|
57
|
+
# UP_LICENSE_KEY=UP_LIVE_...
|
|
58
|
+
# UP_API_URL=https://relintio.com/api
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Optional: sitecustomize bootstrap
|
|
62
|
+
|
|
63
|
+
The platform can generate a `sitecustomize.py` helper inside the **Python auto bundle**.
|
|
64
|
+
If that file is on `PYTHONPATH`, Python auto-imports it on startup.
|
|
65
|
+
Set `UP_ASGI_APP="module:app"` and it will best-effort wrap that object automatically (fail-open).
|
|
66
|
+
|
|
67
|
+
## Risk Scoring Engine (v0.9.3)
|
|
68
|
+
|
|
69
|
+
Every request is evaluated using an **additive 0-100 signal-based score**. Signals include:
|
|
70
|
+
|
|
71
|
+
| Signal | Weight | Description |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| Empty User-Agent | +50 | No UA header sent |
|
|
74
|
+
| Short User-Agent | +25 | UA < 20 characters |
|
|
75
|
+
| No Accept-Language | +20 | Missing browser locale header |
|
|
76
|
+
| Generic Accept | +15 | Wildcard `*/*` only |
|
|
77
|
+
| Connection: close | +10 | Non-persistent connection |
|
|
78
|
+
| POST without Referer | +15 | Form submission without origin |
|
|
79
|
+
| Rate burst | +35 | Token-bucket exhaustion |
|
|
80
|
+
|
|
81
|
+
### Response Tiers
|
|
82
|
+
|
|
83
|
+
| Tier | Score Range | Behavior |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| **ALLOW** | 0–39 | Request proceeds normally |
|
|
86
|
+
| **SLOW** | 40–59 | 2-second `asyncio.sleep` to exhaust scanners |
|
|
87
|
+
| **CHALLENGE** | 60–74 | Browser verification challenge |
|
|
88
|
+
| **DECOY** | 75–84 | Serves fake maintenance page |
|
|
89
|
+
| **BLOCK** | 85–100 | Hard block with configured response |
|
|
90
|
+
|
|
91
|
+
### Token-Bucket Rate Limiter
|
|
92
|
+
|
|
93
|
+
Default: **8 tokens/sec**, burst capacity of **24**. Route-aware multipliers give extra capacity to static assets. Memory-safe with 5-minute eviction via `asyncio`-compatible dict.
|
|
94
|
+
|
|
95
|
+
## Notes
|
|
96
|
+
|
|
97
|
+
- PyPI distribution name: `relintio-agent`
|
|
98
|
+
- Import path: `relintio_agent` (recommended)
|
|
99
|
+
- Legacy import path still supported: `ultimateprotector_agent`
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## Options
|
|
103
|
+
|
|
104
|
+
- `license_key` (required)
|
|
105
|
+
- `api_url` (required) e.g. `https://relintio.com/api`
|
|
106
|
+
- `sync_interval_seconds` (default: `60`)
|
|
107
|
+
- `allow_sample_rate` (default: `0.01`)
|
|
108
|
+
- `only_paths`: list[str] exact (`/checkout`) or prefix (`/product/*`)
|
|
109
|
+
- `except_paths`: list[str]
|
|
110
|
+
- `only_regex`: str (Python regex)
|
|
111
|
+
|
|
112
|
+
## Geo Enrichment
|
|
113
|
+
|
|
114
|
+
When CDN geo headers (`CF-IPCountry`, etc.) are absent, the agent calls the platform's `/api/agent/geo-lookup` endpoint.
|
|
115
|
+
The server resolves the country using **local MaxMind GeoLite2 databases** — zero external API calls, zero cost, microsecond latency.
|
|
116
|
+
Results are cached in-memory (24h TTL) to minimize round-trips.
|
|
117
|
+
|
|
118
|
+
## Changelog
|
|
119
|
+
|
|
120
|
+
### 0.9.3
|
|
121
|
+
|
|
122
|
+
- **Import path alignment** - `relintio_agent` is now the documented import path, with `ultimateprotector_agent` kept as a compatibility alias.
|
|
123
|
+
- **Version telemetry alignment** - Runtime telemetry now reports `0.9.3`, matching the PyPI package version and release tag.
|
|
124
|
+
|
|
125
|
+
### 0.5.0
|
|
126
|
+
|
|
127
|
+
- **Additive risk-scoring engine** — 0-100 signal-based scoring with 7 weighted signals.
|
|
128
|
+
- **5-tier graduated response** — ALLOW, SLOW (`asyncio.sleep(2.0)`), CHALLENGE, DECOY, BLOCK.
|
|
129
|
+
- **Token-bucket rate limiter** — Replaces fixed-window counter. 8 tokens/sec, 24 burst, route-aware multipliers.
|
|
130
|
+
- **`risk_score` telemetry** — Agent-calculated score forwarded to server in log payload.
|
|
131
|
+
|
|
132
|
+
### 0.3.0
|
|
133
|
+
|
|
134
|
+
- **Geo enrichment architecture hardened** — The server-side `/api/agent/geo-lookup` endpoint now performs local MaxMind GeoLite2 lookups instead of proxying to `ipinfo.io`. Agent behaviour is unchanged; the improvement is server-side.
|
|
135
|
+
|
|
136
|
+
### 0.2.0
|
|
137
|
+
|
|
138
|
+
- **HMAC payload verification** — Rules payloads are now authenticated with HMAC-SHA256 before decryption. Requires platform ≥ 2026-04.
|
|
139
|
+
- **`X-Agent-Version` header** — Sent on every `/verify` request for dashboard version tracking.
|
|
140
|
+
- **`outdated` status handling** — If the cloud responds with `outdated`, the agent fails open and stops protecting until updated.
|
|
141
|
+
|
|
142
|
+
### 0.1.1
|
|
143
|
+
|
|
144
|
+
- Initial stable release with AES-256-CBC encrypted rules sync.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# relintio-agent (Python)
|
|
2
|
+
|
|
3
|
+
> **Note on Features & Quotas**: Advanced features (like Bot Challenge and Custom Shield Pages) are tied to your subscription plan. If you exceed your monthly API quota, the agent will operate in a degraded mode (basic protection) before ultimately failing-open to prevent locking you out of your own site. All configuration rules are centrally managed via the dashboard.
|
|
4
|
+
|
|
5
|
+
Python in-process agent for ASGI runtimes (FastAPI/Starlette/etc).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install relintio-agent
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## FastAPI usage
|
|
14
|
+
|
|
15
|
+
```py
|
|
16
|
+
from fastapi import FastAPI
|
|
17
|
+
from relintio_agent.asgi import UltimateProtectorMiddleware
|
|
18
|
+
|
|
19
|
+
app = FastAPI()
|
|
20
|
+
|
|
21
|
+
app.add_middleware(
|
|
22
|
+
UltimateProtectorMiddleware,
|
|
23
|
+
license_key="UP_LIVE_...",
|
|
24
|
+
api_url="https://relintio.com/api",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Zero-code-ish usage (env wrapper)
|
|
30
|
+
|
|
31
|
+
If you can change *how* the app is created (but don't want to paste config into code),
|
|
32
|
+
wrap the ASGI app using env vars:
|
|
33
|
+
|
|
34
|
+
```py
|
|
35
|
+
import os
|
|
36
|
+
from fastapi import FastAPI
|
|
37
|
+
from relintio_agent import wrap_asgi_app
|
|
38
|
+
|
|
39
|
+
app = wrap_asgi_app(FastAPI())
|
|
40
|
+
|
|
41
|
+
# env:
|
|
42
|
+
# UP_LICENSE_KEY=UP_LIVE_...
|
|
43
|
+
# UP_API_URL=https://relintio.com/api
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Optional: sitecustomize bootstrap
|
|
47
|
+
|
|
48
|
+
The platform can generate a `sitecustomize.py` helper inside the **Python auto bundle**.
|
|
49
|
+
If that file is on `PYTHONPATH`, Python auto-imports it on startup.
|
|
50
|
+
Set `UP_ASGI_APP="module:app"` and it will best-effort wrap that object automatically (fail-open).
|
|
51
|
+
|
|
52
|
+
## Risk Scoring Engine (v0.9.3)
|
|
53
|
+
|
|
54
|
+
Every request is evaluated using an **additive 0-100 signal-based score**. Signals include:
|
|
55
|
+
|
|
56
|
+
| Signal | Weight | Description |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| Empty User-Agent | +50 | No UA header sent |
|
|
59
|
+
| Short User-Agent | +25 | UA < 20 characters |
|
|
60
|
+
| No Accept-Language | +20 | Missing browser locale header |
|
|
61
|
+
| Generic Accept | +15 | Wildcard `*/*` only |
|
|
62
|
+
| Connection: close | +10 | Non-persistent connection |
|
|
63
|
+
| POST without Referer | +15 | Form submission without origin |
|
|
64
|
+
| Rate burst | +35 | Token-bucket exhaustion |
|
|
65
|
+
|
|
66
|
+
### Response Tiers
|
|
67
|
+
|
|
68
|
+
| Tier | Score Range | Behavior |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| **ALLOW** | 0–39 | Request proceeds normally |
|
|
71
|
+
| **SLOW** | 40–59 | 2-second `asyncio.sleep` to exhaust scanners |
|
|
72
|
+
| **CHALLENGE** | 60–74 | Browser verification challenge |
|
|
73
|
+
| **DECOY** | 75–84 | Serves fake maintenance page |
|
|
74
|
+
| **BLOCK** | 85–100 | Hard block with configured response |
|
|
75
|
+
|
|
76
|
+
### Token-Bucket Rate Limiter
|
|
77
|
+
|
|
78
|
+
Default: **8 tokens/sec**, burst capacity of **24**. Route-aware multipliers give extra capacity to static assets. Memory-safe with 5-minute eviction via `asyncio`-compatible dict.
|
|
79
|
+
|
|
80
|
+
## Notes
|
|
81
|
+
|
|
82
|
+
- PyPI distribution name: `relintio-agent`
|
|
83
|
+
- Import path: `relintio_agent` (recommended)
|
|
84
|
+
- Legacy import path still supported: `ultimateprotector_agent`
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## Options
|
|
88
|
+
|
|
89
|
+
- `license_key` (required)
|
|
90
|
+
- `api_url` (required) e.g. `https://relintio.com/api`
|
|
91
|
+
- `sync_interval_seconds` (default: `60`)
|
|
92
|
+
- `allow_sample_rate` (default: `0.01`)
|
|
93
|
+
- `only_paths`: list[str] exact (`/checkout`) or prefix (`/product/*`)
|
|
94
|
+
- `except_paths`: list[str]
|
|
95
|
+
- `only_regex`: str (Python regex)
|
|
96
|
+
|
|
97
|
+
## Geo Enrichment
|
|
98
|
+
|
|
99
|
+
When CDN geo headers (`CF-IPCountry`, etc.) are absent, the agent calls the platform's `/api/agent/geo-lookup` endpoint.
|
|
100
|
+
The server resolves the country using **local MaxMind GeoLite2 databases** — zero external API calls, zero cost, microsecond latency.
|
|
101
|
+
Results are cached in-memory (24h TTL) to minimize round-trips.
|
|
102
|
+
|
|
103
|
+
## Changelog
|
|
104
|
+
|
|
105
|
+
### 0.9.3
|
|
106
|
+
|
|
107
|
+
- **Import path alignment** - `relintio_agent` is now the documented import path, with `ultimateprotector_agent` kept as a compatibility alias.
|
|
108
|
+
- **Version telemetry alignment** - Runtime telemetry now reports `0.9.3`, matching the PyPI package version and release tag.
|
|
109
|
+
|
|
110
|
+
### 0.5.0
|
|
111
|
+
|
|
112
|
+
- **Additive risk-scoring engine** — 0-100 signal-based scoring with 7 weighted signals.
|
|
113
|
+
- **5-tier graduated response** — ALLOW, SLOW (`asyncio.sleep(2.0)`), CHALLENGE, DECOY, BLOCK.
|
|
114
|
+
- **Token-bucket rate limiter** — Replaces fixed-window counter. 8 tokens/sec, 24 burst, route-aware multipliers.
|
|
115
|
+
- **`risk_score` telemetry** — Agent-calculated score forwarded to server in log payload.
|
|
116
|
+
|
|
117
|
+
### 0.3.0
|
|
118
|
+
|
|
119
|
+
- **Geo enrichment architecture hardened** — The server-side `/api/agent/geo-lookup` endpoint now performs local MaxMind GeoLite2 lookups instead of proxying to `ipinfo.io`. Agent behaviour is unchanged; the improvement is server-side.
|
|
120
|
+
|
|
121
|
+
### 0.2.0
|
|
122
|
+
|
|
123
|
+
- **HMAC payload verification** — Rules payloads are now authenticated with HMAC-SHA256 before decryption. Requires platform ≥ 2026-04.
|
|
124
|
+
- **`X-Agent-Version` header** — Sent on every `/verify` request for dashboard version tracking.
|
|
125
|
+
- **`outdated` status handling** — If the cloud responds with `outdated`, the agent fails open and stops protecting until updated.
|
|
126
|
+
|
|
127
|
+
### 0.1.1
|
|
128
|
+
|
|
129
|
+
- Initial stable release with AES-256-CBC encrypted rules sync.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "relintio-agent"
|
|
7
|
+
version = "0.9.5"
|
|
8
|
+
description = "RelintioAgent in-process agent for Python ASGI runtimes."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "LicenseRef-Proprietary"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.26",
|
|
15
|
+
"cryptography>=42",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://github.com/relintio/Relintio"
|
|
20
|
+
Repository = "https://github.com/relintio/Relintio"
|
|
21
|
+
Issues = "https://github.com/relintio/Relintio/issues"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools]
|
|
24
|
+
package-dir = {"" = "src"}
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Compatibility import path.
|
|
2
|
+
|
|
3
|
+
The distribution name on PyPI is `relintio-agent`.
|
|
4
|
+
|
|
5
|
+
Historically the internal module path was `ultimateprotector_agent`.
|
|
6
|
+
To reduce confusion for new users, we provide `relintio_agent` as
|
|
7
|
+
an alias that re-exports the public API.
|
|
8
|
+
|
|
9
|
+
Both imports are supported:
|
|
10
|
+
|
|
11
|
+
from relintio_agent.asgi import UltimateProtectorMiddleware
|
|
12
|
+
from ultimateprotector_agent.asgi import UltimateProtectorMiddleware
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from ultimateprotector_agent.asgi import UltimateProtectorMiddleware
|
|
16
|
+
from ultimateprotector_agent.auto import config_from_env, wrap_asgi_app
|
|
17
|
+
|
|
18
|
+
__all__ = ["UltimateProtectorMiddleware", "config_from_env", "wrap_asgi_app"]
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: relintio-agent
|
|
3
|
+
Version: 0.9.5
|
|
4
|
+
Summary: RelintioAgent in-process agent for Python ASGI runtimes.
|
|
5
|
+
License-Expression: LicenseRef-Proprietary
|
|
6
|
+
Project-URL: Homepage, https://github.com/relintio/Relintio
|
|
7
|
+
Project-URL: Repository, https://github.com/relintio/Relintio
|
|
8
|
+
Project-URL: Issues, https://github.com/relintio/Relintio/issues
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: httpx>=0.26
|
|
13
|
+
Requires-Dist: cryptography>=42
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# relintio-agent (Python)
|
|
17
|
+
|
|
18
|
+
> **Note on Features & Quotas**: Advanced features (like Bot Challenge and Custom Shield Pages) are tied to your subscription plan. If you exceed your monthly API quota, the agent will operate in a degraded mode (basic protection) before ultimately failing-open to prevent locking you out of your own site. All configuration rules are centrally managed via the dashboard.
|
|
19
|
+
|
|
20
|
+
Python in-process agent for ASGI runtimes (FastAPI/Starlette/etc).
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install relintio-agent
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## FastAPI usage
|
|
29
|
+
|
|
30
|
+
```py
|
|
31
|
+
from fastapi import FastAPI
|
|
32
|
+
from relintio_agent.asgi import UltimateProtectorMiddleware
|
|
33
|
+
|
|
34
|
+
app = FastAPI()
|
|
35
|
+
|
|
36
|
+
app.add_middleware(
|
|
37
|
+
UltimateProtectorMiddleware,
|
|
38
|
+
license_key="UP_LIVE_...",
|
|
39
|
+
api_url="https://relintio.com/api",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Zero-code-ish usage (env wrapper)
|
|
45
|
+
|
|
46
|
+
If you can change *how* the app is created (but don't want to paste config into code),
|
|
47
|
+
wrap the ASGI app using env vars:
|
|
48
|
+
|
|
49
|
+
```py
|
|
50
|
+
import os
|
|
51
|
+
from fastapi import FastAPI
|
|
52
|
+
from relintio_agent import wrap_asgi_app
|
|
53
|
+
|
|
54
|
+
app = wrap_asgi_app(FastAPI())
|
|
55
|
+
|
|
56
|
+
# env:
|
|
57
|
+
# UP_LICENSE_KEY=UP_LIVE_...
|
|
58
|
+
# UP_API_URL=https://relintio.com/api
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Optional: sitecustomize bootstrap
|
|
62
|
+
|
|
63
|
+
The platform can generate a `sitecustomize.py` helper inside the **Python auto bundle**.
|
|
64
|
+
If that file is on `PYTHONPATH`, Python auto-imports it on startup.
|
|
65
|
+
Set `UP_ASGI_APP="module:app"` and it will best-effort wrap that object automatically (fail-open).
|
|
66
|
+
|
|
67
|
+
## Risk Scoring Engine (v0.9.3)
|
|
68
|
+
|
|
69
|
+
Every request is evaluated using an **additive 0-100 signal-based score**. Signals include:
|
|
70
|
+
|
|
71
|
+
| Signal | Weight | Description |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| Empty User-Agent | +50 | No UA header sent |
|
|
74
|
+
| Short User-Agent | +25 | UA < 20 characters |
|
|
75
|
+
| No Accept-Language | +20 | Missing browser locale header |
|
|
76
|
+
| Generic Accept | +15 | Wildcard `*/*` only |
|
|
77
|
+
| Connection: close | +10 | Non-persistent connection |
|
|
78
|
+
| POST without Referer | +15 | Form submission without origin |
|
|
79
|
+
| Rate burst | +35 | Token-bucket exhaustion |
|
|
80
|
+
|
|
81
|
+
### Response Tiers
|
|
82
|
+
|
|
83
|
+
| Tier | Score Range | Behavior |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| **ALLOW** | 0–39 | Request proceeds normally |
|
|
86
|
+
| **SLOW** | 40–59 | 2-second `asyncio.sleep` to exhaust scanners |
|
|
87
|
+
| **CHALLENGE** | 60–74 | Browser verification challenge |
|
|
88
|
+
| **DECOY** | 75–84 | Serves fake maintenance page |
|
|
89
|
+
| **BLOCK** | 85–100 | Hard block with configured response |
|
|
90
|
+
|
|
91
|
+
### Token-Bucket Rate Limiter
|
|
92
|
+
|
|
93
|
+
Default: **8 tokens/sec**, burst capacity of **24**. Route-aware multipliers give extra capacity to static assets. Memory-safe with 5-minute eviction via `asyncio`-compatible dict.
|
|
94
|
+
|
|
95
|
+
## Notes
|
|
96
|
+
|
|
97
|
+
- PyPI distribution name: `relintio-agent`
|
|
98
|
+
- Import path: `relintio_agent` (recommended)
|
|
99
|
+
- Legacy import path still supported: `ultimateprotector_agent`
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## Options
|
|
103
|
+
|
|
104
|
+
- `license_key` (required)
|
|
105
|
+
- `api_url` (required) e.g. `https://relintio.com/api`
|
|
106
|
+
- `sync_interval_seconds` (default: `60`)
|
|
107
|
+
- `allow_sample_rate` (default: `0.01`)
|
|
108
|
+
- `only_paths`: list[str] exact (`/checkout`) or prefix (`/product/*`)
|
|
109
|
+
- `except_paths`: list[str]
|
|
110
|
+
- `only_regex`: str (Python regex)
|
|
111
|
+
|
|
112
|
+
## Geo Enrichment
|
|
113
|
+
|
|
114
|
+
When CDN geo headers (`CF-IPCountry`, etc.) are absent, the agent calls the platform's `/api/agent/geo-lookup` endpoint.
|
|
115
|
+
The server resolves the country using **local MaxMind GeoLite2 databases** — zero external API calls, zero cost, microsecond latency.
|
|
116
|
+
Results are cached in-memory (24h TTL) to minimize round-trips.
|
|
117
|
+
|
|
118
|
+
## Changelog
|
|
119
|
+
|
|
120
|
+
### 0.9.3
|
|
121
|
+
|
|
122
|
+
- **Import path alignment** - `relintio_agent` is now the documented import path, with `ultimateprotector_agent` kept as a compatibility alias.
|
|
123
|
+
- **Version telemetry alignment** - Runtime telemetry now reports `0.9.3`, matching the PyPI package version and release tag.
|
|
124
|
+
|
|
125
|
+
### 0.5.0
|
|
126
|
+
|
|
127
|
+
- **Additive risk-scoring engine** — 0-100 signal-based scoring with 7 weighted signals.
|
|
128
|
+
- **5-tier graduated response** — ALLOW, SLOW (`asyncio.sleep(2.0)`), CHALLENGE, DECOY, BLOCK.
|
|
129
|
+
- **Token-bucket rate limiter** — Replaces fixed-window counter. 8 tokens/sec, 24 burst, route-aware multipliers.
|
|
130
|
+
- **`risk_score` telemetry** — Agent-calculated score forwarded to server in log payload.
|
|
131
|
+
|
|
132
|
+
### 0.3.0
|
|
133
|
+
|
|
134
|
+
- **Geo enrichment architecture hardened** — The server-side `/api/agent/geo-lookup` endpoint now performs local MaxMind GeoLite2 lookups instead of proxying to `ipinfo.io`. Agent behaviour is unchanged; the improvement is server-side.
|
|
135
|
+
|
|
136
|
+
### 0.2.0
|
|
137
|
+
|
|
138
|
+
- **HMAC payload verification** — Rules payloads are now authenticated with HMAC-SHA256 before decryption. Requires platform ≥ 2026-04.
|
|
139
|
+
- **`X-Agent-Version` header** — Sent on every `/verify` request for dashboard version tracking.
|
|
140
|
+
- **`outdated` status handling** — If the cloud responds with `outdated`, the agent fails open and stops protecting until updated.
|
|
141
|
+
|
|
142
|
+
### 0.1.1
|
|
143
|
+
|
|
144
|
+
- Initial stable release with AES-256-CBC encrypted rules sync.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/auraprotector_agent/__init__.py
|
|
5
|
+
src/auraprotector_agent/asgi.py
|
|
6
|
+
src/auraprotector_agent/auto.py
|
|
7
|
+
src/relintio_agent.egg-info/PKG-INFO
|
|
8
|
+
src/relintio_agent.egg-info/SOURCES.txt
|
|
9
|
+
src/relintio_agent.egg-info/dependency_links.txt
|
|
10
|
+
src/relintio_agent.egg-info/requires.txt
|
|
11
|
+
src/relintio_agent.egg-info/top_level.txt
|
|
12
|
+
src/ultimateprotector_agent/__init__.py
|
|
13
|
+
src/ultimateprotector_agent/asgi.py
|
|
14
|
+
src/ultimateprotector_agent/auto.py
|
|
15
|
+
src/ultimateprotector_agent/client.py
|
|
16
|
+
src/ultimateprotector_agent/obsidian.py
|
|
17
|
+
src/ultimateprotector_agent/sitecustomize.py
|
|
18
|
+
src/ultimateprotector_agent/utils.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|