AURA is an open protocol for making a website's capabilities machine-readable and explicitly permissioned to act on. Instead of scraping UIs, agents (LLM tool callers, automation clients, or plugins) read a manifest and call declared HTTP actions that are validated and authorized on the server.
Spec status: Experimental (v1.0 format; breaking changes may occur).
- Serve
/.well-known/aura.jsonwith declared capabilities and actions (public, cacheable, no secrets). - Implement the capability endpoints and enforce auth/authorization and input validation.
- Emit
AURA-Stateto describe dynamic availability (optional but recommended). - Validate the manifest with
aura-validate.
- Integration in 60 seconds
- What is AURA?
- Philosophy
- Core Concepts
- How It Works
- Quickstart: Local Demo
- Production Demo (Build + Start)
- Environment Variables
- Security model (non-negotiable)
- Integrate AURA Into Your Site
- Validation and Tooling
- Reference Packages
- FAQ
- Troubleshooting
- References
- License
AURA (Agent-Usable Resource Assertion) is a small, explicit contract between a website and an AI agent. A site publishes a manifest at /.well-known/aura.json that lists capabilities (verbs) and optionally resources (nouns) with concrete HTTP actions. Agents can then act without guessing UI flows or scraping HTML.
AURA is not a replacement for authentication or authorization, and it is not a universal API description. Think of it as a tool manifest: a curated set of actions intended for automated execution; the manifest is descriptive, not permissive, and the server remains the source of truth.
- Explicit over implicit: Actions are declared, not inferred from markup.
- Small, auditable surface: A compact manifest is easier to review and secure than UI automation.
- State-aware by default (advisory): The
AURA-Stateheader communicates context; the server remains the source of truth. - Server-enforced: The manifest is descriptive. Every action is validated server-side and authenticated/authorized as required.
- Compatibility, not replacement: AURA complements your existing APIs and auth. It does not replace them.
Core terms used in this repo (informal; see the schema for canonical fields):
- Manifest (
/.well-known/aura.json): The machine-readable contract with$schema,protocol,version,site,resources, andcapabilities(all required). - Resources: Noun groupings (required, may be
{}) withuriPattern,description, and HTTP operations that map to capability IDs. - Capabilities: Verbs (required, may be
{}) with parameter schema and anHttpActiondefinition. - HttpAction: How to execute a capability (method, RFC 6570
urlTemplate, encoding, parameter mapping, optionalparameterLocationandcors). - AURA-State header: Base64-encoded JSON describing context and available capability IDs; advisory, not permission.
- Policy (optional): Hints like
rateLimit(limit/window) andauthHint(none,cookie,bearer).
- A client fetches
/.well-known/aura.json. - The client selects a capability (optionally filtered by
AURA-Statecontext). - The client maps arguments from the agent-provided input object via JSON Pointer into the request body/query/path and expands the URL template.
- The server validates the request, enforces auth/authorization and rate limits, logs/audits as configured, and executes the action.
Prereqs: Node.js 18+ (20+ recommended) and pnpm (run corepack enable if needed).
From the repo root:
pnpm install
pnpm --filter aura-reference-server devVerify the manifest:
curl http://localhost:3000/.well-known/aura.jsonYou should see a JSON object with protocol, version, and capabilities.
Demo credentials (local development only):
- Email:
demo@aura.dev - Password:
password123
This bypasses the manifest and is just a direct API sanity check. If you use cookie auth in production, add CSRF protection and SameSite cookies.
# Save the auth cookie after login
curl -i -c cookies.txt \
-H "Content-Type: application/json" \
-d '{"email":"demo@aura.dev","password":"password123"}' \
http://localhost:3000/api/auth/login
# Use the cookie to create a post
curl -i -b cookies.txt \
-H "Content-Type: application/json" \
-d '{"title":"Hello","content":"From AURA"}' \
http://localhost:3000/api/postsThe reference client uses OpenAI's API to plan actions; the AURA protocol itself is model-agnostic.
Create packages/reference-client/.env:
OPENAI_API_KEY=YOUR_KEY_HEREDo not commit .env files.
The agent command fetches the manifest, selects capabilities, and calls the declared HTTP actions (no UI scraping).
Run the agent:
pnpm --filter aura-reference-client agent -- http://localhost:3000 "log in and create a post titled Hello"Inspect the manifest with the crawler:
pnpm --filter aura-reference-client crawler -- http://localhost:3000Run the end-to-end workflow test:
pnpm --filter aura-reference-client test-workflow http://localhost:3000If you want a production-like demo:
pnpm --filter aura-reference-server build
pnpm --filter aura-reference-server startThe server will be available at http://localhost:3000. This is still a demo: auth is simplified and data is in-memory.
Only the following are required for the reference demos:
packages/reference-client/.env:OPENAI_API_KEYfor theagentscript.PORT: Optional. Overrides the default Next.js port for the reference server.
- AURA does not grant permission; it describes actions and inputs.
- Every capability is authenticated/authorized server-side as appropriate.
- Rate-limit and log capability calls; attach request IDs for auditability.
- Treat
AURA-Stateas advisory context; keep it compact and never encode secrets. - Avoid destructive capabilities without explicit user consent or confirmation flows.
If you are using Next.js, place it at public/.well-known/aura.json. Keep it public and avoid secrets. Serve it with Content-Type: application/json and cache headers (ETag/Cache-Control) so clients can safely cache it.
The schema requires $schema, resources, and capabilities. Both resources and capabilities may be empty objects ({}) if you only need one or the other.
Minimal example:
{
"$schema": "https://unpkg.com/aura-protocol@1.0.5/dist/aura-v1.0.schema.json",
"protocol": "AURA",
"version": "1.0",
"site": {
"name": "Example Site",
"url": "https://example.com"
},
"resources": {},
"capabilities": {}
}A more complete example with a capability:
{
"$schema": "https://unpkg.com/aura-protocol@1.0.5/dist/aura-v1.0.schema.json",
"protocol": "AURA",
"version": "1.0",
"site": {
"name": "Example Site",
"url": "https://example.com"
},
"resources": {
"auth_login": {
"uriPattern": "/api/auth/login",
"description": "Authentication login endpoint",
"operations": {
"POST": {
"capabilityId": "login"
}
}
}
},
"capabilities": {
"login": {
"id": "login",
"v": 1,
"description": "Authenticate user with email and password",
"parameters": {
"type": "object",
"required": ["email", "password"],
"properties": {
"email": { "type": "string", "format": "email" },
"password": { "type": "string", "minLength": 8 }
}
},
"action": {
"type": "HTTP",
"method": "POST",
"urlTemplate": "/api/auth/login",
"encoding": "json",
"parameterMapping": {
"email": "/email",
"password": "/password"
}
}
}
}
}Schema reality: $schema is required for v1.0 manifests. The schema's $id is https://aura.dev/schemas/v1.0.json, but aura.dev hosting is planned and not yet live. For now, use the versioned Unpkg URL shown above or reference the bundled schema at node_modules/aura-protocol/dist/aura-v1.0.schema.json. Validation with aura-validate works offline on local files.
To demonstrate state-aware behavior, add authenticated capabilities (for example, create_post) and include them in AURA-State only when a user is logged in.
Your API routes must match the manifest (method + URL template). Validate input using JSON Schema, and enforce authentication and authorization rules for each capability. In the reference server, validateRequest in packages/reference-server/lib/validator.ts uses Ajv to enforce the capability schema.
The AURA-State header is Base64-encoded JSON. It can indicate authentication and what capabilities are currently available; clients should treat it as advisory context and rely on server errors for truth. Keep it compact to fit header size limits and never encode secrets.
const auraState = {
isAuthenticated: true,
context: { path: "/api/posts", timestamp: new Date().toISOString() },
capabilities: ["list_posts", "create_post"]
};
const headerValue = Buffer.from(JSON.stringify(auraState)).toString("base64");
res.setHeader("AURA-State", headerValue);Note: The reference server uses standard Base64. If you control both sides, Base64URL is also acceptable to avoid + and / in headers.
Use the CLI validator and your own tests:
npx -y -p aura-protocol aura-validate public/.well-known/aura.jsonTo validate a remote manifest, download it first:
curl -fsSL https://example.com/.well-known/aura.json -o aura.json
npx -y -p aura-protocol aura-validate aura.jsonNote: aura-validate currently validates local files only. Download remote manifests to a file before validating.
- Serve
/.well-known/aura.jsonwithContent-Type: application/jsonand cache headers (ETag/Cache-Control). - Document capability changes and increment the
vfield for breaking changes. - Every capability should have an authorization rule and a rate limit.
- Log capability calls with request IDs for auditability.
- Keep
AURA-Statecompact, non-sensitive, and advisory. - Add CORS headers for the manifest if browser-based agents will fetch it.
The aura-protocol package ships:
- TypeScript types for
AuraManifest,Resource,Capability,HttpAction, andAuraState. - JSON Schema bundled at
dist/aura-v1.0.schema.json. For editor tooling, reference the versioned CDN URL:https://unpkg.com/aura-protocol@1.0.5/dist/aura-v1.0.schema.json. aura-validateCLI to validate local manifest files and cross-check resource/capability references.
Installation:
npm install aura-protocolExample runtime validation (requires ajv):
import fs from "node:fs";
import path from "node:path";
import Ajv from "ajv";
const schemaPath = path.join(
process.cwd(),
"node_modules",
"aura-protocol",
"dist",
"aura-v1.0.schema.json"
);
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
const manifest = JSON.parse(fs.readFileSync("public/.well-known/aura.json", "utf8"));
const ajv = new Ajv({ allErrors: true, strict: false });
const validate = ajv.compile(schema);
if (!validate(manifest)) {
console.error(validate.errors);
}packages/aura-protocol: Protocol types, schema, and theaura-validateCLI for integrators.packages/reference-server: Next.js demo server that publishes a manifest, auth, andAURA-State.packages/reference-client: Node.js demo client withagent,crawler, andtest-workflowfor agent builders.
Is AURA a replacement for OpenAPI?
No. OpenAPI describes the full endpoint surface. AURA declares a curated set of actions intended for automated execution, with parameter mapping and state hints. Use both if needed.
Can a malicious site lie in the manifest?
Yes. Treat manifests as claims tied to domain trust. Agents should rely on server enforcement and error handling, and only act on sites they trust. Signing or attestation is a possible future direction.
Do I have to expose private APIs?
No. AURA only describes what you choose to expose. Your existing auth and authorization remain in place.
How do agents know what they can do right now?
Use the AURA-State header to return the capability list for the current session. It is advisory; the server remains the source of truth.
What if my endpoints use path and query parameters?
Use RFC 6570 URL templates in urlTemplate and JSON Pointer in parameterMapping.
Can I add my own fields to the manifest?
Yes. The current schema allows additional fields. Clients should ignore unknown keys; prefer namespacing extensions (for example, x-your-org).
See:
TROUBLESHOOTING.md: Common setup and runtime issues.MANIFEST_VALIDATION.md: Validator usage and schema troubleshooting.packages/reference-server/DEPLOYMENT.md: Deployment notes for the reference server.
AURA builds on URI templates (RFC 6570) and JSON Pointer (RFC 6901) for deterministic parameter binding.
MIT