@authorityrail/axap
v2.0.0
Published
AuthorityRail SDK — enforce agent authorization with CAR, ASC, and ARES Gateway support
Downloads
1,673
Maintainers
Readme
@authorityrail/axap
AuthorityRail SDK v2 — enforce agent authorization in any TypeScript or JavaScript stack.
Probability is not permission. Authority is required.
Every action an AI agent takes produces a Certified Action Record (CAR) — a cryptographically-signed, immutable audit receipt stored in your AuthorityRail ledger. This SDK is the developer interface to that system.
Installation
npm install @authorityrail/axapRequires Node.js 18+ and TypeScript 5+ (optional but recommended).
10-Minute Quickstart
1. Create a client
import { createClient } from '@authorityrail/axap';
const ar = createClient({
gateUrl: 'https://authorityrail-production-5b04.up.railway.app',
agentId: 'urn:ar:agent:my-agent',
orgId: 'acme-corp',
// apiKey: process.env.AR_API_KEY, // optional
});2. Authorize an action
const result = await ar.authorize({
action: 'transfer_funds',
risk_score: 0.8,
domain: 'payments',
payload: { amount: 5000, to: 'acct_xyz' },
});
if (result.decision === 'ALLOW') {
console.log('Authorized. CAR ID:', result.car_id);
await executeTransfer();
} else if (result.decision === 'DENY') {
throw new Error(`Denied: ${result.reasoning}`);
}3. One-liner with withAuthority
const { output, authorityRail } = await ar.withAuthority(
{ action: 'delete_record', risk_score: 0.9 },
async () => {
const output = await db.records.delete(id);
return { output };
}
);
// Throws AXAPDeniedError on DENY, AXAPEscalateError on ESCALATECore Concepts
| Concept | Description |
|---------|-------------|
| CAR | Certified Action Record — immutable audit receipt for every decision |
| ASC | Authority Scope Certificate — scoped permission grant for an agent |
| ARES Gateway | MCP proxy that intercepts tool calls and enforces AuthorityRail decisions |
| Decision | ALLOW / DENY / BLOCK / ESCALATE |
API Reference
createClient(config) → AuthorityRail
Factory function. Preferred over new AuthorityRail().
interface AuthorityRailConfig {
gateUrl: string; // AuthorityRail gate URL
agentId: string; // urn:ar:agent:<name> recommended
orgId: string; // organization identifier
apiKey?: string; // API key for authenticated requests
timeout?: number; // request timeout ms (default: 5000)
headers?: Record<string, string>;
signingKey?: string; // HMAC key for CAR verification (env AR_SIGNING_KEY)
ascCacheTtl?: number; // ASC cache TTL ms (default: 300_000)
aresGatewayUrl?: string; // ARES Gateway URL (falls back to gateUrl)
}ar.authorize(opts) → AuthorizeResult
Request authorization for an action. Always returns a decision — never silently allows.
const result = await ar.authorize({
action: 'initiate_payment', // required
risk_score: 0.75, // 0–1 (default: 0.5)
domain: 'payments',
payload: { amount: 1000 },
model_version: 'gpt-5',
parent_car_id: 'car_parent_001', // for delegation chains
financial_value: 1000, // USD, for risk weighting
});
// result: { decision, car_id, car_signature, reasoning, latency_ms, approval_id? }ar.withAuthority(opts, fn) → T & { authorityRail }
Authorize and execute in one step. Throws on DENY/ESCALATE — never executes fn unless ALLOW.
const result = await ar.withAuthority(
{ action: 'send_email', risk_score: 0.3 },
async () => sendEmail(payload)
);
// result.authorityRail.car_id — audit receiptar.verifyCAR(carId, signingKey?) → CARVerificationResult
Fetch a CAR from the gate and confirm it is valid. Optionally verifies the HMAC signature locally.
const check = await ar.verifyCAR('car_abc123');
// { valid, car_id, agent_id, action, decision, verified_at }
// With local HMAC verification:
const check = await ar.verifyCAR('car_abc123', process.env.AR_SIGNING_KEY);
// check.signature_valid — true/falseStandalone function:
import { verifyCAR } from '@authorityrail/axap';
const check = await verifyCAR('car_abc123', {
gateUrl: 'https://authorityrail-production-5b04.up.railway.app',
signingKey: process.env.AR_SIGNING_KEY,
});ar.fetchASC(certId?) → ASC
Fetch the active Authority Scope Certificate for this client's agent. Results are cached.
const asc = await ar.fetchASC();
// asc.authority_scope — ['data:read', 'payments:write']
// asc.action_patterns — ['read_*', 'transfer_funds']
// asc.max_risk_ceiling — 0.8
// asc.expires_at — ISO timestampStandalone function:
import { fetchASC, validateASC, ascCoversAction } from '@authorityrail/axap';
const asc = await fetchASC('urn:ar:agent:my-agent', {
gateUrl: 'https://authorityrail-production-5b04.up.railway.app',
cacheTtl: 600_000, // 10 min
});
const valid = validateASC(asc);
const covered = ascCoversAction(asc, 'transfer_funds');ARES Gateway (MCP tool call enforcement)
// Low-level: authorize a tool call
const decision = await ar.aresAuthorize({
tool: 'write_database',
arguments: { table: 'users', data: { ... } },
domain: 'data',
});
// One-liner: authorize and execute
const result = await ar.aresCall(
{ tool: 'read_config', arguments: { key: 'feature_flags' } },
async () => getConfig('feature_flags')
);
// result._ar.decision, result._ar.car_id
// Standalone client:
import { AresClient } from '@authorityrail/axap';
const ares = new AresClient({ gateUrl, agentId, failOpen: false });Express Middleware
import { axapMiddleware } from '@authorityrail/axap/middleware/express';
app.use(axapMiddleware({
gateUrl: process.env.AUTHORITYRAIL_URL,
agentId: 'urn:ar:agent:my-service',
orgId: 'acme',
actionClassMap: {
'POST /payments': 'initiate_payment',
'DELETE /*': 'delete_resource',
'GET /*': 'read_data',
},
onDeny: (req, res, ctx) => {
res.status(403).json({ error: 'Denied', car_id: ctx.car_id });
},
onAllow: (req, ctx) => {
logger.info('authorized', { car_id: ctx.car_id, action: ctx.action });
},
}));
// req.authorityRail — { decision, car_id, latency_ms, action }CAR Signature Verification (offline)
import { verifyCARSignatureLocal, computeCARSignature, carCanonicalString } from '@authorityrail/axap';
// Verify a locally-held CAR without a network call
const valid = verifyCARSignatureLocal(car, process.env.AR_SIGNING_KEY);
// Compute expected signature
const sig = computeCARSignature(car, process.env.AR_SIGNING_KEY);
// Inspect canonical string
const canonical = carCanonicalString(car);
// "car_abc123|urn:ar:agent:test|transfer_funds|ALLOW"Error Handling
All errors are explicit and typed. The SDK never silently allows execution on error.
import {
AXAPError, // base class
AXAPDeniedError, // decision is DENY or BLOCK
AXAPEscalateError, // decision is ESCALATE (approvalId attached)
AXAPTimeoutError, // request timed out
AXAPCertError, // ASC missing, expired, or revoked
AXAPSignatureError, // CAR signature verification failed
} from '@authorityrail/axap';
try {
await ar.withAuthority({ action: 'send_wire_transfer' }, fn);
} catch (err) {
if (err instanceof AXAPDeniedError) {
console.error('Denied:', err.reasoning, 'CAR:', err.carId);
} else if (err instanceof AXAPEscalateError) {
console.log('Awaiting approval:', err.approvalId);
} else if (err instanceof AXAPTimeoutError) {
console.error('Gate timeout — action blocked');
} else {
throw err;
}
}CLI
# After installing globally: npm install -g @authorityrail/axap
axap authorize \
--agent urn:ar:agent:demo \
--org acme-corp \
--action transfer_funds \
--risk 80 \
--gateway https://authorityrail-production-5b04.up.railway.app
axap verify --car car_abc123 --gateway https://authorityrail-production-5b04.up.railway.app
axap asc --agent urn:ar:agent:demo --gateway https://authorityrail-production-5b04.up.railway.app
axap statusEnvironment variables:
AUTHORITYRAIL_URL— gate URLAXAP_AGENT— agent IDAXAP_ORG— org IDAR_SIGNING_KEY— HMAC signing key for CAR verification
TypeScript
Full type definitions are included. Key types:
import type {
Decision, // 'ALLOW' | 'DENY' | 'BLOCK' | 'ESCALATE'
CAR, // Certified Action Record
ASC, // Authority Scope Certificate
AuthorizeOptions,
AuthorizeResult,
AresCallOptions,
AresDecision,
AuthorityRailConfig,
CARVerificationResult,
ASCValidationResult,
} from '@authorityrail/axap';License
MIT — AuthorityRail-ai/authorityrail
