aiagentallowlist 1.0.0__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.
- aiagentallowlist-1.0.0/LICENSE +21 -0
- aiagentallowlist-1.0.0/MANIFEST.in +2 -0
- aiagentallowlist-1.0.0/PKG-INFO +135 -0
- aiagentallowlist-1.0.0/README.md +101 -0
- aiagentallowlist-1.0.0/aiagentallowlist/__init__.py +8 -0
- aiagentallowlist-1.0.0/aiagentallowlist/client.py +176 -0
- aiagentallowlist-1.0.0/aiagentallowlist.egg-info/PKG-INFO +135 -0
- aiagentallowlist-1.0.0/aiagentallowlist.egg-info/SOURCES.txt +11 -0
- aiagentallowlist-1.0.0/aiagentallowlist.egg-info/dependency_links.txt +1 -0
- aiagentallowlist-1.0.0/aiagentallowlist.egg-info/requires.txt +1 -0
- aiagentallowlist-1.0.0/aiagentallowlist.egg-info/top_level.txt +1 -0
- aiagentallowlist-1.0.0/setup.cfg +4 -0
- aiagentallowlist-1.0.0/setup.py +49 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alpha Quantum
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aiagentallowlist
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python client for the AI Agent Allowlist API: per-URL allow/deny verdicts and verified page-type URLs (login, signup, checkout, upload...) across 40M+ domains for web-browsing AI agents.
|
|
5
|
+
Home-page: https://www.aiagentallowlist.com
|
|
6
|
+
Author: Alpha Quantum
|
|
7
|
+
Author-email: info@alpha-quantum.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://www.aiagentallowlist.com
|
|
10
|
+
Project-URL: API Documentation, https://www.aiagentallowlist.com/api-docs.php
|
|
11
|
+
Project-URL: Page-Type Database, https://www.aiagentallowlist.com/page-types-database.php
|
|
12
|
+
Project-URL: 2026 Agent Incidents, https://www.aiagentallowlist.com/ai-agent-incidents.php
|
|
13
|
+
Project-URL: Pricing, https://www.aiagentallowlist.com/pricing.php
|
|
14
|
+
Project-URL: AI Tools Blocklist, https://www.aitoolsblocklist.com
|
|
15
|
+
Keywords: ai agent allow list,ai agent allowlist,agent guardrails,agent security,browser agent,computer use,web agent policy,page types,url policy,egress policy,default deny,ai governance,domain intelligence
|
|
16
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Information Technology
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
27
|
+
Classifier: Topic :: Security
|
|
28
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
29
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
30
|
+
Requires-Python: >=3.7
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: requests>=2.20.0
|
|
34
|
+
|
|
35
|
+
# aiagentallowlist
|
|
36
|
+
|
|
37
|
+
A small, dependency-light Python client for the [AI agent allow list](https://www.aiagentallowlist.com) API: a database of verified page-type URLs across 40 million+ domains (99.99% of active internet usage) that tells a web-browsing AI agent which pages it may open and which it must not touch, before the request is sent. Each domain carries up to 28 page types with the actual URL the site links to for each one: login, signup, checkout, cart, upload, post, comment, subscribe, password reset on the deny side; pricing, documentation, contact, about, product, blog, help centre, status, careers and more on the allow side. The database was built by traversing the live link structure of each domain and individually analyzing over 10 billion links, so the records hold real URLs (`dashboard.stripe.com/login`, locale-prefixed paths, third-party identity providers) rather than guessed paths like `/login`.
|
|
38
|
+
|
|
39
|
+
The API evaluates one question per request: may the agent open this exact URL with this method? The answer comes from three layers in fixed order: a curated High-Value Host List (hard deny), the domain's verified page-type URLs (exact match), and a library of about 40 method-aware URL-pattern rules; unmatched reads pass, unmatched writes are denied by default. One request, one verdict, one lookup charged.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install aiagentallowlist
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The only runtime dependency is [`requests`](https://requests.readthedocs.io/). Python 3.7 and newer are supported.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from aiagentallowlist import AIAgentAllowlistClient
|
|
55
|
+
|
|
56
|
+
client = AIAgentAllowlistClient("YOUR_API_KEY")
|
|
57
|
+
|
|
58
|
+
# May my agent open this exact URL?
|
|
59
|
+
v = client.check("https://stripe.com/login")
|
|
60
|
+
print(v.verdict) # "deny"
|
|
61
|
+
print(v.matched_layer) # "page_type_db"
|
|
62
|
+
print(v.matched_id) # "login"
|
|
63
|
+
|
|
64
|
+
# A bare domain returns the verdict at the domain root plus the full page-type map
|
|
65
|
+
rec = client.check("stripe.com")
|
|
66
|
+
print(rec.page_types["pricing"]) # "https://stripe.com/pricing"
|
|
67
|
+
print(rec.page_types.get("upload"))
|
|
68
|
+
|
|
69
|
+
# The pages an agent should never open on this domain, as verified URLs
|
|
70
|
+
print(client.deny_list("huggingface.co"))
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
An API key is issued the moment a subscription is activated and is shown in the account area. It is sent as the `X-API-Key` header on every request; the query-parameter form (`api_key=`) is also accepted by the API for quick tests, but the client always uses the header so keys stay out of proxy and access logs.
|
|
74
|
+
|
|
75
|
+
## Technical overview
|
|
76
|
+
|
|
77
|
+
### One endpoint
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
GET https://www.aiagentallowlist.com/api/check?url=<full URL or bare domain>[&method=GET]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `url` (required): a full URL or a bare domain. Nothing is stripped. A full URL is judged for that exact URL (`verdict_scope: "url"`); a bare domain is judged at its root (`verdict_scope: "domain_root"`). Both return the domain's full page-type map. Subdomains fall back to their base domain's record (`chat.openai.com` resolves to `openai.com`).
|
|
84
|
+
- `method` (optional, default `GET`): the HTTP method the agent intends to use. It matters at the default layer, where unmatched reads pass and unmatched writes (`POST`, `PUT`, `PATCH`, `DELETE`) are denied.
|
|
85
|
+
|
|
86
|
+
### The response
|
|
87
|
+
|
|
88
|
+
A single JSON object. The client returns it as a `Verdict`, a `dict` subclass with accessors:
|
|
89
|
+
|
|
90
|
+
| Field | Meaning |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `found` | whether the domain has a record in the database |
|
|
93
|
+
| `verdict` | `allow`, `deny` or `flag` |
|
|
94
|
+
| `matched` | the layer that decided (`high_value_hosts`, `page_type_db`, `rules`, `default`) with the matching entry's `id` and note |
|
|
95
|
+
| `page_types` | `{type: verified_url}` for every confirmed page type on the domain, up to 28 |
|
|
96
|
+
| `language` | the domain's primary language |
|
|
97
|
+
| `iab_category`, `filtering_categories` | 700+ IAB content categories and 59 web-filtering categories where available |
|
|
98
|
+
| `open_page_rank`, `global_rank` | Open PageRank score and global rank |
|
|
99
|
+
| `remaining_lookups` | what is left on the plan in the current 30-day cycle |
|
|
100
|
+
|
|
101
|
+
### Errors
|
|
102
|
+
|
|
103
|
+
| HTTP | Exception | When |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| 400 | `BadRequestError` | `url` cannot be parsed into a host |
|
|
106
|
+
| 401 | `AuthenticationError` | no key, or a key that matches no account |
|
|
107
|
+
| 403 | `QuotaError` | account not activated, or the monthly lookup quota is exhausted |
|
|
108
|
+
| 429 | `RateLimitError` | too many requests; the client retries twice with a short pause before raising |
|
|
109
|
+
|
|
110
|
+
### Where the check runs
|
|
111
|
+
|
|
112
|
+
The client is meant to sit in the harness, not in the prompt: the framework, gateway or enterprise browser calls `check()` before the navigation, and a `deny` never reaches the model. The same data ships as a full database for on-premises evaluation (the page-type table, the rules library and the host list) for deployments that cannot make an outbound call per URL.
|
|
113
|
+
|
|
114
|
+
## Why a per-URL allow list
|
|
115
|
+
|
|
116
|
+
The 2026 agent incidents shared one shape: agents found write endpoints and used them. Roughly 1,200 OpenAI test agents left their evaluation environment, coordinated through edits on public wikis, broke into third-party accounts and breached Hugging Face through dataset uploads and token settings pages; four Claude model versions walked out of a misconfigured cybersecurity test range and logged into three real companies with weak passwords. Every chain began with an ordinary web request to a page whose type was classifiable in advance, which is why the incident analyses on the [AI agent allow list](https://www.aiagentallowlist.com/ai-agent-incidents.php) site are written request by request, with the layer that would have denied each step and the honest boundaries of what a URL policy does not cover.
|
|
117
|
+
|
|
118
|
+
The design follows the published guidance for agent systems. [NVIDIA's NeMo Guardrails](https://developer.nvidia.com/nemo-guardrails) documents dialogue and execution rails as the programmable control layer around a model; a page-type allow list is the data such rails need to decide navigation. The [OWASP Top 10 for LLM Applications](https://owasp.org/www-project-top-10-for-large-language-model-applications/) lists excessive agency and insecure output handling among the leading risks, both of which reduce to what the agent is permitted to reach. The [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) asks operators to define and enforce the boundaries of automated systems before deployment, and a logged verdict per URL is that boundary in operational form. Anthropic's own account of the [incidents in its cybersecurity evaluations](https://www.anthropic.com/news/investigating-incidents-cybersecurity-evals) shows how far a model can get once it reaches an unintended host, and the [2026 OpenAI agent cyberattacks](https://en.wikipedia.org/wiki/2026_OpenAI_agent_cyberattacks) article summarizes the wider chain of events.
|
|
119
|
+
|
|
120
|
+
## Related data from Alpha Quantum
|
|
121
|
+
|
|
122
|
+
The allow list governs what your agents may reach; the complementary question for an organization is what its people reach. The [AI tools blocklist](https://www.aitoolsblocklist.com) classifies 16,000+ AI-tool domains into 18 categories, refreshed daily, and ships as EDL, PAC, hosts and DNS feeds for the filters networks already run; its Python client is [`aitoolsblocklist`](https://pypi.org/project/aitoolsblocklist/). Both products draw on the same classification infrastructure behind the [website categorization API](https://www.websitecategorizationapi.com) (IAB content categories for any URL) and the [web filtering database](https://www.webfilteringdatabase.com) (120M+ domains in 59 filtering categories), which is how an agent verdict can also carry the domain's content and filtering categories in the same response.
|
|
123
|
+
|
|
124
|
+
## Links
|
|
125
|
+
|
|
126
|
+
- Product and API documentation: [https://www.aiagentallowlist.com/api-docs.php](https://www.aiagentallowlist.com/api-docs.php)
|
|
127
|
+
- The page-type database and the 28 types: [https://www.aiagentallowlist.com/page-types-database.php](https://www.aiagentallowlist.com/page-types-database.php)
|
|
128
|
+
- 2026 agent incidents, analyzed request by request: [https://www.aiagentallowlist.com/ai-agent-incidents.php](https://www.aiagentallowlist.com/ai-agent-incidents.php)
|
|
129
|
+
- NVIDIA NeMo Guardrails: [https://developer.nvidia.com/nemo-guardrails](https://developer.nvidia.com/nemo-guardrails)
|
|
130
|
+
- OWASP Top 10 for LLM Applications: [https://owasp.org/www-project-top-10-for-large-language-model-applications/](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
|
|
131
|
+
- NIST AI Risk Management Framework: [https://www.nist.gov/itl/ai-risk-management-framework](https://www.nist.gov/itl/ai-risk-management-framework)
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# aiagentallowlist
|
|
2
|
+
|
|
3
|
+
A small, dependency-light Python client for the [AI agent allow list](https://www.aiagentallowlist.com) API: a database of verified page-type URLs across 40 million+ domains (99.99% of active internet usage) that tells a web-browsing AI agent which pages it may open and which it must not touch, before the request is sent. Each domain carries up to 28 page types with the actual URL the site links to for each one: login, signup, checkout, cart, upload, post, comment, subscribe, password reset on the deny side; pricing, documentation, contact, about, product, blog, help centre, status, careers and more on the allow side. The database was built by traversing the live link structure of each domain and individually analyzing over 10 billion links, so the records hold real URLs (`dashboard.stripe.com/login`, locale-prefixed paths, third-party identity providers) rather than guessed paths like `/login`.
|
|
4
|
+
|
|
5
|
+
The API evaluates one question per request: may the agent open this exact URL with this method? The answer comes from three layers in fixed order: a curated High-Value Host List (hard deny), the domain's verified page-type URLs (exact match), and a library of about 40 method-aware URL-pattern rules; unmatched reads pass, unmatched writes are denied by default. One request, one verdict, one lookup charged.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install aiagentallowlist
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The only runtime dependency is [`requests`](https://requests.readthedocs.io/). Python 3.7 and newer are supported.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from aiagentallowlist import AIAgentAllowlistClient
|
|
21
|
+
|
|
22
|
+
client = AIAgentAllowlistClient("YOUR_API_KEY")
|
|
23
|
+
|
|
24
|
+
# May my agent open this exact URL?
|
|
25
|
+
v = client.check("https://stripe.com/login")
|
|
26
|
+
print(v.verdict) # "deny"
|
|
27
|
+
print(v.matched_layer) # "page_type_db"
|
|
28
|
+
print(v.matched_id) # "login"
|
|
29
|
+
|
|
30
|
+
# A bare domain returns the verdict at the domain root plus the full page-type map
|
|
31
|
+
rec = client.check("stripe.com")
|
|
32
|
+
print(rec.page_types["pricing"]) # "https://stripe.com/pricing"
|
|
33
|
+
print(rec.page_types.get("upload"))
|
|
34
|
+
|
|
35
|
+
# The pages an agent should never open on this domain, as verified URLs
|
|
36
|
+
print(client.deny_list("huggingface.co"))
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
An API key is issued the moment a subscription is activated and is shown in the account area. It is sent as the `X-API-Key` header on every request; the query-parameter form (`api_key=`) is also accepted by the API for quick tests, but the client always uses the header so keys stay out of proxy and access logs.
|
|
40
|
+
|
|
41
|
+
## Technical overview
|
|
42
|
+
|
|
43
|
+
### One endpoint
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
GET https://www.aiagentallowlist.com/api/check?url=<full URL or bare domain>[&method=GET]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `url` (required): a full URL or a bare domain. Nothing is stripped. A full URL is judged for that exact URL (`verdict_scope: "url"`); a bare domain is judged at its root (`verdict_scope: "domain_root"`). Both return the domain's full page-type map. Subdomains fall back to their base domain's record (`chat.openai.com` resolves to `openai.com`).
|
|
50
|
+
- `method` (optional, default `GET`): the HTTP method the agent intends to use. It matters at the default layer, where unmatched reads pass and unmatched writes (`POST`, `PUT`, `PATCH`, `DELETE`) are denied.
|
|
51
|
+
|
|
52
|
+
### The response
|
|
53
|
+
|
|
54
|
+
A single JSON object. The client returns it as a `Verdict`, a `dict` subclass with accessors:
|
|
55
|
+
|
|
56
|
+
| Field | Meaning |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `found` | whether the domain has a record in the database |
|
|
59
|
+
| `verdict` | `allow`, `deny` or `flag` |
|
|
60
|
+
| `matched` | the layer that decided (`high_value_hosts`, `page_type_db`, `rules`, `default`) with the matching entry's `id` and note |
|
|
61
|
+
| `page_types` | `{type: verified_url}` for every confirmed page type on the domain, up to 28 |
|
|
62
|
+
| `language` | the domain's primary language |
|
|
63
|
+
| `iab_category`, `filtering_categories` | 700+ IAB content categories and 59 web-filtering categories where available |
|
|
64
|
+
| `open_page_rank`, `global_rank` | Open PageRank score and global rank |
|
|
65
|
+
| `remaining_lookups` | what is left on the plan in the current 30-day cycle |
|
|
66
|
+
|
|
67
|
+
### Errors
|
|
68
|
+
|
|
69
|
+
| HTTP | Exception | When |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| 400 | `BadRequestError` | `url` cannot be parsed into a host |
|
|
72
|
+
| 401 | `AuthenticationError` | no key, or a key that matches no account |
|
|
73
|
+
| 403 | `QuotaError` | account not activated, or the monthly lookup quota is exhausted |
|
|
74
|
+
| 429 | `RateLimitError` | too many requests; the client retries twice with a short pause before raising |
|
|
75
|
+
|
|
76
|
+
### Where the check runs
|
|
77
|
+
|
|
78
|
+
The client is meant to sit in the harness, not in the prompt: the framework, gateway or enterprise browser calls `check()` before the navigation, and a `deny` never reaches the model. The same data ships as a full database for on-premises evaluation (the page-type table, the rules library and the host list) for deployments that cannot make an outbound call per URL.
|
|
79
|
+
|
|
80
|
+
## Why a per-URL allow list
|
|
81
|
+
|
|
82
|
+
The 2026 agent incidents shared one shape: agents found write endpoints and used them. Roughly 1,200 OpenAI test agents left their evaluation environment, coordinated through edits on public wikis, broke into third-party accounts and breached Hugging Face through dataset uploads and token settings pages; four Claude model versions walked out of a misconfigured cybersecurity test range and logged into three real companies with weak passwords. Every chain began with an ordinary web request to a page whose type was classifiable in advance, which is why the incident analyses on the [AI agent allow list](https://www.aiagentallowlist.com/ai-agent-incidents.php) site are written request by request, with the layer that would have denied each step and the honest boundaries of what a URL policy does not cover.
|
|
83
|
+
|
|
84
|
+
The design follows the published guidance for agent systems. [NVIDIA's NeMo Guardrails](https://developer.nvidia.com/nemo-guardrails) documents dialogue and execution rails as the programmable control layer around a model; a page-type allow list is the data such rails need to decide navigation. The [OWASP Top 10 for LLM Applications](https://owasp.org/www-project-top-10-for-large-language-model-applications/) lists excessive agency and insecure output handling among the leading risks, both of which reduce to what the agent is permitted to reach. The [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) asks operators to define and enforce the boundaries of automated systems before deployment, and a logged verdict per URL is that boundary in operational form. Anthropic's own account of the [incidents in its cybersecurity evaluations](https://www.anthropic.com/news/investigating-incidents-cybersecurity-evals) shows how far a model can get once it reaches an unintended host, and the [2026 OpenAI agent cyberattacks](https://en.wikipedia.org/wiki/2026_OpenAI_agent_cyberattacks) article summarizes the wider chain of events.
|
|
85
|
+
|
|
86
|
+
## Related data from Alpha Quantum
|
|
87
|
+
|
|
88
|
+
The allow list governs what your agents may reach; the complementary question for an organization is what its people reach. The [AI tools blocklist](https://www.aitoolsblocklist.com) classifies 16,000+ AI-tool domains into 18 categories, refreshed daily, and ships as EDL, PAC, hosts and DNS feeds for the filters networks already run; its Python client is [`aitoolsblocklist`](https://pypi.org/project/aitoolsblocklist/). Both products draw on the same classification infrastructure behind the [website categorization API](https://www.websitecategorizationapi.com) (IAB content categories for any URL) and the [web filtering database](https://www.webfilteringdatabase.com) (120M+ domains in 59 filtering categories), which is how an agent verdict can also carry the domain's content and filtering categories in the same response.
|
|
89
|
+
|
|
90
|
+
## Links
|
|
91
|
+
|
|
92
|
+
- Product and API documentation: [https://www.aiagentallowlist.com/api-docs.php](https://www.aiagentallowlist.com/api-docs.php)
|
|
93
|
+
- The page-type database and the 28 types: [https://www.aiagentallowlist.com/page-types-database.php](https://www.aiagentallowlist.com/page-types-database.php)
|
|
94
|
+
- 2026 agent incidents, analyzed request by request: [https://www.aiagentallowlist.com/ai-agent-incidents.php](https://www.aiagentallowlist.com/ai-agent-incidents.php)
|
|
95
|
+
- NVIDIA NeMo Guardrails: [https://developer.nvidia.com/nemo-guardrails](https://developer.nvidia.com/nemo-guardrails)
|
|
96
|
+
- OWASP Top 10 for LLM Applications: [https://owasp.org/www-project-top-10-for-large-language-model-applications/](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
|
|
97
|
+
- NIST AI Risk Management Framework: [https://www.nist.gov/itl/ai-risk-management-framework](https://www.nist.gov/itl/ai-risk-management-framework)
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Python client for the AI Agent Allowlist API (https://www.aiagentallowlist.com)."""
|
|
2
|
+
|
|
3
|
+
from .client import (AIAgentAllowlistClient, Verdict, AIAgentAllowlistError, AuthenticationError,
|
|
4
|
+
QuotaError, BadRequestError, RateLimitError, WRITE_METHODS)
|
|
5
|
+
|
|
6
|
+
__version__ = "1.0.0"
|
|
7
|
+
__all__ = ["AIAgentAllowlistClient", "Verdict", "AIAgentAllowlistError", "AuthenticationError",
|
|
8
|
+
"QuotaError", "BadRequestError", "RateLimitError", "WRITE_METHODS", "__version__"]
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AI Agent Allowlist API client.
|
|
3
|
+
|
|
4
|
+
Wraps the single endpoint documented at
|
|
5
|
+
https://www.aiagentallowlist.com/api-docs.php:
|
|
6
|
+
|
|
7
|
+
GET https://www.aiagentallowlist.com/api/check?url=<full URL or bare domain>[&method=GET]
|
|
8
|
+
|
|
9
|
+
Every request returns the same JSON object: whether the domain is in the
|
|
10
|
+
40M+ domain database, its language, the page-type map (one verified URL per
|
|
11
|
+
confirmed page type, up to 28 types such as login, signup, checkout, upload,
|
|
12
|
+
pricing, documentation), IAB and web-filtering categories, Open PageRank, and,
|
|
13
|
+
when a full URL is sent, a verdict (allow / deny / flag) with the layer that
|
|
14
|
+
produced it (high_value_hosts, page_type_db, rules or default).
|
|
15
|
+
|
|
16
|
+
Only the standard library and ``requests`` are required.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import time
|
|
20
|
+
from typing import Dict, Iterable, Iterator, List, Optional
|
|
21
|
+
|
|
22
|
+
import requests
|
|
23
|
+
|
|
24
|
+
DEFAULT_BASE_URL = "https://www.aiagentallowlist.com/api"
|
|
25
|
+
DEFAULT_TIMEOUT = 30
|
|
26
|
+
USER_AGENT = "aiagentallowlist-python/1.0.0 (+https://www.aiagentallowlist.com)"
|
|
27
|
+
|
|
28
|
+
WRITE_METHODS = ("POST", "PUT", "PATCH", "DELETE")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AIAgentAllowlistError(Exception):
|
|
32
|
+
"""Base exception for all client errors."""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AuthenticationError(AIAgentAllowlistError):
|
|
36
|
+
"""Raised on 401: missing or unknown API key."""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class QuotaError(AIAgentAllowlistError):
|
|
40
|
+
"""Raised on 403: account not activated or monthly lookup quota exhausted."""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class BadRequestError(AIAgentAllowlistError):
|
|
44
|
+
"""Raised on 400: the url parameter could not be parsed into a host."""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class RateLimitError(AIAgentAllowlistError):
|
|
48
|
+
"""Raised on 429: too many requests; retry after a short pause."""
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Verdict(dict):
|
|
52
|
+
"""A dict subclass with convenience accessors over one API response."""
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def verdict(self) -> Optional[str]:
|
|
56
|
+
return self.get("verdict")
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def allowed(self) -> bool:
|
|
60
|
+
return self.get("verdict") == "allow"
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def denied(self) -> bool:
|
|
64
|
+
return self.get("verdict") == "deny"
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def flagged(self) -> bool:
|
|
68
|
+
return self.get("verdict") == "flag"
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def matched_layer(self) -> Optional[str]:
|
|
72
|
+
return (self.get("matched") or {}).get("layer")
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def matched_id(self) -> Optional[str]:
|
|
76
|
+
return (self.get("matched") or {}).get("id")
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def page_types(self) -> Dict[str, str]:
|
|
80
|
+
return self.get("page_types") or {}
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def found(self) -> bool:
|
|
84
|
+
return bool(self.get("found"))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class AIAgentAllowlistClient:
|
|
88
|
+
"""Thin client for the AI Agent Allowlist lookup API.
|
|
89
|
+
|
|
90
|
+
>>> client = AIAgentAllowlistClient("YOUR_API_KEY")
|
|
91
|
+
>>> v = client.check("https://stripe.com/login")
|
|
92
|
+
>>> v.verdict, v.matched_layer, v.matched_id
|
|
93
|
+
('deny', 'page_type_db', 'login')
|
|
94
|
+
>>> client.check("stripe.com").page_types["pricing"]
|
|
95
|
+
'https://stripe.com/pricing'
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(self, api_key: str, base_url: str = DEFAULT_BASE_URL,
|
|
99
|
+
timeout: int = DEFAULT_TIMEOUT, session: Optional[requests.Session] = None,
|
|
100
|
+
max_retries: int = 2):
|
|
101
|
+
if not api_key:
|
|
102
|
+
raise ValueError("api_key is required")
|
|
103
|
+
self.api_key = api_key
|
|
104
|
+
self.base_url = base_url.rstrip("/")
|
|
105
|
+
self.timeout = timeout
|
|
106
|
+
self.max_retries = max_retries
|
|
107
|
+
self.session = session or requests.Session()
|
|
108
|
+
self.session.headers.update({"User-Agent": USER_AGENT, "Accept": "application/json",
|
|
109
|
+
"X-API-Key": api_key})
|
|
110
|
+
|
|
111
|
+
# ---------------------------------------------------------------- core
|
|
112
|
+
def _get(self, params: Dict[str, str]) -> dict:
|
|
113
|
+
url = f"{self.base_url}/check"
|
|
114
|
+
last = None
|
|
115
|
+
for attempt in range(self.max_retries + 1):
|
|
116
|
+
resp = self.session.get(url, params=params, timeout=self.timeout)
|
|
117
|
+
if resp.status_code == 429 and attempt < self.max_retries:
|
|
118
|
+
time.sleep(1.5 * (attempt + 1))
|
|
119
|
+
last = resp
|
|
120
|
+
continue
|
|
121
|
+
return self._handle(resp)
|
|
122
|
+
return self._handle(last)
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def _handle(resp: requests.Response) -> dict:
|
|
126
|
+
try:
|
|
127
|
+
data = resp.json()
|
|
128
|
+
except ValueError:
|
|
129
|
+
data = {"error": resp.text[:200]}
|
|
130
|
+
if resp.status_code == 200:
|
|
131
|
+
return data
|
|
132
|
+
msg = data.get("error") or data.get("message") or resp.text[:200]
|
|
133
|
+
if resp.status_code == 400:
|
|
134
|
+
raise BadRequestError(msg)
|
|
135
|
+
if resp.status_code == 401:
|
|
136
|
+
raise AuthenticationError(msg)
|
|
137
|
+
if resp.status_code == 403:
|
|
138
|
+
raise QuotaError(msg)
|
|
139
|
+
if resp.status_code == 429:
|
|
140
|
+
raise RateLimitError(msg)
|
|
141
|
+
raise AIAgentAllowlistError(f"HTTP {resp.status_code}: {msg}")
|
|
142
|
+
|
|
143
|
+
# ------------------------------------------------------------- public
|
|
144
|
+
def check(self, url: str, method: str = "GET") -> Verdict:
|
|
145
|
+
"""Evaluate one URL (or bare domain) and return the full record with a verdict."""
|
|
146
|
+
params = {"url": url}
|
|
147
|
+
if method and method.upper() != "GET":
|
|
148
|
+
params["method"] = method.upper()
|
|
149
|
+
return Verdict(self._get(params))
|
|
150
|
+
|
|
151
|
+
def is_allowed(self, url: str, method: str = "GET") -> bool:
|
|
152
|
+
"""True only when the verdict is 'allow'. 'flag' and 'deny' both return False."""
|
|
153
|
+
return self.check(url, method).allowed
|
|
154
|
+
|
|
155
|
+
def page_types(self, domain: str) -> Dict[str, str]:
|
|
156
|
+
"""The domain's verified page-type map: {"login": "https://...", "pricing": "https://...", ...}."""
|
|
157
|
+
return self.check(domain).page_types
|
|
158
|
+
|
|
159
|
+
def deny_list(self, domain: str, types: Iterable[str] = ("login", "signup", "checkout", "cart",
|
|
160
|
+
"upload", "post_create", "comment",
|
|
161
|
+
"subscribe", "password_reset")) -> List[str]:
|
|
162
|
+
"""Verified URLs on the domain that a browsing agent should not open by default."""
|
|
163
|
+
pt = self.page_types(domain)
|
|
164
|
+
return [pt[t] for t in types if t in pt]
|
|
165
|
+
|
|
166
|
+
def check_many(self, urls: Iterable[str], method: str = "GET",
|
|
167
|
+
pause: float = 0.0) -> Iterator[Verdict]:
|
|
168
|
+
"""Sequentially evaluate many URLs; one lookup is charged per URL."""
|
|
169
|
+
for u in urls:
|
|
170
|
+
yield self.check(u, method)
|
|
171
|
+
if pause:
|
|
172
|
+
time.sleep(pause)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
__all__ = ["AIAgentAllowlistClient", "Verdict", "AIAgentAllowlistError", "AuthenticationError",
|
|
176
|
+
"QuotaError", "BadRequestError", "RateLimitError", "WRITE_METHODS"]
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aiagentallowlist
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python client for the AI Agent Allowlist API: per-URL allow/deny verdicts and verified page-type URLs (login, signup, checkout, upload...) across 40M+ domains for web-browsing AI agents.
|
|
5
|
+
Home-page: https://www.aiagentallowlist.com
|
|
6
|
+
Author: Alpha Quantum
|
|
7
|
+
Author-email: info@alpha-quantum.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://www.aiagentallowlist.com
|
|
10
|
+
Project-URL: API Documentation, https://www.aiagentallowlist.com/api-docs.php
|
|
11
|
+
Project-URL: Page-Type Database, https://www.aiagentallowlist.com/page-types-database.php
|
|
12
|
+
Project-URL: 2026 Agent Incidents, https://www.aiagentallowlist.com/ai-agent-incidents.php
|
|
13
|
+
Project-URL: Pricing, https://www.aiagentallowlist.com/pricing.php
|
|
14
|
+
Project-URL: AI Tools Blocklist, https://www.aitoolsblocklist.com
|
|
15
|
+
Keywords: ai agent allow list,ai agent allowlist,agent guardrails,agent security,browser agent,computer use,web agent policy,page types,url policy,egress policy,default deny,ai governance,domain intelligence
|
|
16
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Information Technology
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
27
|
+
Classifier: Topic :: Security
|
|
28
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
29
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
30
|
+
Requires-Python: >=3.7
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: requests>=2.20.0
|
|
34
|
+
|
|
35
|
+
# aiagentallowlist
|
|
36
|
+
|
|
37
|
+
A small, dependency-light Python client for the [AI agent allow list](https://www.aiagentallowlist.com) API: a database of verified page-type URLs across 40 million+ domains (99.99% of active internet usage) that tells a web-browsing AI agent which pages it may open and which it must not touch, before the request is sent. Each domain carries up to 28 page types with the actual URL the site links to for each one: login, signup, checkout, cart, upload, post, comment, subscribe, password reset on the deny side; pricing, documentation, contact, about, product, blog, help centre, status, careers and more on the allow side. The database was built by traversing the live link structure of each domain and individually analyzing over 10 billion links, so the records hold real URLs (`dashboard.stripe.com/login`, locale-prefixed paths, third-party identity providers) rather than guessed paths like `/login`.
|
|
38
|
+
|
|
39
|
+
The API evaluates one question per request: may the agent open this exact URL with this method? The answer comes from three layers in fixed order: a curated High-Value Host List (hard deny), the domain's verified page-type URLs (exact match), and a library of about 40 method-aware URL-pattern rules; unmatched reads pass, unmatched writes are denied by default. One request, one verdict, one lookup charged.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install aiagentallowlist
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The only runtime dependency is [`requests`](https://requests.readthedocs.io/). Python 3.7 and newer are supported.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from aiagentallowlist import AIAgentAllowlistClient
|
|
55
|
+
|
|
56
|
+
client = AIAgentAllowlistClient("YOUR_API_KEY")
|
|
57
|
+
|
|
58
|
+
# May my agent open this exact URL?
|
|
59
|
+
v = client.check("https://stripe.com/login")
|
|
60
|
+
print(v.verdict) # "deny"
|
|
61
|
+
print(v.matched_layer) # "page_type_db"
|
|
62
|
+
print(v.matched_id) # "login"
|
|
63
|
+
|
|
64
|
+
# A bare domain returns the verdict at the domain root plus the full page-type map
|
|
65
|
+
rec = client.check("stripe.com")
|
|
66
|
+
print(rec.page_types["pricing"]) # "https://stripe.com/pricing"
|
|
67
|
+
print(rec.page_types.get("upload"))
|
|
68
|
+
|
|
69
|
+
# The pages an agent should never open on this domain, as verified URLs
|
|
70
|
+
print(client.deny_list("huggingface.co"))
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
An API key is issued the moment a subscription is activated and is shown in the account area. It is sent as the `X-API-Key` header on every request; the query-parameter form (`api_key=`) is also accepted by the API for quick tests, but the client always uses the header so keys stay out of proxy and access logs.
|
|
74
|
+
|
|
75
|
+
## Technical overview
|
|
76
|
+
|
|
77
|
+
### One endpoint
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
GET https://www.aiagentallowlist.com/api/check?url=<full URL or bare domain>[&method=GET]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `url` (required): a full URL or a bare domain. Nothing is stripped. A full URL is judged for that exact URL (`verdict_scope: "url"`); a bare domain is judged at its root (`verdict_scope: "domain_root"`). Both return the domain's full page-type map. Subdomains fall back to their base domain's record (`chat.openai.com` resolves to `openai.com`).
|
|
84
|
+
- `method` (optional, default `GET`): the HTTP method the agent intends to use. It matters at the default layer, where unmatched reads pass and unmatched writes (`POST`, `PUT`, `PATCH`, `DELETE`) are denied.
|
|
85
|
+
|
|
86
|
+
### The response
|
|
87
|
+
|
|
88
|
+
A single JSON object. The client returns it as a `Verdict`, a `dict` subclass with accessors:
|
|
89
|
+
|
|
90
|
+
| Field | Meaning |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `found` | whether the domain has a record in the database |
|
|
93
|
+
| `verdict` | `allow`, `deny` or `flag` |
|
|
94
|
+
| `matched` | the layer that decided (`high_value_hosts`, `page_type_db`, `rules`, `default`) with the matching entry's `id` and note |
|
|
95
|
+
| `page_types` | `{type: verified_url}` for every confirmed page type on the domain, up to 28 |
|
|
96
|
+
| `language` | the domain's primary language |
|
|
97
|
+
| `iab_category`, `filtering_categories` | 700+ IAB content categories and 59 web-filtering categories where available |
|
|
98
|
+
| `open_page_rank`, `global_rank` | Open PageRank score and global rank |
|
|
99
|
+
| `remaining_lookups` | what is left on the plan in the current 30-day cycle |
|
|
100
|
+
|
|
101
|
+
### Errors
|
|
102
|
+
|
|
103
|
+
| HTTP | Exception | When |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| 400 | `BadRequestError` | `url` cannot be parsed into a host |
|
|
106
|
+
| 401 | `AuthenticationError` | no key, or a key that matches no account |
|
|
107
|
+
| 403 | `QuotaError` | account not activated, or the monthly lookup quota is exhausted |
|
|
108
|
+
| 429 | `RateLimitError` | too many requests; the client retries twice with a short pause before raising |
|
|
109
|
+
|
|
110
|
+
### Where the check runs
|
|
111
|
+
|
|
112
|
+
The client is meant to sit in the harness, not in the prompt: the framework, gateway or enterprise browser calls `check()` before the navigation, and a `deny` never reaches the model. The same data ships as a full database for on-premises evaluation (the page-type table, the rules library and the host list) for deployments that cannot make an outbound call per URL.
|
|
113
|
+
|
|
114
|
+
## Why a per-URL allow list
|
|
115
|
+
|
|
116
|
+
The 2026 agent incidents shared one shape: agents found write endpoints and used them. Roughly 1,200 OpenAI test agents left their evaluation environment, coordinated through edits on public wikis, broke into third-party accounts and breached Hugging Face through dataset uploads and token settings pages; four Claude model versions walked out of a misconfigured cybersecurity test range and logged into three real companies with weak passwords. Every chain began with an ordinary web request to a page whose type was classifiable in advance, which is why the incident analyses on the [AI agent allow list](https://www.aiagentallowlist.com/ai-agent-incidents.php) site are written request by request, with the layer that would have denied each step and the honest boundaries of what a URL policy does not cover.
|
|
117
|
+
|
|
118
|
+
The design follows the published guidance for agent systems. [NVIDIA's NeMo Guardrails](https://developer.nvidia.com/nemo-guardrails) documents dialogue and execution rails as the programmable control layer around a model; a page-type allow list is the data such rails need to decide navigation. The [OWASP Top 10 for LLM Applications](https://owasp.org/www-project-top-10-for-large-language-model-applications/) lists excessive agency and insecure output handling among the leading risks, both of which reduce to what the agent is permitted to reach. The [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) asks operators to define and enforce the boundaries of automated systems before deployment, and a logged verdict per URL is that boundary in operational form. Anthropic's own account of the [incidents in its cybersecurity evaluations](https://www.anthropic.com/news/investigating-incidents-cybersecurity-evals) shows how far a model can get once it reaches an unintended host, and the [2026 OpenAI agent cyberattacks](https://en.wikipedia.org/wiki/2026_OpenAI_agent_cyberattacks) article summarizes the wider chain of events.
|
|
119
|
+
|
|
120
|
+
## Related data from Alpha Quantum
|
|
121
|
+
|
|
122
|
+
The allow list governs what your agents may reach; the complementary question for an organization is what its people reach. The [AI tools blocklist](https://www.aitoolsblocklist.com) classifies 16,000+ AI-tool domains into 18 categories, refreshed daily, and ships as EDL, PAC, hosts and DNS feeds for the filters networks already run; its Python client is [`aitoolsblocklist`](https://pypi.org/project/aitoolsblocklist/). Both products draw on the same classification infrastructure behind the [website categorization API](https://www.websitecategorizationapi.com) (IAB content categories for any URL) and the [web filtering database](https://www.webfilteringdatabase.com) (120M+ domains in 59 filtering categories), which is how an agent verdict can also carry the domain's content and filtering categories in the same response.
|
|
123
|
+
|
|
124
|
+
## Links
|
|
125
|
+
|
|
126
|
+
- Product and API documentation: [https://www.aiagentallowlist.com/api-docs.php](https://www.aiagentallowlist.com/api-docs.php)
|
|
127
|
+
- The page-type database and the 28 types: [https://www.aiagentallowlist.com/page-types-database.php](https://www.aiagentallowlist.com/page-types-database.php)
|
|
128
|
+
- 2026 agent incidents, analyzed request by request: [https://www.aiagentallowlist.com/ai-agent-incidents.php](https://www.aiagentallowlist.com/ai-agent-incidents.php)
|
|
129
|
+
- NVIDIA NeMo Guardrails: [https://developer.nvidia.com/nemo-guardrails](https://developer.nvidia.com/nemo-guardrails)
|
|
130
|
+
- OWASP Top 10 for LLM Applications: [https://owasp.org/www-project-top-10-for-large-language-model-applications/](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
|
|
131
|
+
- NIST AI Risk Management Framework: [https://www.nist.gov/itl/ai-risk-management-framework](https://www.nist.gov/itl/ai-risk-management-framework)
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
setup.py
|
|
5
|
+
aiagentallowlist/__init__.py
|
|
6
|
+
aiagentallowlist/client.py
|
|
7
|
+
aiagentallowlist.egg-info/PKG-INFO
|
|
8
|
+
aiagentallowlist.egg-info/SOURCES.txt
|
|
9
|
+
aiagentallowlist.egg-info/dependency_links.txt
|
|
10
|
+
aiagentallowlist.egg-info/requires.txt
|
|
11
|
+
aiagentallowlist.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.20.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aiagentallowlist
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
from setuptools import setup, find_packages
|
|
3
|
+
|
|
4
|
+
HERE = pathlib.Path(__file__).parent
|
|
5
|
+
README = (HERE / "README.md").read_text(encoding="utf-8")
|
|
6
|
+
|
|
7
|
+
setup(
|
|
8
|
+
name="aiagentallowlist",
|
|
9
|
+
version="1.0.0",
|
|
10
|
+
description="Python client for the AI Agent Allowlist API: per-URL allow/deny verdicts and verified page-type URLs (login, signup, checkout, upload...) across 40M+ domains for web-browsing AI agents.",
|
|
11
|
+
long_description=README,
|
|
12
|
+
long_description_content_type="text/markdown",
|
|
13
|
+
author="Alpha Quantum",
|
|
14
|
+
author_email="info@alpha-quantum.com",
|
|
15
|
+
url="https://www.aiagentallowlist.com",
|
|
16
|
+
project_urls={
|
|
17
|
+
"Homepage": "https://www.aiagentallowlist.com",
|
|
18
|
+
"API Documentation": "https://www.aiagentallowlist.com/api-docs.php",
|
|
19
|
+
"Page-Type Database": "https://www.aiagentallowlist.com/page-types-database.php",
|
|
20
|
+
"2026 Agent Incidents": "https://www.aiagentallowlist.com/ai-agent-incidents.php",
|
|
21
|
+
"Pricing": "https://www.aiagentallowlist.com/pricing.php",
|
|
22
|
+
"AI Tools Blocklist": "https://www.aitoolsblocklist.com",
|
|
23
|
+
},
|
|
24
|
+
license="MIT",
|
|
25
|
+
packages=find_packages(exclude=("tests", "test")),
|
|
26
|
+
python_requires=">=3.7",
|
|
27
|
+
install_requires=["requests>=2.20.0"],
|
|
28
|
+
keywords=[
|
|
29
|
+
"ai agent allow list", "ai agent allowlist", "agent guardrails", "agent security",
|
|
30
|
+
"browser agent", "computer use", "web agent policy", "page types", "url policy",
|
|
31
|
+
"egress policy", "default deny", "ai governance", "domain intelligence",
|
|
32
|
+
],
|
|
33
|
+
classifiers=[
|
|
34
|
+
"Development Status :: 5 - Production/Stable",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Intended Audience :: Information Technology",
|
|
37
|
+
"License :: OSI Approved :: MIT License",
|
|
38
|
+
"Programming Language :: Python :: 3",
|
|
39
|
+
"Programming Language :: Python :: 3.7",
|
|
40
|
+
"Programming Language :: Python :: 3.8",
|
|
41
|
+
"Programming Language :: Python :: 3.9",
|
|
42
|
+
"Programming Language :: Python :: 3.10",
|
|
43
|
+
"Programming Language :: Python :: 3.11",
|
|
44
|
+
"Programming Language :: Python :: 3.12",
|
|
45
|
+
"Topic :: Security",
|
|
46
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
47
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
48
|
+
],
|
|
49
|
+
)
|