authyouragent 0.3.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.
- authyouragent-0.3.0/PKG-INFO +149 -0
- authyouragent-0.3.0/README.md +131 -0
- authyouragent-0.3.0/authyouragent/__init__.py +34 -0
- authyouragent-0.3.0/authyouragent/__main__.py +6 -0
- authyouragent-0.3.0/authyouragent/agent.py +476 -0
- authyouragent-0.3.0/authyouragent/mcp_server.py +397 -0
- authyouragent-0.3.0/authyouragent/site.py +589 -0
- authyouragent-0.3.0/authyouragent/takeover.py +330 -0
- authyouragent-0.3.0/authyouragent/vault_cli.py +214 -0
- authyouragent-0.3.0/authyouragent/vault_seccomp.json +1236 -0
- authyouragent-0.3.0/authyouragent.egg-info/PKG-INFO +149 -0
- authyouragent-0.3.0/authyouragent.egg-info/SOURCES.txt +16 -0
- authyouragent-0.3.0/authyouragent.egg-info/dependency_links.txt +1 -0
- authyouragent-0.3.0/authyouragent.egg-info/entry_points.txt +3 -0
- authyouragent-0.3.0/authyouragent.egg-info/requires.txt +9 -0
- authyouragent-0.3.0/authyouragent.egg-info/top_level.txt +1 -0
- authyouragent-0.3.0/pyproject.toml +34 -0
- authyouragent-0.3.0/setup.cfg +4 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: authyouragent
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Auth Your Agent SDK: let AI agents act for a user on websites, with the user's approval on their phone.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://authyouragent.com
|
|
7
|
+
Project-URL: Documentation, https://authyouragent.com/docs
|
|
8
|
+
Keywords: ai-agents,authorization,dpop,webauthn,identity,mcp,takeover
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: httpx>=0.25
|
|
12
|
+
Requires-Dist: pyjwt>=2.8
|
|
13
|
+
Requires-Dist: cryptography>=41
|
|
14
|
+
Provides-Extra: takeover
|
|
15
|
+
Requires-Dist: websockets>=12; extra == "takeover"
|
|
16
|
+
Provides-Extra: mcp
|
|
17
|
+
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
18
|
+
|
|
19
|
+
<!-- mcp-name: com.authyouragent.mcp -->
|
|
20
|
+
# authyouragent (Python)
|
|
21
|
+
|
|
22
|
+
SDK for [Auth Your Agent](https://authyouragent.com): let AI agents act for a person on websites, with the person's approval on their phone.
|
|
23
|
+
|
|
24
|
+
- `AgentClient`: an agent asks for access, then calls sites with a short-lived pass and a fresh DPoP proof (RFC 9449) on every request.
|
|
25
|
+
- `SiteVerifier`: a website checks each call in one line.
|
|
26
|
+
- **Browser vault**: the agent's browser runs in a container it cannot read into. When a site asks for a password, a CAPTCHA or 2FA, the owner takes over from their phone; clicks that commit something wait for the owner's approval.
|
|
27
|
+
|
|
28
|
+
Python 3.9+. Depends on `httpx`, `pyjwt`, `cryptography`.
|
|
29
|
+
|
|
30
|
+
Full documentation: https://authyouragent.com/docs/developers/quickstart
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
You need Python 3.9+ and Docker.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
pip install "authyouragent[mcp]"
|
|
38
|
+
authyouragent vault up --agent-id ag_xxxxx --key /path/to/agent-key.pem
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`vault up` starts the browser vault: the browser your agent uses, in a
|
|
42
|
+
container on your machine. The agent drives it through the vault and never
|
|
43
|
+
gets its cookies. It prints the `env` block for your MCP client. See
|
|
44
|
+
[vault/README.md](https://github.com/kjames2001/authyouragent/blob/main/vault/README.md)
|
|
45
|
+
for what protects what, and the known limits.
|
|
46
|
+
|
|
47
|
+
For just the SDK (no browser, no MCP): `pip install authyouragent`.
|
|
48
|
+
|
|
49
|
+
## MCP server
|
|
50
|
+
|
|
51
|
+
The `authyouragent-mcp` command starts an MCP server with eleven tools:
|
|
52
|
+
|
|
53
|
+
- **Browser:** `navigate`, `click`, `type_text`, `read_page`. Clicks that
|
|
54
|
+
submit, send, delete, pay or publish wait for your approval on your phone.
|
|
55
|
+
- **`check_login_wall`**: is the page asking for a password, a code or a
|
|
56
|
+
sign-in approval?
|
|
57
|
+
- **`request_takeover`** / **`wait_for_takeover`**: you take over the browser
|
|
58
|
+
from your phone. The agent is disconnected until you finish, and the vault
|
|
59
|
+
hands back by itself once you have signed in.
|
|
60
|
+
- **`request_approval`**: ask you to approve an action the vault cannot see.
|
|
61
|
+
- **`end_session`**: sign out of every site used, then destroy the browser
|
|
62
|
+
profile. Always called at the end.
|
|
63
|
+
- **`check_agent_status`**: is the agent still authorized? You can revoke it
|
|
64
|
+
at any time.
|
|
65
|
+
- **`report_site`**: report a site where take over did not work.
|
|
66
|
+
|
|
67
|
+
### Configuration
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
AYA_AGENT_ID=ag_xxxxx
|
|
71
|
+
AYA_KEY_FILE=/path/to/agent-key.pem
|
|
72
|
+
AYA_VAULT_URL=http://127.0.0.1:7801
|
|
73
|
+
AYA_VAULT_TOKEN_FILE=~/.authyouragent/vault/token
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Hermes
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
mcp:
|
|
80
|
+
authyouragent:
|
|
81
|
+
enabled: true
|
|
82
|
+
command: authyouragent-mcp
|
|
83
|
+
env:
|
|
84
|
+
AYA_AGENT_ID: "ag_xxxxx"
|
|
85
|
+
AYA_KEY_FILE: "/path/to/agent-key.pem"
|
|
86
|
+
AYA_VAULT_URL: "http://127.0.0.1:7801"
|
|
87
|
+
AYA_VAULT_TOKEN_FILE: "~/.authyouragent/vault/token"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Claude Desktop / Cursor
|
|
91
|
+
|
|
92
|
+
Claude Desktop: `claude_desktop_config.json`. Cursor: `~/.cursor/mcp.json`.
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"mcpServers": {
|
|
97
|
+
"authyouragent": {
|
|
98
|
+
"command": "authyouragent-mcp",
|
|
99
|
+
"env": {
|
|
100
|
+
"AYA_AGENT_ID": "ag_xxxxx",
|
|
101
|
+
"AYA_KEY_FILE": "/path/to/agent-key.pem",
|
|
102
|
+
"AYA_VAULT_URL": "http://127.0.0.1:7801",
|
|
103
|
+
"AYA_VAULT_TOKEN_FILE": "~/.authyouragent/vault/token"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Agent
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
python -m authyouragent keygen --name "Job-search assistant"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Register the printed `jwk` in the app (Agents -> Add an agent). Keep `privkey_pem` on the agent's machine.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from authyouragent import AgentClient
|
|
120
|
+
|
|
121
|
+
agent = AgentClient(base_url="https://authyouragent.com", agent_id="ag_…",
|
|
122
|
+
privkey_pem=open("agent-key.pem").read())
|
|
123
|
+
agent.ensure_grant("jobs.example.com", scopes=["list", "apply"]) # phone approval
|
|
124
|
+
r = agent.request("GET", "https://jobs.example.com/api/jobs")
|
|
125
|
+
r = agent.request("POST", "https://jobs.example.com/api/jobs/j1/apply", stepup_action="apply")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Site
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from authyouragent import SiteVerifier, AuthError
|
|
132
|
+
|
|
133
|
+
verifier = SiteVerifier("https://authyouragent.com", expected_audience="jobs.example.com",
|
|
134
|
+
public_base_url="https://jobs.example.com")
|
|
135
|
+
|
|
136
|
+
@app.get("/api/jobs")
|
|
137
|
+
def jobs(request: Request):
|
|
138
|
+
try:
|
|
139
|
+
auth = verifier.verify(request)
|
|
140
|
+
except AuthError as e:
|
|
141
|
+
raise HTTPException(401, {"error": e.error})
|
|
142
|
+
...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
See `examples/` for a complete agent and a complete FastAPI site.
|
|
146
|
+
|
|
147
|
+
## Licence
|
|
148
|
+
|
|
149
|
+
MIT
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<!-- mcp-name: com.authyouragent.mcp -->
|
|
2
|
+
# authyouragent (Python)
|
|
3
|
+
|
|
4
|
+
SDK for [Auth Your Agent](https://authyouragent.com): let AI agents act for a person on websites, with the person's approval on their phone.
|
|
5
|
+
|
|
6
|
+
- `AgentClient`: an agent asks for access, then calls sites with a short-lived pass and a fresh DPoP proof (RFC 9449) on every request.
|
|
7
|
+
- `SiteVerifier`: a website checks each call in one line.
|
|
8
|
+
- **Browser vault**: the agent's browser runs in a container it cannot read into. When a site asks for a password, a CAPTCHA or 2FA, the owner takes over from their phone; clicks that commit something wait for the owner's approval.
|
|
9
|
+
|
|
10
|
+
Python 3.9+. Depends on `httpx`, `pyjwt`, `cryptography`.
|
|
11
|
+
|
|
12
|
+
Full documentation: https://authyouragent.com/docs/developers/quickstart
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
You need Python 3.9+ and Docker.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
pip install "authyouragent[mcp]"
|
|
20
|
+
authyouragent vault up --agent-id ag_xxxxx --key /path/to/agent-key.pem
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`vault up` starts the browser vault: the browser your agent uses, in a
|
|
24
|
+
container on your machine. The agent drives it through the vault and never
|
|
25
|
+
gets its cookies. It prints the `env` block for your MCP client. See
|
|
26
|
+
[vault/README.md](https://github.com/kjames2001/authyouragent/blob/main/vault/README.md)
|
|
27
|
+
for what protects what, and the known limits.
|
|
28
|
+
|
|
29
|
+
For just the SDK (no browser, no MCP): `pip install authyouragent`.
|
|
30
|
+
|
|
31
|
+
## MCP server
|
|
32
|
+
|
|
33
|
+
The `authyouragent-mcp` command starts an MCP server with eleven tools:
|
|
34
|
+
|
|
35
|
+
- **Browser:** `navigate`, `click`, `type_text`, `read_page`. Clicks that
|
|
36
|
+
submit, send, delete, pay or publish wait for your approval on your phone.
|
|
37
|
+
- **`check_login_wall`**: is the page asking for a password, a code or a
|
|
38
|
+
sign-in approval?
|
|
39
|
+
- **`request_takeover`** / **`wait_for_takeover`**: you take over the browser
|
|
40
|
+
from your phone. The agent is disconnected until you finish, and the vault
|
|
41
|
+
hands back by itself once you have signed in.
|
|
42
|
+
- **`request_approval`**: ask you to approve an action the vault cannot see.
|
|
43
|
+
- **`end_session`**: sign out of every site used, then destroy the browser
|
|
44
|
+
profile. Always called at the end.
|
|
45
|
+
- **`check_agent_status`**: is the agent still authorized? You can revoke it
|
|
46
|
+
at any time.
|
|
47
|
+
- **`report_site`**: report a site where take over did not work.
|
|
48
|
+
|
|
49
|
+
### Configuration
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
AYA_AGENT_ID=ag_xxxxx
|
|
53
|
+
AYA_KEY_FILE=/path/to/agent-key.pem
|
|
54
|
+
AYA_VAULT_URL=http://127.0.0.1:7801
|
|
55
|
+
AYA_VAULT_TOKEN_FILE=~/.authyouragent/vault/token
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Hermes
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
mcp:
|
|
62
|
+
authyouragent:
|
|
63
|
+
enabled: true
|
|
64
|
+
command: authyouragent-mcp
|
|
65
|
+
env:
|
|
66
|
+
AYA_AGENT_ID: "ag_xxxxx"
|
|
67
|
+
AYA_KEY_FILE: "/path/to/agent-key.pem"
|
|
68
|
+
AYA_VAULT_URL: "http://127.0.0.1:7801"
|
|
69
|
+
AYA_VAULT_TOKEN_FILE: "~/.authyouragent/vault/token"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Claude Desktop / Cursor
|
|
73
|
+
|
|
74
|
+
Claude Desktop: `claude_desktop_config.json`. Cursor: `~/.cursor/mcp.json`.
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"authyouragent": {
|
|
80
|
+
"command": "authyouragent-mcp",
|
|
81
|
+
"env": {
|
|
82
|
+
"AYA_AGENT_ID": "ag_xxxxx",
|
|
83
|
+
"AYA_KEY_FILE": "/path/to/agent-key.pem",
|
|
84
|
+
"AYA_VAULT_URL": "http://127.0.0.1:7801",
|
|
85
|
+
"AYA_VAULT_TOKEN_FILE": "~/.authyouragent/vault/token"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Agent
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
python -m authyouragent keygen --name "Job-search assistant"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Register the printed `jwk` in the app (Agents -> Add an agent). Keep `privkey_pem` on the agent's machine.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from authyouragent import AgentClient
|
|
102
|
+
|
|
103
|
+
agent = AgentClient(base_url="https://authyouragent.com", agent_id="ag_…",
|
|
104
|
+
privkey_pem=open("agent-key.pem").read())
|
|
105
|
+
agent.ensure_grant("jobs.example.com", scopes=["list", "apply"]) # phone approval
|
|
106
|
+
r = agent.request("GET", "https://jobs.example.com/api/jobs")
|
|
107
|
+
r = agent.request("POST", "https://jobs.example.com/api/jobs/j1/apply", stepup_action="apply")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Site
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from authyouragent import SiteVerifier, AuthError
|
|
114
|
+
|
|
115
|
+
verifier = SiteVerifier("https://authyouragent.com", expected_audience="jobs.example.com",
|
|
116
|
+
public_base_url="https://jobs.example.com")
|
|
117
|
+
|
|
118
|
+
@app.get("/api/jobs")
|
|
119
|
+
def jobs(request: Request):
|
|
120
|
+
try:
|
|
121
|
+
auth = verifier.verify(request)
|
|
122
|
+
except AuthError as e:
|
|
123
|
+
raise HTTPException(401, {"error": e.error})
|
|
124
|
+
...
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
See `examples/` for a complete agent and a complete FastAPI site.
|
|
128
|
+
|
|
129
|
+
## Licence
|
|
130
|
+
|
|
131
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Auth Your Agent — Python SDK.
|
|
2
|
+
|
|
3
|
+
Two halves:
|
|
4
|
+
|
|
5
|
+
* :mod:`authyouragent.agent` — for AI agents. Holds the agent's private key,
|
|
6
|
+
asks the user's phone for approval, and signs every request (DPoP).
|
|
7
|
+
* :mod:`authyouragent.site` — for websites. Verifies that a request really
|
|
8
|
+
comes from an agent the user approved, and whether a sensitive action was
|
|
9
|
+
confirmed (step-up).
|
|
10
|
+
|
|
11
|
+
Quick start (agent)::
|
|
12
|
+
|
|
13
|
+
from authyouragent import AgentClient
|
|
14
|
+
agent = AgentClient(base_url="https://authyouragent.com",
|
|
15
|
+
agent_id="ag_…", privkey_pem=open("agent.pem").read())
|
|
16
|
+
agent.ensure_grant("jobs.example.com", scopes=["list"])
|
|
17
|
+
r = agent.request("GET", "https://jobs.example.com/api/jobs")
|
|
18
|
+
|
|
19
|
+
Quick start (site)::
|
|
20
|
+
|
|
21
|
+
from authyouragent import SiteVerifier, AuthError
|
|
22
|
+
verifier = SiteVerifier("https://authyouragent.com")
|
|
23
|
+
auth = verifier.verify(request) # raises AuthError
|
|
24
|
+
|
|
25
|
+
Documentation: https://authyouragent.com/docs
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from .agent import AgentClient, AgentError, keygen, agent_jwk
|
|
29
|
+
from .site import SiteVerifier, AuthError, Auth
|
|
30
|
+
|
|
31
|
+
__all__ = ["AgentClient", "AgentError", "keygen", "agent_jwk",
|
|
32
|
+
"SiteVerifier", "AuthError", "Auth"]
|
|
33
|
+
__version__ = "0.3.0"
|
|
34
|
+
DEFAULT_CLOUD = "https://authyouragent.com"
|