npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cnothing

v0.1.4

Published

CNothing AuthAI + Encrypted KV server and SDK for AI-safe secret workflows

Readme

CNothing

For Chinese documentation, see README.CN.MD.

CNothing is a production-oriented AuthAI + Encrypted KV service for AI automation systems that need to use secrets without exposing plaintext to the model.

It is designed for a specific problem: an AI agent needs to help orchestrate work, choose tools, and route requests, but the sensitive values used by that workflow must stay inside a trusted backend boundary. CNothing gives you a way to let the AI participate in the flow while keeping private keys and decrypted secrets out of the model.

Why CNothing

CNothing is valuable when you want all of the following at the same time:

  • The AI can coordinate a workflow that depends on secrets
  • The AI never sees secret plaintext
  • The client backend remains the trust boundary because it holds the private key
  • Secret reads and writes can still be standardized through HTTP, MCP, and Skill interfaces
  • Stored data remains encrypted at rest with per-record envelope encryption

In practice, CNothing sits between an AI-facing orchestration layer and a backend that is allowed to handle cryptographic material. The model can discover available capabilities, forward ciphertext envelopes, and work with non-sensitive routing metadata, while the backend performs decryption and signing-sensitive operations.

GitHub repository:

When To Use It

CNothing is a strong fit when:

  • You are building AI agents or copilots that need to trigger authenticated integrations
  • You want AI to drive flow control, but not directly hold API tokens, access tokens, or user secrets
  • You need a reusable secret-access protocol instead of one custom backend adapter per tool
  • You want both human operators and AI systems to browse capabilities through a shared control plane

CNothing is probably not the right primary abstraction when:

  • AI is not involved in the workflow at all
  • Your backend can talk directly to upstream systems without any AI-facing layer
  • A standard secrets manager alone already solves your problem because you do not need challenge-based client authentication or encrypted envelope forwarding

Core Model

CNothing is built around a few simple roles:

  • CNothing
    • Holds the AuthAI private key, validates challenge usage, and stores encrypted KV records
  • Client backend
    • Holds the client private key and acts as the trusted cryptographic boundary
  • AI
    • Orchestrates the workflow, calls HTTP or MCP APIs, and forwards ciphertext envelopes without decrypting them

That split is the main value proposition: the AI is operationally useful, but cryptographically blind.

End-To-End Flow

The shortest mental model for CNothing is:

  1. The client registers a public key with CNothing.
  2. CNothing returns a one-time challenge encrypted to that client public key.
  3. The client backend decrypts the challenge locally.
  4. The client backend creates an auth_envelope plus either a data_envelope or query_envelope, then encrypts them to CNothing.
  5. The AI forwards those ciphertext envelopes to CNothing using HTTP or MCP.
  6. CNothing validates the challenge, performs the read or write, and returns the next challenge.
  7. For reads, the result is encrypted back to the client public key so only the client backend can decrypt it.

This means:

  • The AI never receives plaintext secrets
  • The AI never needs a private key
  • Challenge replay is limited because challenges are single-use and short-lived

For deeper protocol details, see:

Main Endpoints

  • GET /v1/authai/public-key
    • Return the CNothing AuthAI public key metadata
  • POST /v1/authai/register
    • Register or reuse a client public key and return an encrypted one-time challenge
  • POST /v1/authai/refresh
    • Issue the next challenge using a valid auth envelope
  • POST /v1/authai/rotate-key
    • Rotate the client public key while keeping the same client_uuid
  • POST /v1/kv/save
    • Save KV items using auth_envelope + data_envelope
  • POST /v1/kv/read
    • Read KV items using auth_envelope + query_envelope, then return the result encrypted to the client public key

Console And Browse APIs

This repository also includes a standalone CNothing Console:

  • console/
    • A Next.js console for browsing MCP tools and resources, skills, clients, namespaces, key names, and decrypted values through backend APIs

Browsable APIs:

  • GET /v1/catalog/mcp
    • List MCP tools and resources
  • GET /v1/catalog/skills
    • List bundled skills in the repository

