dumbtv
dumbtv가 ADB로 Fire TV에서 광고·추적·업데이트 알림을 제거, 루트·앱 변경 없이, 무료 오픈소스
TrustTab은 사이트 폼 중 AI가 안전히 활용할 수 있는 형태를 확인하고 배지를 발급합니다
TrustTab verifies which of your site's forms are safe and correctly structured for AI agents to act on, and issues a badge anyone can check.
보안TypeScript · JavaScriptGitHub @trusttab온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Open-source protocol and badge verifying which forms on your site are safe for AI agents to fill out.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Verified, agent-ready forms. TrustTab lets a website declare which of its
forms are safe and correctly structured for an AI agent to act on (a contact
form, a booking page, a support ticket), verifies that claim automatically, and
issues a badge that anyone can check against a public registry.
Status: early development. This repository is being built in the open.
The full loop works: claim a domain, publish a signed manifest, get
checked, and show a live badge. Expect rough edges (see Roadmap).README 전문 보기 ↗Verified, agent-ready forms. TrustTab lets a website declare which of its forms are safe and correctly structured for an AI agent to act on (a contact form, a booking page, a support ticket), verifies that claim automatically, and issues a badge that anyone can check against a public registry.
Status: early development. This repository is being built in the open. The full loop works: claim a domain, publish a signed manifest, get checked, and show a live badge. Expect rough edges (see Roadmap).
AI agents are starting to fill in forms on people's behalf. That raises two questions a site owner currently has no standard way to answer:
TrustTab gives sites a way to publish those answers in a machine-readable
manifest at /.well-known/agent-trust.json, and gives agents (and people) a way
to confirm the manifest was independently checked and is still current.
TrustTab is not an agent-identity or payments protocol. Efforts like Visa's Trusted Agent Protocol and Google's AP2 verify that an agent is real and authorized to act for someone. TrustTab is complementary: it verifies the site the agent is about to interact with.
Claim your domain. Sign up (and confirm your email address), enter your domain, and add the generated tag
to the <head> of your homepage:
<meta name="agenttrust-verify" content="YOUR_TOKEN">
Click Check now. TrustTab fetches https://your-domain/ and confirms
the tag is present.
Declare your agent-safe endpoints. Describe each form: its path,
method, purpose (from a fixed, centrally maintained list such as
lead_inquiry or booking) and field schema. TrustTab signs the manifest
and serves it. Point your site at it with a /.well-known/agent-trust.json
redirect or an agent-trust-manifest tag on your homepage (see Discovery).
Get checked. TrustTab confirms each declared form exists with the declared fields, scans the page for hidden prompt-injection content, checks HTTPS, and makes sure the manifest's domain matches the domain serving it. Click Re-check now to run the checks. The manifest is re-signed after every run to reflect the result.
| Check | Passes when |
|---|---|
| Endpoint match | Each declared page has a server-rendered <form> containing every declared field name |
| Injection scan | No instruction-override phrases or chat-template markers, and no hidden text directing AI agents |
| HTTPS | Pages load over HTTPS with valid certificates |
| Domain match | The discovered manifest is signed for this domain and registration |
| Expiry | That served manifest hasn't expired |
Forms rendered by JavaScript. TrustTab reads server-rendered HTML, so it
can't see forms that only appear after client-side JavaScript runs. For
those, an owner can self-attest the endpoint. If every other check
passes, the site gets the separate Self-declared status, never
"Verified". The manifest marks each endpoint's verified_by as issuer
(confirmed) or owner (self-attested only). Self-attestation never covers a
page that fails to load or any check other than the form match.
| Status | Meaning | Badge |
|---|---|---|
| Verified | Every automated check passed | |
| Self-declared | Everything passed except forms the owner self-attests | |
| Needs fixes | Some checks failed | |
| Failed | Content that could manipulate AI agents was found | |
| Expired | Was verified or self-declared, but not re-checked in time | |
| Pending | Not checked yet |
Show the badge. Embed the snippet from your dashboard. It displays your live status and links to a public verification page on the issuer.
Each site's dashboard has an AI assistant (Claude) that can:
Everything it does lands in your draft, visibly, in the manifest editor. Before you publish, TrustTab shows exactly what will change and why the assistant changed it.
A manifest is a signed attestation by you, so publishing is a human-only action, enforced in code rather than just the UI:
What this can't prove is that a human hand made the click: code running inside your own signed-in browser (a malicious extension, say) could repeat the calls. A WebAuthn "user presence" check at publish would close that gap and is a planned option.
The assistant needs ANTHROPIC_API_KEY; without it, the panel is hidden.
extension/ contains a Chrome extension. Click it on any site to see that
site's TrustTab status. It asks only for the activeTab permission, and it
contacts TrustTab only when you open its popup. See
extension/README.md to build and load it.
| Endpoint | Returns |
|---|---|
GET /api/manifest/:domain | The live signed manifest for a domain |
GET /api/verify/by-domain/:domain | Same as below, looked up by domain (normalized, exact match; subdomains don't inherit). 404 if the domain has no entry |
GET /api/verify/:verificationId | { verification_id, status, domain, verified_at, expires_at, issuer, manifest_url, self_declared_endpoints }. status is verified, self_declared, pending, needs_fix, failed or expired |
GET /api/badge/:verificationId.svg | Live status badge |
GET /.well-known/jwks.json | The issuer's public signing keys |
All public endpoints send Access-Control-Allow-Origin: * and are rate-limited
per client IP (120 requests/minute for the manifest and verify endpoints, 300
for badges, and 60 for the human-readable /verify/:verificationId page). Requests to the manifest and verify endpoints appear in the site
owner's traffic log.
Privacy: the traffic log stores only a truncated client IP (IPv4 /24, IPv6 /48) and a user agent, and rows are deleted after 30 days. Rate limiting (for these endpoints and for sign-in/sign-up) is counted in Postgres under a keyed hash of the IP, so no raw addresses are stored.
The manifest format is defined by agent-trust.schema.json
(JSON Schema 2020-12, version 1.0 draft). An abbreviated example:
{
"version": "1.0",
"issuer": { "name": "TrustTab", "url": "https://trusttab.example", "verification_id": "tt_3v5urc2st37r" },
"site": {
"domain": "acme-plumbing.com",
"verification_status": "unverified",
"verified_at": null,
"expires_at": "2026-10-14T18:00:00.000Z",
"signature": "eyJhbGciOiJFZERTQSIsImtpZCI6Ii4uLiJ9..3q2-7w..."
},
"policy": {
"no_prompt_injection_pledge": true,
"agent_rate_limit": { "requests_per_minute": 20, "captcha_exempt": true },
"content_scan": { "last_scanned": null, "status": "pending" }
},
"endpoints": [
{
"path": "/contact",
"method": "POST",
"purpose": "lead_inquiry",
"schema": { "name": "string", "email": "email", "service": "enum[repair,install]", "notes": "string?" },
"agent_safe": true,
"requires_captcha": false,
"self_attested": false,
"verified_by": null
}
]
}
verification_status: "unverified" and content_scan.status: "pending" mean
the manifest is signed but hasn't been checked yet. Agents should treat a
manifest as verified only when verification_status is "verified" (which is
the only case where verified_at is set) and expires_at is in the future.
"self_declared" means TrustTab could not confirm every form: rely only on
endpoints whose verified_by is "issuer".
A site's live manifest is served at <issuer>/api/manifest/<domain>.
Agents find a site's manifest in one of two places, checked in this order:
https://<domain>/.well-known/agent-trust.json, typically a redirect to
the issuer URL above.
A tag in the homepage <head>, for platforms that reserve
/.well-known/ (many hosted site builders do). Either form works; some
builders keep custom <meta> tags but strip custom <link> tags:
<meta name="agent-trust-manifest" content="https://<issuer>/api/manifest/<domain>">
<link rel="agent-trust-manifest" href="https://<issuer>/api/manifest/<domain>">
If the well-known path serves a manifest, that one wins. Either way, always
check the manifest's signature and that site.domain matches the site you're
on.
site.signature is a detached compact JWS (RFC 7515)
using Ed25519 (alg: EdDSA). To verify:
header, an empty segment, and sig on ..header (base64url JSON) and read kid.<issuer.url>/.well-known/jwks.json and pick the key with that kid.
Only trust keys from an issuer you trust (see below).site.signature from the manifest and serialize the rest with
RFC 8785 JSON canonicalization.sig over the ASCII bytes header + "." + base64url(canonical JSON).Any standard JOSE library that supports detached payloads and EdDSA can do steps 4–5.
The code is MIT-licensed. Anyone can read it, fork it and run their own instance. A badge, though, only means as much as the registry it resolves against. A self-hosted instance issues badges that verify against its own keys, and the canonical TrustTab badge is the one that resolves against the official hosted service. It's the same model as Let's Encrypt: open code, with one widely trusted issuer in practice. Issuer identity and signing keys are configured through environment variables, never hard-coded.
crypto for Ed25519 signinggit clone <this repo> trusttab && cd trusttab
npm install
cp .env.example .env.local # then fill in the values
npm run db:migrate # create tables
npm run dev # http://localhost:3000
.env.local needs:
| Variable | Purpose |
|---|---|
DATABASE_URL | Postgres connection string |
BETTER_AUTH_SECRET | Session signing secret. Generate one with openssl rand -base64 32 |
BETTER_AUTH_URL | Public base URL of the deployment, e.g. http://localhost:3000 |
TRUSTTAB_ISSUER_NAME | Issuer name written into signed manifests |
TRUSTTAB_ISSUER_URL | Public https:// base URL of this instance, written into manifests |
TRUSTTAB_SIGNING_PRIVATE_KEY | Ed25519 signing key. Generate with npm run keys:generate and back it up |
RESEND_API_KEY, EMAIL_FROM | Sends account verification and password reset email via Resend. EMAIL_FROM must use a domain verified in Resend. Without them, npm run dev prints emails to the server log, and production builds disable email verification and password reset (with a startup warning) |
ANTHROPIC_API_KEY, ASSISTANT_MODEL | Optional. Enables the dashboard assistant (default model claude-sonnet-5) |
AI_TEXT_MODEL, AI_IMAGE_MODEL, AI_CHECK_DAILY_CAP | Optional. The extension's AI Check text and image estimates, which also need ANTHROPIC_API_KEY (models default to claude-haiku-4-5-20251001; one shared budget of 1000 checks/day across all clients) |
TRUSTTAB_URL (collectors) | Optional. Where an installed collector reports agent traffic; defaults to the hosted TrustTab (see collectors/) |
AGENTTRUST_VERIFY_TOKEN | Optional. Makes this deployment publish its own verification tag so it can claim its own domain |
DATABASE_URL for you.BETTER_AUTH_SECRET, BETTER_AUTH_URL, TRUSTTAB_ISSUER_NAME,
TRUSTTAB_ISSUER_URL, TRUSTTAB_SIGNING_PRIVATE_KEY, RESEND_API_KEY and
EMAIL_FROM under Settings → Environment Variables.vercel env pull .env.production.local, then
DATABASE_URL=<direct, unpooled URL> npm run db:migrate. With Neon, that's
DATABASE_URL_UNPOOLED. Keep the pulled file out of the repo and delete it
afterwards.Self-hosting elsewhere: run TrustTab behind a reverse proxy that
overwrites X-Forwarded-For with the real client IP. Rate limiting and the
traffic log rely on that header, and without such a proxy clients can claim
any IP. Accounts are limited to 10 sites (MAX_SITES_PER_USER) to bound
outbound verification traffic.
| Script | What it does |
|---|---|
npm run dev | Start the dev server |
npm run build | Production build (includes type checking) |
npm test | Unit tests (Node's built-in test runner) |
npm run test:integration | Assistant and publish-gate tests against the database in .env.local |
npm run lint / npm run typecheck | Static checks |
npm run keys:generate | Print a new manifest-signing key |
npm run db:generate | Generate a SQL migration after editing src/db/schema.ts |
npm run db:migrate | Apply pending migrations |
npm run db:studio | Browse the database with Drizzle Studio |
npm run ext:build / ext:typecheck / ext:preview | Build, typecheck or preview the browser extension |
src/
app/ pages and API routes (App Router)
api/auth/[...all] Better Auth endpoints
api/sites/ domain claims, ownership checks, manifest publishing, verification
api/manifest/ public manifest lookup
api/verify/ public registry lookup
api/badge/ live status badge (SVG)
verify/ public verification page (badge link target)
.well-known/ public signing keys (JWKS)
dashboard/ signed-in UI
components/ UI components
db/ Drizzle schema and client
proxy.ts request proxy (rate-limits the public verification page)
lib/
auth.ts Better Auth config and session helpers
domain.ts domain normalization and validation
ownership.ts verification token and meta-tag check
safe-fetch.ts SSRF-hardened fetch for user-supplied sites
manifest/ build, canonicalize, sign, validate manifests
verification/ verification checks and engine
assistant/ dashboard assistant: tool allowlist, crawler, model loop
drafts/ saved manifest drafts (shared by editor and assistant)
publish-gate.ts human-only publish confirmations
agent-trust.schema.json manifest format (JSON Schema)
drizzle/ generated SQL migrations
/api/manifest/[domain]agent-trust-manifest homepage tag discovery for platforms that reserve /.well-known//dashboard/account)See CONTRIBUTING.md.
If you find a vulnerability, please don't open a public issue. Report it privately through GitHub's private vulnerability reporting on this repository.