KYA Platform Documentation
Complete developer documentation for the Know Your Agent (KYA) and Know Your Developer (KYD) Platform
Welcome to the KYA Platform
The Know Your Agent (KYA) Platform provides enterprise-grade identity verification and trust management for AI agents and developers. Build confidence in your AI systems with our comprehensive verification infrastructure.
Quick Integration
Get started in minutes with our simple REST API and comprehensive SDKs
Enterprise Security
Bank-grade security with OAuth 2.0, MFA, and end-to-end encryption
Fully Managed
We handle the complexity so you can focus on building great AI products
Why Choose KYA Platform?
For AI Developers
- →Establish trust for your AI agents without complex infrastructure
- →Get verified credentials that users and enterprises recognize
- →Track agent performance and trust metrics in real-time
- →Seamless integration with existing AI frameworks
For Enterprises
- →Verify AI agents before deployment in production
- →Maintain compliance with AI governance requirements
- →Centralized management for all AI agent interactions
- →Detailed audit trails and compliance reporting
Core Concepts
AI Agents
Any autonomous AI system that performs tasks, makes decisions, or interacts with users.
Trust Scores
Dynamic scoring system (0-100) that evaluates agent reliability, security, and performance.
Verification Levels
Progressive verification system from basic registration to full enterprise compliance.
Blockchain-Secured Records
All verifications are secured on blockchain for immutability and decentralization.
100% Web2 Friendly: No wallet, no crypto, no gas fees. We handle all blockchain complexity behind our simple API.
PDLSS Permission Boundaries
Every agent registered on AstraSync has PDLSS boundaries that define what it can do, when, how much, where, and whether it can spawn sub-agents. Counterparties use these boundaries to make informed access decisions.
PDLSS is immutable post-registration. Once an agent is registered, itspdlss,model,framework,agentType, andapiEndpoint are fixed for the life of that record. Attempting to PATCH them returns409 pdlss_immutable. To change permissions, retire this agent and register a new one. An in-place upgrade flow is on the roadmap; ownership transfer is a separate feature for changing an agent's owner, not its permissions. See Agent Access for the registration-flow walkthrough.
PPurpose
Action categories the agent is allowed to perform.
{
categories: ['read_data', 'write_data', 'execute_action'],
allowedActions: ['search', 'create_report'],
deniedActions: ['delete_account']
}DDuration
Time windows and session limits.
{
maxSessionDuration: 3600, // 1 hour max
ttl: 1800, // 30 min token lifetime
allowedDays: [1, 2, 3, 4, 5], // Weekdays only
allowedHours: { start: 9, end: 17 },
timezone: 'America/New_York'
}LLimits
Transaction thresholds with approval tiers.
{
autonomousThreshold: 100, // Under $100: auto-approved
stepUpThreshold: 1000, // $100-$1000: requires MFA
approvalThreshold: 10000, // Over $1000: manual approval
maxTransactionsPerHour: 50,
currency: 'USD'
}SScope
Resources, jurisdictions, and counterparty rules.
{
jurisdictions: ['US', 'AU'],
resources: ['/api/data/*'],
unverifiedCounterpartyPolicy: 'deny',
minCounterpartyTrustScore: 60
}SSelf-Instantiation
Rules for sub-agent spawning by an already-registered orchestrator. This is not the primary agent's own onboarding — primary agents always need human-in-the-loop or crypto-keypair step-up to register (seeAgent Access). Self-instantiation governs whether a registered agent can mint downstream workers inside its own PDLSS envelope.
{
allowed: true,
maxSubAgents: 3,
maxDepth: 2,
inheritPermissions: true,
requireApproval: true
}Complete Example: Customer Support Agent
A real-world PDLSS configuration combining all five dimensions:
{
purpose: {
categories: ['read_data', 'write_data'],
allowedActions: ['search', 'create_ticket', 'update_ticket'],
deniedActions: ['delete_account', 'export_all_data']
},
duration: {
maxSessionDuration: 3600,
ttl: 1800,
allowedDays: [1, 2, 3, 4, 5],
allowedHours: { start: 9, end: 17 },
timezone: 'America/New_York'
},
limits: {
autonomousThreshold: 100,
stepUpThreshold: 1000,
approvalThreshold: 10000,
maxTransactionsPerHour: 50,
currency: 'USD'
},
scope: {
jurisdictions: ['US', 'AU'],
resources: ['/api/support/*', '/api/tickets/*'],
unverifiedCounterpartyPolicy: 'deny',
minCounterpartyTrustScore: 60
},
selfInstantiation: {
allowed: true,
maxSubAgents: 3,
maxDepth: 2,
inheritPermissions: true,
requireApproval: true
}
}Worked register call (SDK)
The complete payload using @astrasyncai/verification-gateway:
import { AstraSync } from '@astrasyncai/verification-gateway/registration';
const client = new AstraSync({ apiKey: process.env.ASTRASYNC_API_KEY });
await client.register({
name: 'My Shopping Agent',
agentType: 'shopping_assistant',
apiEndpoint: 'https://my-agent.example.com/astrasync',
model: { modelName: 'claude-opus-4-7', modelProvider: 'anthropic', modelType: 'llm' },
framework: { frameworkName: 'langchain', frameworkVersion: '0.3.0' },
// First-class as of v1.0.0 (was previously stuffed in metadata.protocols[]).
protocols: ['acp', 'ap2', 'a2a', 'vi', 'mpp', 'ucp'],
pdlss: {
purpose: { categories: ['shopping'], allowedActions: ['search', 'compare', 'purchase'] },
duration: { maxSessionDuration: 3600 },
limits: { autonomousThreshold: 50, approvalThreshold: 500, currency: 'AUD' },
scope: { jurisdictions: ['AU', 'NZ'] },
},
});Trust score: dynamic and intentionally opaque
trustScore is recomputed at runtime on every request from the agent's metadata, certifications, observed behaviour, and policy state — the value at register-time is a baseline only.
The exact algorithm is intentionally opaque (anti-gaming).Score improves with metadata completeness — populatingmodel,framework, and certifications is the most reliable lever you have.
Why agents can't read their own permissions
GET /api/agents/{id}returns 403 when the caller is the agent itself. This is by design: permissions live in your agent's context window from registration onward. If an agent has to ask "what can I do?" at runtime, that itself is a drift signal — natural forgetting, prompt injection, or hijack.
The owner can read permissions via the dashboard or via API key auth at any time. The agent's own bearer token cannot.
Registering without an account: the async outreach path
If your agent runs against a counterparty whose owner does not yet have an AstraSync account, use POST /agents/request-registration. That endpoint is unauthenticated and emails the owner an onboarding link. The response includes a requestIdyou can poll via GET /agents/request-registration/{requestId}until status flips to approved.
See Agent Access for the full sync-vs-async flow comparison.
Agent Access & Step-Up
Two paths register an agent: synchronous (owner has an AstraSync account and a verified KYD) or asynchronous outreach(owner doesn't yet). Both end with a registered agent under the owner's authorising party. They differ in who initiates and how step-up is applied.
Step-up rules at registration
| Auth method | Step-up requirement |
|---|---|
| Crypto keypair | None — the keypair is the step-up. |
| API key (any) | Always required. POST /agents/register with API-key auth returns 202 pending_approval with a requestId; the owner is emailed a Sign-In-To-Accept link and a dashboard alert is emitted. The agent activates only on owner approval.Use sdk.register({ waitForApproval: true }) to block until the request resolves, or omit the flag and call sdk.pollRegistration(requestId) later. |
| KYD ID on account | Precondition for any API-key agent registration. Without it, the API key cannot register agents (returns 403 KYD_REQUIRED). |
| KYD-verified (passport + selfie) | Bumps owner trust score. Does NOT bypass step-up. |
The 3-step verification handshake
- Owner sets agent's PDLSS at registration. Immutable thereafter. This is the agent's declared envelope.
- Merchant sets endpoint access policy at endpoint registration. Independent of any single agent — describes what the endpoint will accept from anyone.
- Per session:agent declares intended PDLSS for this call → merchant checks against endpoint policy → AstraSync confirms the agent is operating within its registered boundaries → approve + record. If outside endpoint policy: merchant denies + records. If within endpoint policy but outside the agent's registered boundaries: AstraSync tells merchant to deny + records.
Both agent and merchant have purposes; session intent must overlap with both envelopes for access to be granted.
Runtime challenge timing
The runtime challenge fires at first verify-access, not at register.apiEndpoint is immutable post-registration, so the recommended deploy order is:
- Deploy your agent endpoint first.
- Register the agent against that endpoint URL.
- First counterparty call triggers the challenge handshake.
If the challenge fails (endpoint unreachable / wrong response), the call is denied — but the agent record itself remains valid. Bring your endpoint up and retry.
Async outreach: register on someone else's behalf
When the owner doesn't yet have an account:
POST /api/agents/request-registration
{
"agentName": "Their agent",
"ownerEmail": "[email protected]",
"agentDescription": "...",
"reason": "..."
}
→ 202 { "requestId": "uuid", "message": "..." }We email the owner. If they already have an account, the email links straight to a sign-in page that lands on the pending-approval queue. Otherwise it walks them through account + KYD + agent registration. Poll status:
GET /api/agents/request-registration/{requestId}
→ 200 {
"status": "pending" | "approved" | "denied" | "expired",
"agentId": "uuid | null",
"requestedAt": "...",
"lastEventAt": "..."
}Quick Start
Four steps to register your first AI agent on the KYA Platform.
Create Account
Sign up with email or use OAuth for instant access. Enable MFA for enhanced security.
Set Up Developer Profile
Create your Know Your Developer (KYD) profile with basic details to get started. Optional identity verification earns additional trust score points.
Generate Credentials
Create an API key or crypto key pair from your dashboard for programmatic access via the SDKs or REST API.
Register Agent
Use the SDK — it routes synchronously when signed and queues for owner approval when not. Raw HTTP is available for non-Node clients.
import { AstraSync } from '@astrasyncai/verification-gateway/registration';
const sdk = new AstraSync({ apiKey });
const result = await sdk.register({ name: 'My Agent' });API Overview
RESTful Architecture
Read Operations
Fetch agents, users, verification status
Create Operations
Register agents, initiate verifications
Update Operations
Modify agent details, update settings
Delete Operations
Remove agents, revoke access
Key Endpoints
POST /api/agents/registerRegister an agentGET /api/agents/:astraIdPublic agent lookupPOST /api/agents/verify-accessAgent verification (Handshake)POST /api/auth/loginAuthenticationGET /api/healthService health checkAgent listing restricted to dashboard
The GET /api/agents endpoint is only available via the web dashboard (JWT auth). API key and SDK callers cannot list agents. This prevents agent ID enumeration — an API key holder could otherwise discover sibling agent IDs and inspect their PDLSS boundaries or impersonate them. To view your agents, use the dashboard at /agents.
verify-access response contract
Authoritative shape of the POST /api/agents/verify-access response. Two branches: verified-agent (request body included an agentId matching a registered agent) and anonymous (no agentId — endpoint policy resolves the call). Both branches return 200 OK on success and emit a verification.* event for the activity feed and blockchain audit trail.
Why two linkage keys (sessionId vs correlationId)? They are not two implementations of the same concept. sessionIdidentifies a verified agent's tracked session and threads through PDLSS, runtime challenge, and token guidance. correlationId pairs anonymous events for activity-feed linkage where no agent identity exists. Both serve the same role on their branch — the linkage key for downstream paired events — but they represent two genuinely different identity states by design.
Common fields (both branches)
{
"success": true,
"access": {
"allowed": boolean,
"accessLevel": "none" | "restricted" | "read-only" | "standard" | "full",
"reason": string
},
"recommendation": "grant" | "deny" | "step_up_required" | "audit",
"recommendationReasons": string[],
"advisory"?: { // present on anonymous responses
"ial": "unverified",
"registrationUrl": string,
"docsUrl": string,
"policy": "deny" | "audit" | "allow_partial" | "allow_full",
"restrictionsExplained": string[]
},
"warningHeader"?: { // present when policy = 'audit'
"name": "X-Astra-Unverified-Warning",
"value": string
}
}access.accessLevel is the band the SDK enforces routes against. v2.3.9 renamed guidance → restricted to remove the value-name collision with the guidance: {} response object that never existed (denial branches return none).
recommendation is the four-bucket activity-feed bucket the event is counted under. audit (v2.3.8+) is a soft-launch grant that allows the call but stamps an X-Astra-Unverified-Warningheader on the merchant's response — distinct from grant (verified) and deny.
Verified-agent branch — request body included agentId
{
"success": true,
"access": { "allowed": true, "accessLevel": "standard", "reason": "..." },
"recommendation": "grant",
"recommendationReasons": ["..."],
"agent": {
"astraId": "ASTRA-...",
"name": string,
"trustScore": number,
"agentStatus": "active",
"blockchainStatus": "verified",
"runtimeChallengeSupported": boolean
},
"sessionId": "uuid", // ← key field (see below)
"tokenGuidance"?: { ... }, // present when SDK opted in
"runtimeChallenge"?: { ... } // present when challenge was issued
}sessionId is the verified-traffic correlation key. The SDK uses it to report local overrides (e.g. an MCP toolGate floor exceeds the granted band) via POST /api/agents/verify-access/{sessionId}/decision with overriddenBy + requestedLevel + grantedLevel so the activity feed shows a verification.local_override event paired with the original grant.
Anonymous branch — no agentId in request body
Triggered when the calling agent is not registered (or the SDK chose not to send an ASTRA-id). The endpoint's unverifiedAgentPolicy resolves the response. All four policy values produce the same wire shape but populate access, recommendation, and advisory.policy differently.
{
"success": true,
"access": { "allowed": boolean, "accessLevel": "...", "reason": "..." },
"correlationId": "uuid", // ← key field, anonymous-only (see below)
"advisory": {
"ial": "unverified",
"registrationUrl": "https://astrasync.ai/register",
"docsUrl": "https://astrasync.ai/docs/agent-access",
"policy": "deny" | "audit" | "allow_partial" | "allow_full",
"restrictionsExplained": ["..."]
},
"warningHeader"?: { ... }, // only when policy = 'audit'
"agent"?: { ... }, // only when caller fingerprint matched a known platform
"recommendation": "grant" | "deny" | "step_up_required" | "audit",
"recommendationReasons": ["..."]
}correlationId (v2.3.10+) is the anonymous-traffic linkage key. The backend mints a fresh correlationIdper anonymous request, persists it on the emitted event, and surfaces it on the response. SDK >= 2.3.10 reads it onto EnhancedVerificationResult.correlationId and posts to POST /api/agents/verify-access/local-overrideto record any SDK-side override of the server's grant. correlationId plays the same event-pairing role on the anonymous branch that sessionId plays on the verified branch — they are mutually exclusive by design, not transitional.
Sessionless local-override report — POST /agents/verify-access/local-override
The SDK calls this when it locally denies a call the server granted (e.g. MCP toolGates floor exceeds access.accessLevel) AND there's no sessionId available (anonymous traffic). Rate-limited to 30/minute/IP.
POST /api/agents/verify-access/local-override
Content-Type: application/json
{
"correlationId": "uuid", // from the original verify-access response
"overriddenBy": "toolGate" | "methodGate" | "trustScore" | "other",
"toolName"?: "start_checkout",
"requestedLevel": "standard", // what the local floor required
"grantedLevel": "restricted", // what the server granted
"reason"?: "toolGate floor exceeded"
}
# 200 → emits verification.local_override event linked to the original
# event by correlationId. counterpartyId / counterpartyOwnerId
# are inherited from the original event so the activity feed
# attributes the override correctly.
# 404 → correlationId did not match any anonymous verify-access event
# 400 → malformed payload (Zod rejection)
# 429 → rate limit exceededActivity-feed event types you'll see
| eventType | When it fires | Carries |
|---|---|---|
verification.completed | Verified-agent grant. | sessionId, recommendation: grant, trustScoreAtRequest |
verification.unverified_audit | Anonymous call, endpoint policy = audit. | correlationId, recommendation: audit, decision: audit |
verification.unverified_allow_partial / verification.unverified_allow_full / verification.unverified_deny | Anonymous call, matching the endpoint's unverifiedAgentPolicy. | correlationId, recommendation matching policy |
verification.local_override | SDK locally denied a server-granted call. Either keyed on sessionId (verified traffic) or correlationId (anonymous). | overriddenBy, toolName?, requestedLevel, grantedLevel, decision: denied |
verification.agent_not_found | Request body included agentIdthat doesn't exist. | errorMessage, no sessionId / correlationId |
counterparty.discovery_blocked | Auto-register URL validation rejected a placeholder/non-FQDN URL (v2.3.10). | reason: url_hostname_*, counterpartyUrl |
Click any row in /activity > Recent Activity to expand the full eventData payload — useful for verifying paired-event linkage (a verification.local_override row should share its correlationId with an earlier verification.unverified_* row).
Contract stability
The shape above is the v2.3.10+ contract. Older SDK releases may see narrower field sets. Specifically:
correlationIdon anonymous responses — added v2.3.10 (defect #34 fix). Mutually exclusive withsessionIdby design (anonymous vs verified branch); not a transitional field.recommendation: 'audit'— added v2.3.8 (defect #26).access.accessLevel: 'restricted'(replaces'guidance') — added v2.3.9 (defect #30).warningHeaderon audit responses — added v2.3.8.
Field additions are non-breaking — older SDKs ignore unknown keys. Removing or renaming a documented field is a breaking change and ships in a major bump.
Platform Features
Everything you need to manage AI agent identity and trust at scale.
Authentication & Security
- OAuth 2.0 (Google & GitHub)
- Multi-Factor Authentication
- API Key Management
- Role-Based Access Control
Verification Services
- AI Agent Registration
- Developer KYD Verification
- PDLSS Permission Policies
- Agent Handshake Protocol
- Runtime Challenges
- Trust Score Calculation
Analytics & Monitoring
- Real-time Dashboards
- Usage Analytics
- Trust Trend Analysis
- Audit Logging
Team Management
- Multi-user Accounts
- Team Permissions
- Activity Tracking
- Shared Resources
Integration Options
- REST API
- Verification Gateway SDK
- Cross-Protocol Transport (HTTP, A2A, MCP)
- Webhook Events
- SDK Libraries
Data Management
- Encrypted Storage
- Data Export Tools
- Backup & Recovery
- GDPR Compliance
Integration Guide
Multiple ways to integrate KYA Platform into your workflow with our production-ready SDKs.
Python SDK
Register and manage AI agents with API key auth, email+password, or secp256k1 crypto signing. Includes CLI and decorator support.
pip install astrasyncai
from astrasyncai import AstraSync
client = AstraSync(api_key="kya_your_api_key")
result = client.register(
name="My AI Assistant",
model={
"model_name": "claude-opus-4.6",
"model_provider": "anthropic",
"model_type": "llm",
},
)
print(f"Agent ID: {result['data']['agent']['kyaAgentId']}")
print(f"Trust Score: {result['data']['agent']['trustScore']}")Node.js / TypeScript SDK
TypeScript SDK with complete type definitions, 3 auth methods, and full model/framework/PDLSS registration support. Includes CLI.
npm install @astrasyncai/verification-gateway
import { AstraSync } from '@astrasyncai/verification-gateway/registration';
const client = new AstraSync({
apiKey: 'kya_your_api_key'
});
const result = await client.register({
name: 'My AI Agent',
model: {
modelName: 'gpt-4o',
modelProvider: 'openai',
modelType: 'llm',
},
});
console.log(`Agent ID: ${result.data.agent.kyaAgentId}`);Framework & Model Metadata
Pass your agent's framework and model metadata during registration to improve its trust score. AstraSync works with any AI agent framework — just include the name and version:
// Node.js
await client.register({
name: 'My Agent',
model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },
framework: { frameworkName: 'langchain', frameworkVersion: '0.3.0' },
});
# Python
client.register(
name="My Agent",
model={"model_name": "gpt-4o", "model_provider": "openai", "model_type": "llm"},
framework={"framework_name": "crewai", "framework_version": "0.1.0"},
)Providing model and framework metadata contributes to the Origin component of your agent's trust score (up to 5 points for platform+model data).
Registration — SDK first
Use @astrasyncai/verification-gateway for all registration — both developer-CLI calls and autonomous agent self-registration. The SDK handles the API-key step-up handshake for you (202 → owner approval → poll). Raw HTTP is documented for non-Node clients only.
import { AstraSync } from '@astrasyncai/verification-gateway/registration';
const sdk = new AstraSync({
apiKey: process.env.ASTRASYNC_API_KEY,
// Optional: signature auth for synchronous 201 registration
privateKey: process.env.ASTRASYNC_PRIVATE_KEY,
});
// Long-running / CLI pattern — block until approved
const agent = await sdk.register({
name: 'My AI Agent',
description: 'Handles customer inquiries',
apiEndpoint: 'https://my-agent.example.com', // runtime-challenge URL (optional)
model: { modelName: 'claude-opus-4.6', modelProvider: 'anthropic', modelType: 'llm' },
waitForApproval: true,
});
// Or non-blocking — best for serverless / scheduled agents
const result = await sdk.register({ name: 'My AI Agent' });
if (result.status === 'pending_approval') {
storage.set('astrasync.requestId', result.requestId);
}Raw HTTP fallback (non-Node clients)
curl -X POST https://astrasync.ai/api/agents/register \
-H "Authorization: Bearer kya_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "My AI Agent",
"description": "Handles customer inquiries",
"apiEndpoint": "https://my-agent.example.com",
"model": {
"modelName": "claude-opus-4.6",
"modelProvider": "anthropic",
"modelType": "llm"
}
}'
# API-key auth returns 202 pending_approval with a requestId.
# Poll: GET https://astrasync.ai/api/agents/request-registration/{requestId}
# Crypto-keypair signed (X-AstraSync-Signature header) returns 201 sync.Verification Gateway SDK
The Verification Gateway SDK enables any service to verify incoming AI agent requests and enables agents to present their credentials across HTTP, A2A, and MCP protocols.
Two SDKs, two roles — pick by who you are
AstraSync ships two npm packages. They are not alternatives — they sit on opposite sides of the verify-access call.
If you are…
A merchant / API / counterparty
You receive traffic from AI agents and want to enforce policy on it.
Install @astrasyncai/verification-gateway
Express / Next.js middleware, MCP / A2A adapters, the verify() helper, and the webhook signature verifier all live here.
If you are…
An agent author / developer
You build the AI agent that authenticates against AstraSync and calls merchants.
Install @astrasyncai/verification-gateway
Agent registration, credential presentation (prepareMcpMeta, prepareA2AMetadata), trust-score helpers, and KYD onboarding flows.
One end-to-end verification involves both: the agent author's SDK signs the request; the merchant's gateway verifies it. If you're unsure which one to install, the rule is verification-gateway = the side that answers, agent-registration = the side that asks.
Counterparty-Side: Verifying Incoming Agents
Mount Express middleware to verify agents hitting your API. The middleware calls AstraSync's verify-access endpoint and populates req.agentVerification with the result.
import { createMiddleware } from '@astrasyncai/verification-gateway/express';
// v2.3.7+ — per-route policy lives in the AstraSync dashboard.
// The SDK fetches it on init via counterpartyId; do NOT pass routes here.
app.use(createMiddleware({
apiBaseUrl: 'https://astrasync.ai/api', // always includes /api
apiKey: process.env.ASTRASYNC_API_KEY,
counterpartyId: 'ASTRAE-...', // your endpoint id from the dashboard
setPassThroughHeader: true, // recommended for staging — surfaces
// pass-through mode when no policy
// is configured (see /docs#endpoints)
}));After middleware runs, req.agentVerification contains (v2.3.0+):
- →
.verified— whether the agent passed verification - →
.accessLevel— server-decided level (none, restricted, read-only, standard, full, internal). The SDK reads this verbatim from the verify-access response — no client-side trust-score remap (v2.3.0+ contract). v2.3.9 (defect #30): renamedguidanceband →restricted. See the trust-score tier cheatsheet below for the canonical mapping. - →
.agent—astraId,name,trustScore,agentStatus(wasstatus),blockchainStatus(new:verified|pending|failed|unverified) - →
.advisory— present on anonymous calls (v2.3.0+).{ial, registrationUrl, docsUrl, policy, restrictionsExplained}tells the agent how to upgrade based on the endpoint'sunverifiedAgentPolicy. - →
.pdlss— full permission boundaries - →
.tokenGuidance— recommended scopes, TTL, rate limits - →
.recommendation— grant, deny, or step_up_required
Trust-score tier cheatsheet
The server resolves accessLevelfrom the agent's live trust score against the endpoint's trustScoreRequirement. Canonical thresholds (defined in apps/backend/src/utils/access-levels.ts and shipped verbatim by the SDK):
| Trust score | accessLevel | What the SDK does |
|---|---|---|
| 0–19 | none / restricted | Anonymous policy applies; verified agents below threshold get blocked or restricted-only. |
| 20–39 | read-only | GET-style routes; no writes / payments. |
| 40–69 | standard | Default tier for verified agents — POSTs, transactions within PDLSS limits. |
| 70+ | full | Unrestricted within boundary; high-trust agents. |
| same-org | internal | Calling agent shares the endpoint's owner — bypasses PDLSS scope checks. |
Set routes[].minAccessLevel in the middleware config to gate routes by tier. The mapping is server-authoritative — DO NOT pass minTrustScore / minTrustScoreForFull to GatewayConfig (deprecated since v2.3.0).
Anonymous traffic is now first-class (v2.3.0+)
When an agent hits your endpoint without an ASTRA-id, the SDK forwards the call to the server with no agentId. The server applies the endpoint's unverifiedAgentPolicy (see the Endpoint PDLSS section):
deny→access.allowed=false, advisory points the caller at registration.audit(v2.3.8+) →access.allowed=true+X-Astra-Unverified-Warningresponse header, activity feed records "granted (audit)".allow_partial→access.accessLevel="restricted", advisory explains restrictions + how to upgrade. (v2.3.9: wasguidance, renamed to remove value-name collision with the help-payload object.)allow_full→access.accessLevel="standard", advisory recommends registration for next time.
Every branch always emits a verification event + queues a blockchain audit record. Recognised platform agents (Claude / ChatGPT / Gemini / Cursor / Goose) get an auto-provisioned provisional ASTRA-id (IAL=1) so they appear in the AstraSync admin panel under the auto-provisioned tab.
Configure attribution + init self-test (v2.3.0+)
createMiddleware({
apiBaseUrl: 'https://astrasync.ai/api', // always include /api
counterpartyId: 'ASTRAE-xxxxx', // your endpoint's ASTRAE-id from registration
counterpartyUrl: 'https://merchant.example',
// disableInitChecks: true // skip the HEAD probe in tests
});counterpartyId tells the server to attribute traffic by ASTRAE-id rather than resolving by URL — useful when the same merchant runs multiple endpoints under one origin (e.g. /checkout + /mcp with separate policies).
On first verify() call the SDK fires a HEAD probe to ${apiBaseUrl}/agents/verify-access and warns once if the response content-type is text/html — catches the case where apiBaseUrl is pointing at a marketing 404.
Enhanced Verification with Sessions
import { verify } from '@astrasyncai/verification-gateway';
const result = await verify(config, {
credentials: { astraId: 'ASTRA-xxxxx' },
purpose: 'financial_transaction',
createSession: true,
enableRuntimeChallenge: true,
});
// result.sessionId, result.runtimeChallenge, result.tokenGuidanceRecording a Decision
import { recordDecision } from '@astrasyncai/verification-gateway';
await recordDecision(config, {
sessionId: result.sessionId,
decision: 'granted',
reason: 'Agent meets all requirements',
tokenIssued: true,
});Agent-Side: Presenting Credentials
Use AgentClient to automatically inject AstraSync credentials into outgoing requests across all supported protocols.
import { AgentClient } from '@astrasyncai/verification-gateway';
const client = new AgentClient({
agentId: 'ASTRA-xxxxx',
challengeUrl: 'https://my-agent.com/astrasync/challenge',
pdlss: {
purpose: { category: 'read_data' },
duration: { maxSessionDuration: 3600 },
scope: { jurisdiction: 'US' },
},
});
// HTTP — headers auto-injected
const response = await client.fetch('https://counterparty.com/api/data');
// A2A — metadata.astrasync block auto-added
const task = client.prepareA2AMetadata({ id: 'task-1' });
// MCP — _meta.astrasync block auto-added
const params = client.prepareMcpMeta({ tool: 'search', query: '...' });X-Astra-* Headers (HTTP Transport)
| Header | Value | Example |
|---|---|---|
X-Astra-ID | Agent ASTRA ID | ASTRA-wEDhecjrlWEqPNQU4htX6g |
X-Astra-Verify | Verify-access URL | https://astrasync.ai/api/agents/verify-access |
X-Astra-Challenge | Challenge endpoint | https://my-agent.com/astrasync/challenge |
X-Astra-Purpose | Purpose category:action | read_data:search |
X-Astra-Duration | Max session seconds | 3600 |
X-Astra-Scope | Jurisdiction | US |
Challenge/Response Mechanism
Runtime challenges verify that the agent actually initiated the request (prevents MITM attacks). The flow works as follows:
runtimeChallengeSupported: false so counterparties can factor that into their decision. This is a trust signal, not a hard requirement.- Agent registers pending counterparties before initiating contact
- Agent makes request to counterparty with AstraSync headers
- Counterparty calls verify-access with
enableRuntimeChallenge: true - AstraSync POSTs challenge to agent's
/astrasync/challengeendpoint - Agent's ChallengeHandler responds with pending counterparty list
- AstraSync validates (challengeId match, counterparty in list, timestamp fresh)
Setting Up the ChallengeHandler
import { ChallengeHandler } from '@astrasyncai/verification-gateway';
const handler = new ChallengeHandler({ agentId: 'ASTRA-xxxxx' });
// Before contacting a counterparty, register them as pending
handler.registerPending('counterparty-api-id');
// Mount the challenge endpoint
app.post('/astrasync/challenge', handler.expressMiddleware());
// After interaction is complete, clean up
handler.removePending('counterparty-api-id');Challenge Payload (sent to agent)
{
"challengeId": "uuid",
"type": "pending_verification",
"counterpartyId": "counterparty-api-id",
"question": "List the counterparties currently in your pending interaction list",
"issuedAt": "2026-02-24T10:00:00Z",
"expiresAt": "2026-02-24T10:00:30Z"
}Expected Response (from agent)
{
"challengeId": "uuid",
"acknowledged": true,
"pendingCounterparties": ["counterparty-api-id", "other-service"],
"respondedAt": "2026-02-24T10:00:01Z"
}Endpoint Management
Endpoints are the inbound surfaces that agents interact with — APIs, MCP servers, websites, or agent-to-agent callbacks. AstraSync lets you register the endpoints you operate, attach a PDLSS policy to them, restrict who can call them, and see real-time activity with cross-account privacy baked in.
Three verification tiers
URL seen in verify-access traffic under your account but not formally registered yet. Auto-created when your SDK reports a new URL.
You've claimed the URL. Issues an ASTRAE-id. Proof of ownership is not yet enforced — first claim wins, scoped to your account.
Future tier: DNS TXT or /.well-known/astrasync.json proof unlocks the endpoint trust score and cross-account recognition.
Register & Claim
Two paths produce a registered endpoint:
1. Direct registration
POST /api/endpoints
Authorization: Bearer <api-key>
Content-Type: application/json
{
"counterpartyType": "api",
"name": "Invoice API",
"endpointUrl": "https://api.example.com",
"trustScoreRequirement": 20
}
# → returns astraeId "ASTRAE-<22-char>"2. Claim from the Discovered tab
Every authenticated verify-access call with a counterpartyUrlthat doesn't match a registered row creates a discovered row owned by the caller (the SDK operator). These appear in the Discovered tab at /endpoints — click Claim to promote them to self_asserted without losing traffic history.
Removing auto-registered endpoints from your active list
Auto-registered endpoints carry an auto-registered badge on the endpoints list. To remove one from your active list, use the standard Deactivateaction — the same flow you'd use for endpoints you registered yourself. There's no separate “Dismiss” action: deactivate is the dismiss path for auto-registered rows.
Deactivated rows remain available under the Deactivated tab so audit history stays intact. Use Archive from there if you want the row out of the default views permanently — the underlying audit events are not deleted, just hidden from the working list.
Where orphans live (management vs activity views): auto-registered or discovered orphan endpoints attributed to your account appear in /activity → Endpoints for traffic-attribution and audit purposes. The /endpointsmanagement view filters to endpoints you've explicitly claimed — that's deliberate so the working list stays focused on owned configuration. To deactivate or archive an orphan, find it under /activity → Endpoints, click through to its detail, and use the Deactivate action — same flow as for claimed endpoints.
Proof-of-ownership is not yet enforced
Registration today is self-asserted. DNS/well-known proof lands in a follow-up release alongside endpoint trust scoring. Until then, the first account to claim a URL blocks subsequent claims with a conflict error.
PDLSS on Endpoints
Endpoint policies mirror agent PDLSS. When an agent calls an endpoint, the enforcement engine evaluates bothboundaries — the agent's own and the endpoint's — and the intersection wins. The endpoint detail page at /endpoints/[id] exposes all five PDLSS dimensions:
Allowed purpose categories, allowed actions, denied actions.
Max session duration, TTL, business hours, day-of-week, timezone.
Autonomous / step-up / approval thresholds, tx rate caps, cumulative cap, ISO currency.
Resource globs (allow + deny), resource types, jurisdictions, unverified-agent policy, min trust score, required certifications.
Whether agents calling this endpoint may spawn sub-agents; max sub-agents, max depth, inherit permissions, require approval, allowed sub-agent purposes.
Anonymous-agent policy (unverifiedAgentPolicy, v2.3.0+)
Endpoint owners pick how the canonical verify-access flow handles callers who arrive without an ASTRA-id (no X-Astra-Id header, no agentId in the request body). One of four values, set at registration or via PUT /api/endpoints/:id:
deny(default) — the caller is rejected. Response carries anadvisoryblock pointing at the registration URL + docs. Strictest setting — recommended for endpoints handling sensitive operations.audit(v2.3.8+) — the caller is allowed through but AstraSync setsX-Astra-Unverified-Warningon the response. Activity feed records as "granted (audit)". Soft-launch mode for endpoints transitioning to registration enforcement. Disjoint vocabulary from the PDLSS-scope outboundwarnvalue (see Inbound vs outbound docs).allow_partial— the caller is grantedaccessLevel="restricted"(browse-only, read-only) plus an advisory explaining what they can't do and how to upgrade. Recommended for content endpoints (catalog, public reads). v2.3.9: wasguidance; renamed to remove the value-name collision with theguidance: {}help-payload object.allow_full— the caller is grantedaccessLevel="standard"with no PDLSS-scoped token but is advised to register for next time. Recommended for fully public endpoints where you still want activity attribution.
All three branches always emit a verification.unverified_* event and queue a blockchain audit record. Recognised platform agents (Claude / ChatGPT / Gemini / Cursor / Goose) get an auto-provisioned provisional ASTRA-id under the AstraSync admin org regardless of which branch fires.
Webhook signature verification (v2.3.0+)
Endpoint registration returns a webhookSecret ONCE in the response body (subsequent GET calls mask it). Save it — when AstraSync delivers a webhook, the request carries an X-AstraSync-Signature header with HMAC- SHA256 over ${timestamp}.${rawBody}. Use the SDK helper to verify:
import express from 'express';
import { verifyAstraSyncWebhook } from '@astrasyncai/verification-gateway/webhooks';
app.post(
'/webhooks/astrasync',
express.raw({ type: 'application/json' }), // IMPORTANT: raw body
(req, res) => {
const result = verifyAstraSyncWebhook(
req.body.toString('utf8'),
req.headers,
process.env.ASTRASYNC_WEBHOOK_SECRET!
);
if (!result.ok) return res.status(401).json({ error: result.reason });
// ... handle event
res.status(204).end();
}
);5-minute replay tolerance (configurable). Outbound delivery from AstraSync is a separate engineering track — the contract + SDK verifier ship now so partners can implement verification today against test signatures.
Allowlist (KYD/KYO)
Allowlist entries are keyed on the account owner, not individual agents. Every active agent owned by the whitelisted account is then permitted, subject to trust score and purpose filters. Two identifiers are accepted:
ASTRAD-*— KYD identifier for individual developers (sole traders).ASTRAO-*— KYO identifier for organisations. Column exists today; organisation onboarding that issues ASTRAO-ids ships in a follow-up.
POST /api/endpoints/:id/allowlist
Authorization: Bearer <api-key>
{
"allowedOwnerIdentifier": "ASTRAD-4l061o2x",
"minTrustScore": 30,
"allowedPurposes": ["read_data"]
}Activity & Alerts
Every platform_events row now carries both owner_id(the calling agent's account) and counterparty_owner_id (the endpoint owner), so the same event powers activity views from either seat.
Agent-side (outbound)
/activity → Agents tab. Each agent row shows a categorisation badge cluster:
- Internal — endpoint owned by your account.
- External — endpoint owned by another AstraSync account. Privacy-masked: only ASTRAE-id and type surface.
- Unregistered — URL not claimed by any account.
Endpoint-side (inbound)
/activity → Endpoints tab. Expand any registered endpoint to see callers categorised:
- Internally governed — the calling agent is owned by your account.
- Externally governed — different AstraSync owner. ASTRA-id only; all other fields masked.
- Ungoverned — no AstraSync record. Source IP, User-Agent, Host, Referer, and Agent Card URL (when present) surface for forensics.
Alerts
Surfaced in the dashboard bell icon. Current codes:
sdk_unregistered_endpoint— warning fired when your SDK is operating on a URL still indiscoveredstate. Nudge to claim it.agent.ownership_mismatch_attempt— critical, fires on the legitimate agent owner's account when a foreign API key tries to use their ASTRA-id.
SDK Authentication
/api/agents/verify-access is authenticated — every call must identify the caller so attribution, rate limits, and the Discovered flow work correctly. Authenticate with an API key:
API key
Authorization: Bearer kya_<api-key>SDK config: new ExpressMiddleware({ apiKey: process.env.ASTRASYNC_KEY, ... }). The Express and Next.js adapters auto-wire this.
Caller metadata forwarding
When the SDK runs inside a counterparty server, the backend otherwise sees the counterparty server's own IP/UA — useless for endpoint-owner forensics. The Express and Next.js adapters auto-forward the agent-side fingerprint:
{
"callerMetadata": {
"sourceIp": "203.0.113.42", // First X-Forwarded-For hop or req.ip
"userAgent": "Mozilla/5.0 (…)",
"referer": "https://example.com/…",
"host": "api.yourservice.com",
"forwardedFor": "203.0.113.42, 10.0.0.1",
"agentCardUrl": "https://agent.example.com/.well-known/agent-card.json"
}
}Probe access — AstraSync-Probe/1.0
AstraSync reserves the User-Agent string AstraSync-Probe/1.0 for future endpoint health-checks and webhook-delivery validation. The probe is opt-in — nothing fires today — but if you operate a WAF, security gateway, or restrictive robots.txt, allow this UA on the paths you registered with AstraSync. Match-by-prefix (AstraSync-Probe/) so future versions don't need a config change.
# robots.txt
User-agent: AstraSync-Probe/1.0
Allow: /
Crawl-delay: 5See https://astrasync.ai/robots.txt for the canonical declaration on our own surface.
Local Guard
A free, local-only verification layer for AI agents. Define what your agent can and cannot do in a simple YAML policy file, and Local Guard enforces it — no account, no cloud connection, no telemetry. When you outgrow local mode, one command upgrades you to cloud-connected verification.
Step 1: Create Your Policy
All Local Guard adapters share the same PDLSS policy file. Create it once, then choose which adapter to run for your platform.
npm install @astrasyncai/verification-gateway
# Interactive wizard — creates local-policy.yaml
npx astrasync guard setupThe wizard asks plain-language questions about what your agent should be allowed to do and generates a local-policy.yaml file using the same PDLSS schema as the cloud — so upgrading later requires zero migration.
Step 2: Choose Your Adapter
Each adapter is a thin, platform-specific wrapper that intercepts agent actions and routes them through the shared PDLSS evaluation engine. The verification logic is identical across platforms — only the interception and enforcement mechanisms change.
Local Guard for OpenClaw CLI
HTTP proxy that sits between OpenClaw (or other CLI agents like Claude Code) and their tool servers. Intercepts tool call JSON, evaluates against your PDLSS policy, then blocks or forwards.
# Start the CLI proxy (uses your local-policy.yaml)
npx astrasync guard startLocal Guard for Cursor
VS Code extension that hooks into file create/delete/save, terminal open, and command execution events. Download the .vsix from GitHub releases and install directly.
# Download .vsix from GitHub releases, then:
code --install-extension astrasync-local-guard-2.0.0.vsixLocal Guard for OpenClaw Browser
Chrome extension for the OpenClaw browser agent. Intercepts web requests and navigation before they execute, with synchronous local evaluation for zero-latency blocking.
# Download extension from GitHub releases, then:
# Chrome → Extensions → Developer mode → Load unpackedCLI Commands
astrasync guard setupInteractive wizard to create your PDLSS policy file
astrasync guard startStart the local guard proxy with your policy
astrasync guard statusCheck guard status, mode, and recent activity
astrasync guard upgradeUpgrade from free local mode to cloud-connected verification
Free vs Paid
Local Mode (Free)
- Local PDLSS policy evaluation (<1ms)
- Interactive setup wizard
- CLI, IDE, and browser platform support
- JSONL audit trace (local file)
- No account required, fully offline
Online / Hybrid Mode
- Everything in Local Mode
- ASTRA-ID and trust score for your agent
- Cloud PDLSS boundaries with counterparty verification
- Runtime challenge/response (proves agent identity)
- Blockchain-secured audit trail
- Git push / PR trigger for enterprise governance
Enterprise: Git Push Trigger
In hybrid mode, Local Guard runs locally during development but automatically switches to cloud verification when code is pushed to a remote repository or a PR is created. This creates a governance boundary: local guardrails for development, full AstraSync verification for anything that reaches the remote codebase.
# Install git hooks for your repo
npx astrasync guard install-hooks
# Hooks auto-trigger on:
# - git push (pre-push hook)
# - git commit to protected branches (pre-commit hook)
# - Block or warn mode configurable per branchBlockchain Technology
Every verification is secured on the Skale blockchain for immutability and trust - without the complexity.
Powered by Skale Network
KYA Platform leverages Skale Network, an Ethereum-native modular blockchain network that provides instant finality and zero gas fees. This means enterprise-grade security without the traditional blockchain cost barriers.
Instant Finality
Transactions confirmed in under 1 second
Zero Gas Fees
No transaction costs for users or developers
EVM Compatible
Full Ethereum tooling and smart contract support
What We Handle For You
- All wallet management and key storage
- Gas fees and transaction costs (zero on Skale)
- Smart contract deployment and maintenance
- Network selection and optimization
Benefits You Receive
- Immutable audit trail for all verifications
- Decentralized trust without centralized control
- Public verifiability and transparency
- Zero blockchain knowledge required
Web2 Simplicity, Web3 Security:No cryptocurrency, no wallets, no gas fees for you. Just pay your subscription and we handle all the blockchain complexity. This is NOT a crypto product - it's enterprise verification powered by Skale's immutable ledger technology.
ERC-8004: On-Chain Agent Registry
ERC-8004 defines an on-chain Agent Registry where each agent is an ERC-721 token. AstraSync wraps ERC-8004 with KYA verification and PDLSS permission boundaries.
Agent Registration File
Each agent's agentURI(tokenURI) points to a spec-compliant JSON document describing the agent's services, trust frameworks, and identity. AstraSync's card generator produces this format automatically.
{
"type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
"name": "My Agent",
"description": "An AI agent registered on-chain",
"image": "https://example.com/avatar.png",
"services": [
{ "name": "web", "endpoint": "https://api.example.com/agent" },
{ "name": "A2A", "endpoint": "https://api.example.com/a2a" },
{ "name": "MCP", "endpoint": "https://api.example.com/mcp" }
],
"x402Support": false,
"active": true,
"registrations": [{
"agentId": 42,
"agentRegistry": "eip155:1187947933:0x8004A169...9a432"
}],
"supportedTrust": ["reputation", "astrasync-pdlss"],
"astrasyncId": "ASTRA-abc123..."
}Services
Agents declare their reachable endpoints via the services[] array:
Supported Trust Frameworks
The supportedTrust field declares which trust mechanisms the agent participates in:
PDLSS + ERC-8004: Complete Trust Lifecycle
ERC-8004's reputation model is post-execution — trust scores update after agent actions. AstraSync's PDLSS framework provides pre-execution governance. Together they form a complete trust lifecycle:
1. Pre-execution (PDLSS)
Purpose, Duration, Limits, Scope, Self-instantiation boundaries
2. Execution
Agent operates within PDLSS boundaries
3. Post-execution (Reputation)
Counterparties submit on-chain feedback
For the full ERC-8004 specification details, see the dedicated ERC-8004 documentation.
Commerce Protocols
The agent commerce ecosystem is fragmenting fast — Google, OpenAI, Stripe, Coinbase, and others each ship their own protocol for how agents communicate, transact, and prove payments. AstraSync absorbs that fragmentation. Agents declare every protocol they support in a single registration flow, get a pre-formatted agent card they can hand out, and use one SDK to actually speak the protocols at runtime. Counterparties read the same card and use the same SDK to decide whether to accept the agent.
Tier 1 vs Tier 2 — the persistence boundary
We split the commerce ecosystem into two tiers based on lifecycle, because they need very different handling:
Persistent (registration-time)
Capabilities the agent declares once and carries forever. Stored on the agent card, surfaced to every counterparty at verify-access time, used to derive PDLSS boundaries automatically. All 10 protocols have persistent metadata.
Commerce: A2A, ACP, AP2, UCP, MPP, x402, ERC-8004. Payment Networks: VI, Agent Pay, TAP.
Session-based (runtime)
Short-lived cryptographic tokens that prove a specific transaction is authorised. They flow through the request pipeline, get verified by the gateway, and disappear. Payment Network protocols (VI, Agent Pay, TAP) have both: a persistent declaration at registration AND session tokens at runtime.
Examples: VI SD-JWT chains, Agent Pay / TAP RFC 9421 signatures, ACP HMAC webhooks, UCP checkout sessions.
Tier 1 declarations answer "what can this agent do, in principle?". Tier 2 tokens answer "is this specific transaction authorised, right now?". Counterparties get both signals through one SDK call.
What AstraSync does for you
Multi-protocol in one registration
Declare A2A + ACP + AP2 + MPP at once via a single checkbox grid. Shared fields (URLs, provider name) are entered once and applied across protocols. Per-protocol fields render in collapsible sections so the form stays manageable. No duplicate registrations, no drift between protocol-specific accounts.
Pre-formatted agent cards
Registration produces a portable JSON agent card that includes every declared protocol's metadata, the verification gateway endpoint, the runtime-challenge capability flag, PDLSS boundaries, and on-chain identity if you've registered one. Hand it out, embed it in your agent.json discovery file, attach it to outbound requests — counterparties parse it the same way every time.
One SDK, every transport
The verification gateway SDK abstracts HTTP, MCP, A2A, and the commerce protocol transports under one credential injection / extraction surface. Your agent calls gateway.fetch(); the SDK picks the right transport, attaches the right headers, handles RFC 9421 signing for Agent Pay / TAP, and parses x402 challenges — without your code knowing the details.
PDLSS pre-populates from declarations
When you declare AP2 with a $500 transaction cap, PDLSS auto-fills the autonomous and hard limit at $500 — your protocol declarations become your permission boundaries with no double entry. Multi-protocol agents get the most restrictive merge across protocols (lowest spend cap wins, jurisdictions union, currencies first-non-default).
For counterparties & merchants
The same verification gateway SDK that agents use is what counterparties use to interpret the declarations. One verify-access call returns:
- Declared protocols as an array — you can route an ACP request differently from a UCP request without negotiating capabilities up front.
- PDLSS boundariesalready merged from every declared protocol — you see the maximum transaction value the agent is authorised for, the jurisdictions it's scoped to, the counterparties it's allowed to transact with.
- Runtime trust signals like
runtimeChallengeSupported(whether the agent has a verification endpoint mounted), trust score, and KYD status — useful for tier-based acceptance policies. - Recommendation —
grant,step_up_required, ordeny— and the reasons, so you can either trust the recommendation or apply your own logic on top.
import { CounterpartyClient } from '@astrasyncai/verification-gateway';
const client = new CounterpartyClient({ apiKey: process.env.ASTRASYNC_KEY });
const result = await client.verifyAccess({
agentId: req.headers['x-astrasync-agent-id'],
purpose: 'financial_transaction',
transactionValue: 250,
currency: 'USD',
});
// result.agent.protocols → ['a2a', 'acp', 'mpp']
// result.agent.runtimeChallengeSupported → true
// result.pdlss.limits.approvalThreshold → 500
// result.recommendation → 'grant'Commerce protocols (persistent registration)
Every protocol below is selectable in the registration UI and lands in the agent card as a top-level metadata block. PDLSS pre-population fires automatically based on the fields you fill in. ERC-8004 has its own dedicated section above. Payment Network protocols (VI, Agent Pay, TAP) are in the next section.
A2A — Agent2Agent Protocol (Linux Foundation, v1.0 GA)
Google & Linux Foundation's open standard for how agents talk to other agents. Defines an agent card schema (name, skills, transports, security) and the JSONRPC / gRPC / HTTP+JSON transport options. Most agents declare A2A as a baseline communication protocol and layer commerce protocols on top.
You declare: agent URL, version, skills (≥1), transport, optional provider info and security schemes. What you get: the verification gateway endpoint pre-fills the agent URL automatically when both target the same server.
ACP — Agentic Commerce Protocol
OpenAI & Stripe's commerce checkout protocol. A merchant exposes a product feed, a checkout endpoint, and a webhook URL; agents discover the products and trigger Stripe-backed checkout sessions on the merchant's behalf.
You declare: merchant ID, checkout endpoint, product feed URL, webhook URL, supported payment methods (card / Apple Pay / Google Pay / Stripe Link / bank transfer), fulfillment options. PDLSS pre-fill: purpose financial_transaction, checkout domain + merchant:<id> added to counterparties.
{
"protocols": ["a2a", "acp"],
"acp": {
"merchantId": "merchant_abc123",
"checkoutEndpoint": "https://api.shop.com/checkout",
"productFeedUrl": "https://api.shop.com/feed",
"webhookUrl": "https://api.shop.com/webhooks/orders",
"supportedPaymentMethods": ["card", "apple_pay"],
"fulfillmentOptions": ["shipping", "digital_delivery"]
}
}AP2 — Agent Payments Protocol
Google's decentralised payment authorisation protocol. Identity is via DID (Decentralised Identifier); authority is granted through mandates (intent / cart / payment) signed by a human supervisor. Agents declare the maximum transaction value they're authorised for, allowed currencies and regions, and whether human delegation is enabled.
You declare: agent DID, max transaction value, allowed currencies, allowed regions, mandate types, delegation flag. PDLSS pre-fill: max transaction value flows to both autonomous and hard limits (the protocol-authorised amount IS the autonomous ceiling); allowed regions to jurisdictions; currency from the first allowed currency; delegation enables self-instantiation.
{
"protocols": ["a2a", "ap2"],
"ap2": {
"agentDid": "did:web:agent.example.com",
"policyClaims": {
"maxTransactionValue": 500,
"allowedCurrencies": ["USD"],
"allowedRegions": ["US", "GB"]
},
"delegationEnabled": true,
"mandateTypes": ["intent", "cart"]
}
}UCP — Universal Commerce Protocol
Google & Shopify's capability-based commerce protocol. The agent points at a UCP manifest (/.well-known/ucp) listing the capabilities it supports (checkout, discount, fulfillment, identity linking, order management, token exchange) and the transports it speaks (A2A, MCP, REST, embedded).
You declare: manifest URL, version, capabilities, transports, custom extensions. PDLSS pre-fill: checkout / payment capabilities add financial_transaction purpose; fulfillment adds execute_action; manifest domain added to counterparties.
{
"protocols": ["a2a", "ucp"],
"ucp": {
"manifestUrl": "https://shop.example.com/.well-known/ucp",
"version": "1.0",
"capabilities": [
"dev.ucp.shopping.checkout",
"dev.ucp.shopping.fulfillment"
],
"transports": ["a2a", "rest"]
}
}MPP — Machine Payments Protocol
Stripe's machine-to-machine payment protocol over HTTP 402. The agent declares its accepted payment rails (card via Stripe / Visa SPTs, stablecoins via Tempo, Lightning), the spending limit it's authorised for, and the facilitator endpoint it talks to.
You declare: merchant ID, facilitator URL, payment methods, currency, spending limit. PDLSS pre-fill: spending limit flows to autonomous and hard limits; facilitator domain + merchant:<id> added to counterparties; currency mirrored to PDLSS.
{
"protocols": ["a2a", "mpp"],
"mpp": {
"merchantId": "merchant_abc123",
"facilitatorUrl": "https://mpp.example.com",
"paymentMethods": ["card", "stablecoin"],
"currency": "USD",
"spendingLimit": 500
}
}x402 — HTTP 402 on-chain payments
Coinbase's HTTP 402 payment protocol for paying for web resources with on-chain stablecoins. Servers return 402 with payment requirements; the agent pays via a facilitator and retries with proof. Agents declare wallet, supported chains (Base, Polygon, Solana), supported tokens (USDC default), and the facilitator URL.
You declare: wallet address, supported chains, supported tokens, facilitator URL, spending limit. PDLSS pre-fill: spending limit flows to autonomous and hard limits; facilitator domain to counterparties; currency defaults to USDC if it appears in the supported-token list.
{
"protocols": ["a2a", "x402"],
"x402": {
"walletAddress": "0x1234...",
"supportedChains": ["base", "polygon"],
"supportedTokens": ["USDC", "USDT"],
"facilitatorUrl": "https://pay.coinbase.com",
"spendingLimit": 100
}
}Payment Networks — VI, Agent Pay, TAP
These protocols have two lives: a persistent declaration at registration (public keys, merchant domains, execution modes — what the agent can do) and session-based attestation tokens at runtime (SD-JWT chains, RFC 9421 signatures — proof that a specific transaction is authorised). Both halves go through the same Verification Gateway SDK.
VI — Verifiable Intent
Mastercard & Google's 3-layer SD-JWT credential chain proving human authorisation for commerce transactions. Two modes: Immediate (user confirms each action, 2-layer chain) and Autonomous (agent delegated, 3-layer chain with constraint enforcement). VI's 8 constraint types (merchant allowlists, payment amounts, budgets, recurrence, line items) map directly to PDLSS boundaries.
You declare: execution mode, agent public key (JWK/PEM), key ID, credential provider, supported mandate types, payment amount constraints, budget limits. PDLSS pre-fill: Autonomous/Both mode enables self-instantiation; payment amount max flows to autonomous and hard limits; allowed merchants become counterparties; currency mirrored.
{
"protocols": ["a2a", "vi", "agentpay"],
"vi": {
"executionMode": "Autonomous",
"kid": "key-1",
"supportedMandateTypes": ["checkout", "payment"],
"defaultConstraints": {
"paymentAmount": { "currency": "USD", "max": 10000 }
}
}
}Agent Pay — Mastercard
Mastercard's payment execution protocol using RFC 9421 HTTP Message Signatures. Agents sign every request (browse and purchase tags) using ECDSA P-256 or RSA-PSS; the Mastercard Agent Registry holds the public key for verification. Agent Pay handles the payment rail; VI handles the authorisation chain — they are complementary.
You declare:agent public key, Mastercard Agent ID, signature algorithm, allowed merchant domains, DTVC formats, consumer ID&V method, token binding scope. PDLSS pre-fill: allowed merchant domains become counterparties; always financial_transaction purpose.
{
"protocols": ["a2a", "vi", "agentpay"],
"agentpay": {
"mastercardAgentId": "mc-agent-12345",
"signatureAlgorithm": "ecdsa-p256-sha256",
"allowedMerchantDomains": ["store.example.com"],
"tokenBindingScope": "per-transaction"
}
}TAP — Visa Trusted Agent Protocol
Visa's equivalent of Agent Pay, also using RFC 9421 HTTP Message Signatures. ~85% of the infrastructure is shared with Agent Pay — the only differences are the registry endpoint (Visa's JWKS at mcp.visa.com/.well-known/jwks) and the payment credential format (Intelligent Commerce tokens vs Agentic Tokens).
You declare: agent public key, Visa Agent ID, signature algorithm, allowed merchant domains, token type (agent-specific or PAR), passkey enrollment. PDLSS pre-fill: allowed merchant domains become counterparties.
{
"protocols": ["a2a", "tap"],
"tap": {
"visaAgentId": "visa-agent-12345",
"signatureAlgorithm": "rsa-pss-sha512",
"allowedMerchantDomains": ["shop.example.com"],
"tokenType": "agent-specific-token",
"passkeyEnrolled": true
}
}Third-Party Credentials
Agents may arrive with existing credentials from external providers — a Mastercard L1 credential via VI, a DID from an AP2 Credential Provider, or a Visa agent token. AstraSync assigns an ASTRA-ID as the primary identity anchor but accepts and stores third-party credentials alongside it.
Supported formats: DID (Decentralized Identifier), Verifiable Credential (VC), SD-JWT, X.509 certificate. When an agent presents a third-party credential at runtime, the gateway resolves it to the ASTRA-ID and proceeds with normal verification.
Third-party credentials appear as an optional section in the registration form when any Payment Network protocol (VI, Agent Pay, TAP) is selected.
Session-based attestation tokens (runtime)
While agents declare their Payment Network capabilities at registration, the actual attestation tokens are short-lived and flow through the request pipeline during each transaction. They never get stored — the Verification Gateway SDK parses and validates them on every request against the agent's registered persistent metadata.
- VI SD-JWT chains— 3-layer credential chain (Credential Provider → User → Agent) with selective disclosure. Verified against the agent's registered public key and constraint templates.
- Agent Pay / TAP RFC 9421 signatures — HTTP Message Signatures on browse and purchase requests. Verified against Mastercard or Visa agent registries using the declared key ID and algorithm.
- ACP HMAC webhooks — signed webhook payloads from Stripe-backed checkout sessions.
- UCP checkout sessions — short-lived session tokens issued by a UCP merchant to authorise a single checkout flow.
Full cryptographic verification of these tokens (SD-JWT chain validation, RFC 9421 signature checking, constraint enforcement against PDLSS) ships with the Commerce Shield Lambda@Edge adapter. Today the SDK extracts and surfaces the tokens; verification is on the roadmap.