Admin APIs:

  • GET /v1/admin/clients
    • List registered clients
  • POST /v1/admin/clients/register
    • Manually register a client by pasting a public key
  • GET /v1/admin/clients/:client_uuid/namespaces
    • List namespaces under a client
  • GET /v1/admin/clients/:client_uuid/kv?namespace=...
    • List key names under a namespace
  • GET /v1/admin/clients/:client_uuid/kv/value?namespace=...&key=...
    • View a decrypted value
  • POST /v1/admin/clients/:client_uuid/kv/save
    • Manually write JSON values through the admin API

Notes:

  • The catalog APIs are public by default and are suitable for discovery
  • The admin APIs reuse KEYSERVICE_BEARER_TOKEN for Bearer authentication
  • If KEYSERVICE_BEARER_TOKEN is unset, the console and admin APIs do not add extra blocking

Third-Party Server SDK

This repository now also includes a reusable Node.js and Bun SDK so third-party backends can integrate with https://cnothing.com without reimplementing the protocol by hand.

Install it from npm:

npm install cnothing

or:

bun add cnothing

The SDK is designed for backend use. A third-party service can:

  • Generate or load its own client key pair
  • Register its public key with CNothing
  • Keep its private key local
  • Save and read encrypted KV values through https://cnothing.com
  • Let AI use the CNothing protocol without ever seeing plaintext secrets

For third-party production use against https://cnothing.com, the most privacy-preserving path is to use the structure-protected methods:

  • saveBlindJson()
  • readBlindJson()

These methods protect namespace, key, metadata, and value on the third-party backend before anything is sent to CNothing.

If you only need to hide the value plaintext but are comfortable exposing namespace and key names to the service, you can use:

  • savePrivateJson()
  • readPrivateJson()

Those methods only add a second encryption layer for the value itself.

Minimal example:

import { CNothingClient, generateClientKeyPair } from "cnothing";

const { privateKeyPem, publicKeyPem } = generateClientKeyPair();

const client = new CNothingClient({
  baseUrl: "https://cnothing.com",
  clientPrivateKeyPem: privateKeyPem,
  clientPublicKeyPem: publicKeyPem,
  clientLabel: "third-party-service",
  privacyKey: process.env.CNOTHING_PRIVACY_KEY!,
});

await client.register();

await client.saveBlindJson({
  namespace: "thirdparty.example.production",
  items: [
    {
      key: "provider/openai/api-key",
      value: { apiKey: "sk-..." },
      metadata: { provider: "openai" },
    },
  ],
});

const readResult = await client.readBlindJson({
  namespace: "thirdparty.example.production",
  keys: ["provider/openai/api-key"],
});

console.log(readResult.items["provider/openai/api-key"]);

The SDK exports:

  • CNothingClient
    • High-level register / refresh / save / read workflow client
  • generateClientKeyPair()
    • Generate a local RSA key pair for development or first-time setup
  • rotateKey()
    • Rotate to a new client key pair while preserving the same CNothing client identity
  • Envelope helpers
    • For teams that want lower-level control over how requests are built

Reference examples:

Why Third-Party Users Do Not Need To Fear AI Leaking Their Secrets

When a third-party backend uses https://cnothing.com correctly, the AI still does not gain access to the third-party's sensitive plaintext values.

That is because:

  • The third-party backend keeps the client private key locally
  • CNothing encrypts challenges to the third-party public key
  • The backend decrypts those challenges locally and creates ciphertext envelopes for CNothing
  • In the recommended SDK flow, the backend also protects namespace and key names with a deterministic privacy mapping
  • The backend seals metadata and value plaintext before they are ever handed to CNothing
  • AI only forwards ciphertext envelopes and non-sensitive metadata
  • Read results are encrypted back to the third-party public key, and the inner value stays client-sealed, so only that backend can decrypt it

In other words, the AI may participate in orchestration, but it does not become the holder of third-party plaintext secrets. In the recommended blind mode, the CNothing service operator also does not receive the third-party plaintext value, plaintext metadata, or original namespace and key names.

The operator can still observe high-level access patterns such as request timing, client identity, and the existence of stable protected identifiers. This is operator-blind for payload and structure content, not an attempt at traffic-analysis resistance.

Key Rotation

CNothing now supports rotating a client public key without changing the client_uuid.

