Ubag_protocol
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Uyari
- network request — Outbound network request in examples/demo.js
- crypto private key — Private key handling in examples/demo.js
- crypto private key — Private key handling in ubag-node/src/AgentCredential.js
- crypto private key — Private key handling in ubag-node/src/keys.js
- process.env — Environment variable access in ubag-node/src/middleware/express.js
- network request — Outbound network request in ubag-node/src/middleware/express.js
- network request — Outbound network request in ubag-node/src/routing.js
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Open reference implementation: agent identity + routing at the web edge (Ed25519 + ES256/JWKS). Python & Node.
UBAG Web Layer
Universal Behavioral Authorization Gateway — Web Layer
Agent identity and routing at the web edge. The open reference implementation.
When an autonomous agent visits a website, UBAG verifies who it is and routes
accordingly: humans to your normal site, credentialed agents to clean JSON-LD,
unknown bots to a cryptographic challenge. MCP standardized how agents talk to
tools — it left a gap at the web layer: agent identity when no human is in the
loop. This is that layer.
Where this fits. UBAG has two layers. The Gateway governs what an agent
is allowed to do against credentialed systems and MCP tools; this Web Layer
governs how an agent reaches a website. This repo is the open, MIT-licensed
reference implementation of the Web Layer — and of an open mechanism any site can
adopt (ubag.jsondiscovery + a sign-the-nonce challenge +X-UBAG-Credential),
not a product you have to buy into.
Status: early but real. Two published SDKs —
pip install ubag(Python) andnpm install ubag-web(Node) — sharing a cross-verifiable wire format.
See Project status for exactly what works today vs. what's planned.
The Problem
When an autonomous MCP agent visits a website today:
- The website has no way to verify who it is
- It scrapes raw HTML like any bot from 2005
- Unknown agents get blocked by Cloudflare — including legitimate ones
- No human is in the loop to click "Allow"
MCP's OAuth 2.1 spec is built for human-delegated auth (browser → redirect → user clicks Allow). It does not cover autonomous agent identity — the credential an agent carries when no human is in the loop.
UBAG fills that gap.
How It Works
Every request to a UBAG-enabled site is routed through a 3-branch matrix:
flowchart TD
R[Incoming request] --> M{UBAG middleware}
M -->|Valid X-UBAG-Credential| B["Branch B — Clean JSON-LD<br/>structured data, no HTML parsing"]
M -->|Looks human| A["Branch A — Transparent proxy<br/>origin server, untouched"]
M -->|Unknown agent| C["Branch C — Sandbox + challenge<br/>sign a nonce with your Ed25519 key"]
C -->|signature verified → credential issued| B
Branch B is the key insight. Instead of an agent crawling 50 pages to understand a business, UBAG serves one structured JSON-LD response — products, prices, policies, contacts. One request, no HTML parsing, far fewer extraction errors.
Security Model
UBAG is asymmetric — there are no shared secrets in the identity path:
- Agent identity = an Ed25519 keypair. An agent's identity is the SHA-256 thumbprint of its public key (
ubag:…). To get in, the agent signs the site's nonce with its private key; the site verifies with the public key. Only the holder of the key can pass — knowing a shared secret never establishes who an agent is. - Credentials = ES256 JWTs signed by an issuer's EC P-256 private key and verifiable by any site with the issuer's public key — auto-served as JWKS at
/.well-known/jwks.json. No site needs a secret to validate a credential — the same model as OAuth / OIDC, which is what lets one credential work across independent sites. - Proof-of-possession ready. Each credential binds to the agent's key via the
cnfclaim, so a verifier can require the bearer to prove it still holds the matching private key. - One server-side HMAC, used only so the site can confirm it issued a given nonce without storing state (the server signing to itself). It is not part of the identity proof.
The Python and Node SDKs share identical wire formats (raw Ed25519 + ES256), so a signature or credential produced by one verifies byte-for-byte in the other. This interop is covered by tests in both packages.
Install
# Python (FastAPI / Starlette)
pip install "ubag[fastapi]"
# Node (Express)
npm install ubag-web
The npm package is
ubag-web(npm reserves the bareubag); the Python
package isubag. Same protocol, identical wire format.
Or from source: git clone the repo, then pip install -e ".[fastapi]" inubag-python/ and npm install in ubag-node/.
Quick Start — Python (FastAPI)
from fastapi import FastAPI
from ubag import UBAGMiddleware, generate_issuer_keypair
# Your site is its own credential issuer. Generate once and persist these
# (or run verify-only by passing issuer_public_key alone).
ISSUER_PRIVATE, ISSUER_PUBLIC = generate_issuer_keypair() # EC P-256 (ES256)
app = FastAPI()
app.add_middleware(
UBAGMiddleware,
origin="https://yoursite.com", # Branch A proxy target
issuer_key=ISSUER_PRIVATE, # mints + verifies agent credentials
server_secret="a-random-32+char-string-for-nonce-stamping",
site_meta={"name": "My Store", "type": "Store", "description": "We sell widgets"},
)
issuer_key can also come from the UBAG_ISSUER_KEY env var; a verify-only
deployment can pass issuer_public_key (or UBAG_ISSUER_PUBLIC) alone.
Your site now:
- ✅ Serves clean JSON-LD to credentialed MCP agents (Branch B)
- ✅ Proxies humans transparently to your origin (Branch A)
- ✅ Sandboxes unknown agents with an Ed25519 nonce challenge (Branch C)
- ✅ Serves
yoursite.com/.well-known/ubag.jsonfor agent discovery - ✅ Calls your optional
audit_fn(branch, request, response)on every visit
Quick Start — Node (Express)
const express = require('express');
const { ubag, generateIssuerKeypair } = require('ubag-web');
const { privateKey: ISSUER_PRIVATE } = generateIssuerKeypair(); // EC P-256 (ES256)
const app = express();
app.use(ubag({
origin: 'https://yoursite.com',
issuerKey: ISSUER_PRIVATE,
serverSecret: 'a-random-32+char-string-for-nonce-stamping',
siteMeta: { name: 'My Store', type: 'Store', description: 'We sell widgets' },
}));
See it work (60 seconds)
Runnable end-to-end demos spin up a UBAG site in-process and walk one agent
through the whole handshake — blocked → challenged → signs the nonce →
credentialed → served JSON-LD — then print the JWKS another site would use to
verify the credential:
# Python
cd ubag-python && pip install -e ".[fastapi]" && python ../examples/demo.py
# Node
npm install --prefix ubag-node && node examples/demo.js
For MCP Agent Developers
If you're building an MCP agent that visits websites, get a UBAG credential:
from ubag import AgentCredential
# Your agent's identity IS its Ed25519 keypair. Generate once; persist agent.export().
agent = AgentCredential.generate(owner="[email protected]")
# When a UBAG site challenges you (HTTP 429), sign the nonce and post it back:
# challenge = resp.json()["ubag_challenge"] # nested in the 429 body: nonce, timestamp, stamp
# solution = agent.solve_challenge(challenge) # signs the nonce with your private key
# r = httpx.post(f"{site}/ubag/verify", json=solution)
# agent.set_credential(r.json()["credential"])
# Once credentialed, it travels with every request:
headers = agent.headers()
# {"X-UBAG-Credential": "eyJ..."}
UBAG-enabled sites recognize your agent and serve structured data instead of HTML. Your agent gets better data; the website owner gets visibility and control. The Node SDK exposes the same AgentCredential API.
Discovery: /.well-known/ubag.json
Every UBAG-enabled site serves a discovery document at /.well-known/ubag.json
(with /agents.json kept as a legacy alias). It's deliberately not namedagents.json — that filename is already claimed by unrelated specs (Wildcard's
OpenAPI-style agents.json, Google/Microsoft/HF's ARD, etc.); ubag.json keeps
UBAG's identity/routing document collision-free and unambiguous.
{
"ubag_version": "1.0",
"host": "yoursite.com",
"credential_endpoint": "https://yoursite.com/ubag/verify",
"branches": {
"B-AGENT": { "description": "Authorized MCP agents — clean JSON-LD",
"requires": "X-UBAG-Credential header with valid JWT",
"content_type": "application/ld+json" },
"A-HUMAN": { "description": "Human browsers — transparently proxied to origin",
"requires": "None" },
"C-SANDBOX": { "description": "Unknown agents — Ed25519 nonce challenge",
"requires": "None — solve challenge to get credentialed",
"challenge_endpoint": "/ubag/verify" }
},
"discovery": {
"ubag_json": "https://yoursite.com/.well-known/ubag.json",
"verify_endpoint": "https://yoursite.com/ubag/verify",
"jwks_endpoint": "https://yoursite.com/.well-known/jwks.json"
}
}
Like robots.txt, but machine-actionable — agents fetch it before making requests.
Why Not Just Use Cloudflare?
| Cloudflare | AWS WAF | UBAG | |
|---|---|---|---|
| Blocks unknown bots | ✅ | ✅ | Challenges them instead |
| Structured data for agents | Markdown (AI features) | ❌ | ✅ JSON-LD |
| Cryptographic agent identity / credential | ❌ | ❌ | ✅ |
| Autonomous agent support (no browser) | ❌ | ❌ | ✅ |
| Open source | ❌ | ❌ | ✅ |
| Vendor lock-in | Cloudflare | AWS | None |
Cloudflare and AWS block or filter bots. UBAG graduates them: an unknown agent can solve the challenge, get credentialed, and become authorized — no legitimate agent is permanently blocked. (Competitor columns reflect general capabilities at time of writing; verify against current vendor docs.)
MCP Integration
UBAG complements MCP, it doesn't replace it:
- MCP OAuth 2.1 — human-delegated auth (user clicks Allow in a browser)
- UBAG credential — autonomous agent identity (no human in the loop)
MCP Agent
│
├── Talking to MCP servers? ──► MCP OAuth 2.1
│
└── Visiting websites? ────────► UBAG credential
A UBAG credential is issued once and verified in-process by the site's middleware — no redirect, no browser flow — and works on any UBAG-enabled site.
Repository Layout
ubag-python/ Python middleware — FastAPI / Starlette today (v0.2.0)
ubag-node/ Node middleware — Express today (v0.2.0)
Both packages implement the full protocol (routing, credentials, challenge, keys,
ubag.json) and share a cross-verifiable wire format.
Run the tests
# Python
cd ubag-python && pip install -e ".[dev]" && pytest
# Node
cd ubag-node && npm install && npm test
Project status
Working today
- Branch A — human transparent proxy
- Branch B — agent JSON-LD structured data
- Branch C — sandbox + Ed25519 nonce challenge
- Asymmetric crypto — Ed25519 agent identity + ES256/JWKS credentials, no shared secrets
-
ubag.jsondiscovery — served on every UBAG site (alias:/agents.json) - Audit hook —
audit_fncallback on every request - Python SDK (FastAPI/Starlette) + Node SDK (Express), cross-SDK verified
- Published —
pip install ubag(PyPI) andnpm install ubag-web(npm)
Planned / not yet built
- Django / Flask / Next.js middleware adapters
- Hosted credential registry / issuer at
ubagprotocol.com/credential - WordPress plugin
- Docker reference deployment (one-command self-host)
- Formal spec docs (
docs/spec/…) - Payment / revenue-share layer for site owners
Contributing
PRs welcome. The goal isn't to make everyone adopt "UBAG" — it's to make the mechanism easy to adopt: ubag.json discovery, a sign-the-nonce challenge, and a portable X-UBAG-Credential that any site can verify without a shared secret. Open, verifiable, and not owned by any cloud provider. UBAG is just the reference implementation.
Contact
Built by Mohamed Ben Hadj Hmida
ubagprotocol.com · github.com/mohameduk/Ubag_protocol
MIT licensed.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi