SDK & API

Server API

Exact server, gateway and framework adapter declarations with enforcement, replay and receipt behaviour.

Alpha documentation0.6.0-alpha.1

Contract and use

Store interfaces require deployment-specific durable implementations for production use. The included in-memory stores are not distributed locks or exactly-once guarantees. Configure assertion enforcement explicitly.

Core and adapter responsibilities

APISuppliesDoes not supply
registerRoute / routeForRoute metadata and shared path/method matchingFramework registration, user permissions or an HTTP listener
verifyRequestDisabled-route check and gateway verification against supplied route/bodyBusiness validation, body-size limits or concrete resource authorization
GatewayVerifier.verifyConfigured assertion verification and expected-claim checksAutomatic trust enrolment or universal callback policy
emitReceiptResult/hash record in the configured storeIndependent proof of an external effect
idempotentSequential get/execute/put reuseAtomic concurrency exclusion, changed-input binding or crash recovery
syncAck / createSyncAckProtocol-shaped acknowledgementApplying/committing a database mutation
cappRoute from /nextVerification before a framework handler and optional response receiptHTTP router, user authentication or durable storage

Use a literal path or additionally check actual request/resource binding in your adapter. verifyRequest() receives a registered route definition, not a URL-bearing Request; do not infer concrete resource authorization from a pattern match. It does not independently enforce the full methods array when called directly—use routeFor(actualPath, method) or framework dispatch and check the result.

Assertion modes and ownership

ModeBoundary
Missing/passiveDefault enforcement is off. Decoded claims can be unverified; never use them as authenticated identity.
HMAC compatibilityRequires a backend-only secret. This path does not provide the same built-in replay claim as Ed25519 install-key verification.
Ed25519 install keyRequires an enrolled, non-revoked public key and matching identity; checks time bounds and claims a replay identity.
Custom verifyToken callbackYour callback must perform signature, time and replay policy. The SDK checks expected fields and enforced verified, but does not run the built-in verifier pipeline again.

The default built-in skew is 60 seconds and maximum Ed25519 assertion lifetime is 300 seconds. Configure deployment policy deliberately. Claims are not copied into a trusted user session just because the signature verifies. GatewayReplayStore.claim() must atomically accept one claim across the deployment; independent in-memory maps do not provide that property.

Use Headers for consistent header lookup at the boundary. Prefer the dedicated x-capp-gateway-assertion transport header rather than confusing a normal user bearer token with a cApp assertion. Do not log the signed token or private trust metadata.

Receipts and error mapping

CappPolicyError.statusCode is the TypeScript HTTP status field; Python uses status_code. The Next adapter maps policy failures to capp.policy-error.v1 before calling the handler. Other handler/storage exceptions remain application errors. Automatic receipts may buffer the returned response, so use explicit limits or application-owned receipt handling for streams and large bodies.

Do not call verification twice under one assertion: replay protection can reject the second verification. Pass the verified gateway/context into the operation and receipt. Receipt storage failure after the handler ran is a potential unknown result, not proof that repeating the handler is safe.

The declarations below are snapshots for reading. Import their named exports from the package; they are not a standalone file to paste without their referenced types.

CappRoutePolicy

ts
export type CappRoutePolicy = {
    capability: string;
    group: string;
    risk?: CappRisk;
    auth?: string;
    mode?: string;
    browserCallable?: boolean;
    receiptRequired?: boolean;
    approval?: string;
    replayProtection?: string;
    coldBehavior?: string;
    defaultEnabled?: boolean;
    online?: boolean;
    offline?: boolean;
    offlineCollection?: string | null;
    localHandler?: string | null;
    sync?: string;
    routeMode?: string;
    metadata?: Record<string, unknown>;
};

CappReceipt

ts
export type CappReceipt = {
    protocol: 'capp.receipt.v1';
    receiptId: string;
    serverId: string;
    route: string;
    method: string;
    capability: string;
    group: string;
    risk: CappRisk;
    result: string;
    createdAt: string;
    requestId?: string;
    subject?: string;
    bodySha256?: string;
    responseSha256?: string;
    gateway?: CappGatewayAssertion;
    metadata?: Record<string, unknown>;
};

ReceiptStore

ts
export interface ReceiptStore {
    put(receipt: CappReceipt): void | Promise<void>;
    get(receiptId: string): CappReceipt | undefined | Promise<CappReceipt | undefined>;
    listRecent(limit?: number): CappReceipt[] | Promise<CappReceipt[]>;
}

IdempotencyStore

ts
export interface IdempotencyStore {
    get<T = unknown>(key: string): CappIdempotencyEntry<T> | undefined | Promise<CappIdempotencyEntry<T> | undefined>;
    put<T = unknown>(entry: CappIdempotencyEntry<T>): void | Promise<void>;
}

GatewayExpected

ts
export type GatewayExpected = {
    route?: string;
    method?: string;
    capability?: string;
    audience?: string;
    appId?: string;
    siteId?: string;
    capsuleHash?: string;
    bindingId?: string;
    bodySha256?: string;
    subject?: string;
};

CappInstallTrustRecord