The intended flow is:

  1. The client authenticates with the current key using a valid auth_envelope.
  2. The client submits a new public key to POST /v1/authai/rotate-key.
  3. CNothing updates the existing client record in place.
  4. Existing active challenges for that client are invalidated.
  5. CNothing returns the next challenge encrypted to the new public key.
  6. The client continues using the same client_uuid, namespaces, and stored records.

From the SDK, the high-level method is:

const nextKeys = generateClientKeyPair();

await client.rotateKey({
  newClientPrivateKeyPem: nextKeys.privateKeyPem,
  newClientPublicKeyPem: nextKeys.publicKeyPem,
  newClientKeyId: "rotation-2026-04",
});

Security Properties

  • Clients only submit public keys during registration
  • challenge_for_client is always encrypted to the client public key
  • auth_envelope and data/query_envelope are always encrypted to CNothing
  • Challenges are single-use and short-lived
  • Server-side records use per-record random DEKs wrapped by the master key

Important constraints:

  • AI should never request private keys
  • AI should never decrypt envelopes
  • AI should only forward ciphertext envelopes and non-sensitive metadata
  • If key names are sensitive, the caller backend should add a mapping or hashing layer

Quick Start

1. Prepare infrastructure

You need:

  • Bun
  • PostgreSQL
  • A .env file with the required CNothing settings

Required environment variables:

  • DATABASE_URL
  • KEYSERVICE_MASTER_KEY
  • KEYSERVICE_AUTHAI_PRIVATE_KEY_PATH
  • KEYSERVICE_AUTHAI_PUBLIC_KEY_PATH (optional if derived from the private key)

Optional but commonly useful:

  • PORT
  • KEYSERVICE_CHALLENGE_TTL_SECONDS
  • KEYSERVICE_BEARER_TOKEN
  • KEYSERVICE_CONSOLE_URL

2. Generate local secrets for development

cd CNothing
bun install
bun run generate-secrets

This creates:

  • .local-keys/authai-private-key.pem
  • .local-keys/authai-public-key.pem
  • .local-keys/generated.env

That explicit initialization step is intentional: service identity does not silently change on restart, and key rotation remains operationally visible.

If you are integrating from a separate third-party backend instead of deploying CNothing itself, install the SDK there and point it at https://cnothing.com:

import { CNothingClient } from "cnothing";

const client = new CNothingClient({
  baseUrl: "https://cnothing.com",
  clientPrivateKeyPem: process.env.CNOTHING_CLIENT_PRIVATE_KEY_PEM!,
  clientPublicKeyPem: process.env.CNOTHING_CLIENT_PUBLIC_KEY_PEM!,
  clientLabel: "my-service",
  privacyKey: process.env.CNOTHING_PRIVACY_KEY!,
});

await client.register();
await client.saveBlindJson({
  namespace: "my.service.production",
  items: [{ key: "secret/example", value: { token: "..." }, metadata: { kind: "token" } }],
});

3. Configure the environment

Create a .env file and set at least:

DATABASE_URL=postgresql://user:[email protected]:5432/cnothing
KEYSERVICE_MASTER_KEY=...
KEYSERVICE_AUTHAI_PRIVATE_KEY_PATH=./.local-keys/authai-private-key.pem
KEYSERVICE_AUTHAI_PUBLIC_KEY_PATH=./.local-keys/authai-public-key.pem
PORT=3021

4. Run migrations and start the API

cd CNothing
bun run migrate
bun run dev

5. Start the console

cd CNothing/console
bun install
bun run dev

Or from the repository root:

cd CNothing
bun run console:dev

6. Verify the deployment

Once the service is running, verify:

  • GET /health
  • GET /v1/authai/public-key
  • GET /mcp
  • GET /skill.md

On a default local setup, that usually means:

curl http://127.0.0.1:3021/health
curl http://127.0.0.1:3021/v1/authai/public-key
curl http://127.0.0.1:3021/mcp

Deployment Notes

CNothing works well as an independently published and deployed repository. For a public repository:

  • Keep .env.example
  • Do not commit .env
  • Do not commit .local-keys/
  • Provide production secrets through environment variables or a separate secrets directory
  • Keep production private keys outside paths that may be overwritten by code sync

This repository already includes deployment helpers under deploy/.

File Guide