npm package: @rubric-protocol/sdk
Description: Rubric Protocol SDK — post-quantum AI attestation with ZK inclusion proofs
Latest version: 1.1.1

# @rubric-protocol/sdk

Post-quantum AI attestation with ZK inclusion proofs.

Rubric Protocol is the independent witness layer for the AI economy - providing tamper-evident, independently verifiable audit trails for AI decisions, anchored to Hedera Consensus Service.


## ⚠️ Critical: /v1/attest vs /v1/tiered-attest

| Endpoint | Tier Required | Behavior | Cost |
|----------|--------------|----------|------|
| `/v1/attest` | **Enterprise only** | Writes directly to Hedera Consensus Service | HBAR per call |
| `/v1/tiered-attest` | Developer+ | Merkle batching (1,000,000:1 compression) | Minimal |

**Use `/v1/tiered-attest` for all development and high-volume workloads.**
`/v1/attest` is a direct HCS write. Unguarded use drained 1,000 HBAR in 12 hours.
Hard rate limit: 60 req/min. If you are unsure which to use: use `/v1/tiered-attest`.

## Installation

    npm install @rubric-protocol/sdk

## Quick Start

    import { RubricClient } from "@rubric-protocol/sdk";
    const client = new RubricClient({
      baseUrl: "https://rubric-protocol.com/verify",
      apiKey: "your-api-key",
    });

Get an API key at https://rubric-protocol.com

## Core Concepts

Every AI decision submitted to Rubric receives:

1. An attestation record - signed with ML-DSA-65 (NIST FIPS 204 post-quantum signature)
2. A Merkle inclusion - aggregated into a cryptographic tree and anchored to Hedera Consensus Service
3. A ZK inclusion proof - independently verifiable proof your record was included in the anchored tree

The ZK proof means you hold cryptographic evidence of your record that does not require Rubric to verify.

## Submitting Attestations

    const result = await client.attestations.tieredAttest({
      data: { model: "gpt-4o", decision: "approved", confidence: 0.94 },
      sourceId: "your-system-id",
      pipelineId: "my-pipeline",
    });
    console.log(result.attestationId); // retain this
    console.log(result.status);        // buffered

## Retrieving ZK Inclusion Proofs

The proof generates asynchronously after the ~30s Merkle flush. Use the built-in polling helper:

    const proof = await client.attestations.getZkProof(result.attestationId, {
      timeoutMs: 120_000,  // default 120s
      intervalMs: 10_000,  // default 10s
    });
    console.log(proof.status);           // ready
    console.log(proof.proof.zkRoot);     // Poseidon2 Merkle root
    console.log(proof.proof.zkPath);     // 20-level inclusion path
    console.log(proof.proof.zkLeaf);     // your record leaf hash
    console.log(proof.hcsSeqNum);        // HCS sequence number
    console.log(proof.verifyEndpoint);   // endpoint to verify this proof

HTTP status codes: 202 = pending (retry), 200 = ready, 404 = not found

## ZK Proof Response Fields

  status          ready or pending
  attestationId   your record ID
  flushId         Merkle batch ID
  hcsSeqNum       HCS sequence number (populated ~60s after submission)
  hcsExplorerUrl  Hashscan link for on-chain verification
  proof.zkLeaf    BN254 field element - your record leaf hash
  proof.zkRoot    Poseidon2 Merkle root - matches HCS anchor
  proof.zkPath    20-element sibling path
  proof.zkIndices left/right indices per level
  proof.leafIndex your position in the Merkle tree
  circuitVersion  noir-beta19-poseidon2-depth20

## Full Example

    import { RubricClient } from "@rubric-protocol/sdk";
    const client = new RubricClient({
      baseUrl: "https://rubric-protocol.com/verify",
      apiKey: process.env.RUBRIC_API_KEY,
    });
    const attest = await client.attestations.tieredAttest({
      data: { model: "claude-3-5-sonnet", action: "content_moderation", result: "approved" },
      sourceId: "my-ai-system",
    });
    const proof = await client.attestations.getZkProof(attest.attestationId);
    console.log("zkRoot:   ", proof.proof.zkRoot);
    console.log("leafIndex:", proof.proof.leafIndex);
    console.log("hcsSeqNum:", proof.hcsSeqNum ?? "pending");

## Payload Privacy — Storing Your payloadKey

Every tieredAttest response includes a payloadKey. This is the only time it is ever returned — Rubric does not store it.

You must store it. If it is lost, the encrypted payload is unrecoverable.

Recommended storage patterns:

- Secrets manager (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager) — index by attestationId
- Encrypted database column — store alongside your own record of the decision
- Customer-side KMS — if you operate your own key management system

Never log the payloadKey. Never transmit it over unencrypted channels. Never store it in the same system as the attestation record — the separation is what gives the privacy guarantee its strength.

The payloadCommitment (also in the response) is safe to store anywhere. It is a public binding between the key and the attestation, containing no secret information.

Example:

    const result = await client.attestations.tieredAttest({ data: decision, sourceId: ' + chr(39) + 'my-system' + chr(39) + ' });
    await mySecretsManager.store(' + chr(39) + 'rubric:key:' + chr(39) + ' + result.attestationId, result.payloadKey);

## EU AI Act Article 12 Compliance

Rubric satisfies the tamper-evident logging requirements of EU AI Act Article 12 for high-risk AI systems.

- Timestamp independence: consensus timestamps generated by Hedera network, not Rubric
- Structural immutability: HCS has no DELETE or UPDATE operation by design
- Third-party verifiability: records verifiable against Hedera public mirror nodes without Rubric
- Post-quantum integrity: ML-DSA-65 signatures valid against quantum adversaries
- ZK inclusion proofs: customers hold independent cryptographic evidence of inclusion

## Framework Integrations

    pip install autogen-rubric

Supports AutoGen, LlamaIndex, CrewAI, LangGraph, OpenAI Agents SDK, Google ADK, and more.

## Support

Website: https://rubric-protocol.com
Email: scott@rubric-protocol.com

Built by Echelon Intelligence Group.