ts
export type CappInstallTrustRecord = {
    protocol: 'capp.gateway-trust.v1';
    keyId: string;
    installId: string;
    publicKeyJwk: JsonWebKey;
    appId?: string;
    siteId?: string;
    revoked?: boolean;
    metadata?: Record<string, unknown>;
};

GatewayTrustStore

ts
export interface GatewayTrustStore {
    get(keyId: string, installId?: string): CappInstallTrustRecord | undefined | Promise<CappInstallTrustRecord | undefined>;
}

GatewayReplayStore

ts
export interface GatewayReplayStore {
    claim(jti: string, expiresAt: number): boolean | Promise<boolean>;
}

GatewayVerifierOptions

ts
export type GatewayVerifierOptions = {
    enforce?: boolean;
    hmacSecret?: string | Uint8Array;
    verifyToken?: GatewayVerificationCallback;
    trustStore?: GatewayTrustStore;
    replayStore?: GatewayReplayStore;
    maxClockSkewSeconds?: number;
    maxAssertionLifetimeSeconds?: number;
};

CappServer

ts
export declare class CappServer {
    readonly serverId: string;
    readonly origin: string;
    readonly verifier: GatewayVerifier;
    readonly receipts: ReceiptStore;
    readonly idempotency: IdempotencyStore;
    readonly metadata: Record<string, unknown>;
    readonly gatewayExpected: Omit<GatewayExpected, 'route' | 'method' | 'capability' | 'bodySha256'>;
    constructor(options: {
        serverId: string;
        origin?: string;
        enforceGatewayAssertions?: boolean;
        gatewayHmacSecret?: string | Uint8Array;
        verifyGatewayAssertion?: GatewayVerificationCallback;
        gatewayTrustStore?: GatewayTrustStore;
        gatewayReplayStore?: GatewayReplayStore;
        gatewayMaxClockSkewSeconds?: number;
        gatewayMaxAssertionLifetimeSeconds?: number;
        gatewayAudience?: string;
        gatewayAppId?: string;
        gatewaySiteId?: string;
        gatewayCapsuleHash?: string;
        gatewayBindingId?: string;
        receiptStore?: ReceiptStore;
        idempotencyStore?: IdempotencyStore;
        metadata?: Record<string, unknown>;
    });
    idempotent<T>(key: string | undefined | null, execute: () => T | Promise<T>): Promise<{
        duplicate: boolean;
        value: T;
    }>;
    syncAck<T = unknown>(input: Omit<CappSyncAck<T>, 'protocol'>): CappSyncAck<T>;
    registerRoute(path: string, methods: string[], policy: CappRoutePolicy, kind?: string, source?: string): CappRouteDefinition;
    routeFor(path: string, method: string): CappRouteDefinition | undefined;
    verifyRequest(route: CappRouteDefinition, method: string, headers: Headers | Record<string, string>, body?: string | Uint8Array | ArrayBuffer | null): Promise<CappGatewayAssertion>;
    emitReceipt(input: {
        route: CappRouteDefinition;
        method: string;
        result: string;
        requestId?: string;
        subject?: string;
        body?: string | Uint8Array | ArrayBuffer | null;
        responseBody?: string | Uint8Array | ArrayBuffer | null;
        gateway?: CappGatewayAssertion;
        metadata?: Record<string, unknown>;
    }): Promise<CappReceipt>;
    serverContract(): Record<string, unknown>;
}

CappRouteDefinition

ts
export type CappRouteDefinition = {
    path: string;
    methods: string[];
    kind?: string;
    source?: string;
    policy: CappRoutePolicy;
};

CappGatewayAssertion

ts
export type CappGatewayAssertion = {
    protocol?: string;
    audience?: string;
    appId?: string;
    installId?: string;
    keyId?: string;
    capsuleHash?: string;
    siteId?: string;
    bindingId?: string;
    capability?: string;
    route?: string;
    method?: string;
    bodySha256?: string;
    requestId?: string;
    jti?: string;
    subject?: string;
    issuedAt?: number;
    notBefore?: number;
    expiresAt?: number;
    verified: boolean;
    verificationMode: string;
    rawClaims?: Record<string, unknown>;
};

CappIdempotencyEntry

ts
export type CappIdempotencyEntry<T = unknown> = {
    key: string;
    createdAt: string;
    value: T;
};

GatewayVerifier

ts
export declare class GatewayVerifier {
    readonly options: GatewayVerifierOptions;
    constructor(options?: GatewayVerifierOptions);
    signClaims(claims: Record<string, unknown>): Promise<string>;
    verify(token: string | undefined | null, expected?: GatewayExpected): Promise<CappGatewayAssertion>;
}

createSyncAck

ts
export declare function createSyncAck<T = unknown>(input: Omit<CappSyncAck<T>, 'protocol'>): CappSyncAck<T>;

cappRoute

ts
export declare function cappRoute(server: CappServer, path: string, methods: string[], policy: CappRoutePolicy, handler: NextHandler): NextHandler;

cappShowcaseDemo

ts
export declare function cappShowcaseDemo(snapshot: CappShowcaseDemoSnapshot | (() => CappShowcaseDemoSnapshot | Promise<CappShowcaseDemoSnapshot>)): NextHandler;

SDK overview · Build with Sidecars · Security and authority

↑ ↓ to navigate · Enter to open · Esc to close. Search stays in your browser.