Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/remove-secrets-leftovers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@cipherstash/stack": patch
"stash": patch
---

Remove the leftovers from the secrets removal (`1929c8fe`), which deleted
`packages/stack/src/secrets/` but left its export, build entry, skill, and docs
behind. Secrets tooling is not ready; nothing here was functional.

- **Drop the dead `@cipherstash/stack/secrets` subpath export.** It pointed at
`./dist/secrets/index.js`, which has no source and is not in the tarball, so
`import '@cipherstash/stack/secrets'` has been throwing `ERR_MODULE_NOT_FOUND`
for every consumer since the source was removed. Also drops the dangling
`src/secrets/index.ts` entry from `tsup.config.ts`. Removing an export that
cannot resolve breaks nothing.
- **Remove the `stash-secrets` agent skill** and its references in `AGENTS.md`
and the init setup-prompt skill index. It was never installed by `stash init`
(it is absent from `SKILL_MAP`), so no user project ever received it.
- **Remove the secrets documentation** from both published READMEs: the
`Secrets` class API and the `npx stash secrets` command reference in
`@cipherstash/stack`, and the `npx stash secrets` section in `stash`. The CLI
command does not exist — `stash secrets` returns `Unknown command`.
7 changes: 3 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ If these variables are missing, tests that require live encryption will fail or
## Repository Layout

- `packages/stack`: Main package (`@cipherstash/stack`) containing the encryption client and all integrations
- Subpath exports: `@cipherstash/stack`, `@cipherstash/stack/client`, `@cipherstash/stack/identity`, `@cipherstash/stack/secrets`, `@cipherstash/stack/schema`, `@cipherstash/stack/types`, `@cipherstash/stack/drizzle`, `@cipherstash/stack/dynamodb`, `@cipherstash/stack/supabase`, `@cipherstash/stack/encryption`, `@cipherstash/stack/errors`, `@cipherstash/stack/wasm-inline`
- Subpath exports: `@cipherstash/stack`, `@cipherstash/stack/client`, `@cipherstash/stack/identity`, `@cipherstash/stack/schema`, `@cipherstash/stack/types`, `@cipherstash/stack/drizzle`, `@cipherstash/stack/dynamodb`, `@cipherstash/stack/supabase`, `@cipherstash/stack/encryption`, `@cipherstash/stack/errors`, `@cipherstash/stack/wasm-inline`
- `packages/protect`: Core encryption library (internal, re-exported via `@cipherstash/stack`)
- `src/index.ts`: Public API (`Encryption`, exports)
- `src/ffi/index.ts`: `EncryptionClient` implementation, bridges to `@cipherstash/protect-ffi`
- `src/ffi/operations/*`: Encrypt/decrypt/model/bulk/query operations (thenable pattern with optional `.withLockContext()`)
- `__tests__/*`: End-to-end and API contract tests (Vitest)
- `packages/cli`: The `stash` CLI — auth, init, encryption schema, database setup (`stash eql install`), and secrets. Has its own `AGENTS.md`.
- `packages/cli`: The `stash` CLI — auth, init, encryption schema, and database setup (`stash eql install`). Has its own `AGENTS.md`.
- `packages/wizard`: AI-powered encryption setup (`@cipherstash/wizard`)
- `packages/migrate`: Plaintext-to-encrypted column migration (`@cipherstash/migrate`) — resumable backfill, per-column state
- `packages/prisma-next`: Prisma Next integration (`@cipherstash/prisma-next`) — searchable field-level encryption for Postgres
Expand All @@ -91,7 +91,7 @@ If these variables are missing, tests that require live encryption will fail or
- `e2e/*`: Cross-package end-to-end tests (package managers, supply chain, Prisma example README)
- `examples/*`: Working apps (basic, prisma, supabase-worker)
- `docs/plans/*`: Internal design plans. User-facing documentation lives at https://cipherstash.com/docs (not in this repo).
- `skills/*`: Agent skills (`stash-cli`, `stash-encryption`, `stash-drizzle`, `stash-dynamodb`, `stash-secrets`, `stash-supabase`, `stash-supply-chain-security`)
- `skills/*`: Agent skills (`stash-cli`, `stash-encryption`, `stash-drizzle`, `stash-dynamodb`, `stash-supabase`, `stash-supply-chain-security`)

## Supply Chain Security

Expand Down Expand Up @@ -120,7 +120,6 @@ Three rules to remember when editing CI or pnpm config:
- **Drizzle ORM**: `encryptedType`, `extractEncryptionSchema`, `createEncryptionOperators` from `@cipherstash/stack/drizzle`
- **Supabase**: `encryptedSupabase` from `@cipherstash/stack/supabase`
- **DynamoDB**: `encryptedDynamoDB` from `@cipherstash/stack/dynamodb`
- **Secrets management**: `Secrets` class from `@cipherstash/stack/secrets` for encrypted secret storage and retrieval.

## Critical Gotchas (read before coding)

Expand Down
39 changes: 1 addition & 38 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![npm version](https://img.shields.io/npm/v/stash.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/stash)
[![License: MIT](https://img.shields.io/npm/l/stash.svg?style=for-the-badge&labelColor=000000)](https://github.com/cipherstash/stack/blob/main/LICENSE.md)

The single CLI for CipherStash. It handles authentication, project initialization, EQL database lifecycle (install, upgrade, validate, push, migrate), schema building, and encrypted secrets management. Install it as a devDependency alongside the runtime SDK `@cipherstash/stack`.
The single CLI for CipherStash. It handles authentication, project initialization, EQL database lifecycle (install, upgrade, validate, push, migrate), and schema building. Install it as a devDependency alongside the runtime SDK `@cipherstash/stack`.

---

Expand Down Expand Up @@ -169,43 +169,6 @@ Any flags after `wizard` are forwarded verbatim to the wizard package. On the fi

---

### `npx stash secrets`

Manage end-to-end encrypted secrets.

```bash
npx stash secrets <subcommand> [options]
```

| Subcommand | Description |
|------------|-------------|
| `set` | Store an encrypted secret |
| `get` | Retrieve and decrypt a secret |
| `get-many` | Retrieve and decrypt multiple secrets (2–100) |
| `list` | List all secrets in an environment |
| `delete` | Delete a secret |

**Flags:**

| Flag | Alias | Description |
|------|-------|-------------|
| `--name` | `-n` | Secret name (comma-separated for `get-many`) |
| `--value` | `-V` | Secret value (`set` only) |
| `--environment` | `-e` | Environment name |
| `--yes` | `-y` | Skip confirmation (`delete` only) |

**Examples:**

```bash
npx stash secrets set -n DATABASE_URL -V "postgres://..." -e production
npx stash secrets get -n DATABASE_URL -e production
npx stash secrets get-many -n DATABASE_URL,API_KEY -e production
npx stash secrets list -e production
npx stash secrets delete -n DATABASE_URL -e production -y
```

---

### `npx stash eql install`

Configure your database and install CipherStash EQL extensions in a single command. Run this after `npx stash init`. (`npx stash db install` is a deprecated alias — it still works but prints a warning.)
Expand Down
2 changes: 0 additions & 2 deletions packages/cli/src/commands/init/lib/setup-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ const SKILL_PURPOSES: Record<string, string> = {
'DynamoDB encryption: per-item encrypt/decrypt, HMAC attribute keys, audit logging',
'stash-cli':
'`stash` command reference — `status`, `plan`, `impl`, `eql install`, `encrypt {backfill,cutover,drop}`, etc.',
'stash-secrets':
'storing and retrieving encrypted secrets (separate concern from column encryption)',
'stash-supply-chain-security':
'supply-chain controls (post-install policy, lockfile integrity, etc.)',
}
Expand Down
77 changes: 2 additions & 75 deletions packages/stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ The all-in-one TypeScript SDK for the CipherStash data security stack.
- [Encryption and Decryption](#encryption-and-decryption)
- [Searchable Encryption](#searchable-encryption)
- [Identity-Aware Encryption](#identity-aware-encryption)
- [Secrets Management](#secrets-management)
- [CLI Reference](#cli-reference)
- [Configuration](#configuration)
- [Error Handling](#error-handling)
Expand Down Expand Up @@ -94,8 +93,7 @@ if (decrypted.failure) {
- **Searchable encryption** - Exact match, free-text search, order/range queries, and encrypted JSONB queries in PostgreSQL.
- **Bulk operations** - Encrypt or decrypt thousands of values in a single ZeroKMS call (`bulkEncrypt`, `bulkDecrypt`, `bulkEncryptModels`, `bulkDecryptModels`).
- **Identity-aware encryption** - Tie encryption to a user's JWT via `LockContext`, so only that user can decrypt.
- **Secrets management** - Store, retrieve, list, and delete encrypted secrets with the `Secrets` class.
- **CLI (`stash`)** - Initialize projects, manage secrets, and set up encryption from the terminal.
- **CLI (`stash`)** - Initialize projects and set up encryption from the terminal.
- **TypeScript-first** - Strongly typed schemas, results, and model operations with full generics support.

## Schema Definition
Expand Down Expand Up @@ -398,44 +396,6 @@ const decrypted = await client

Lock contexts work with all operations: `encrypt`, `decrypt`, `encryptModel`, `decryptModel`, `bulkEncryptModels`, `bulkDecryptModels`, `bulkEncrypt`, `bulkDecrypt`.

## Secrets Management

The `Secrets` class provides end-to-end encrypted secret storage. Values are encrypted locally before being sent to the CipherStash API.

```typescript
import { Secrets } from "@cipherstash/stack/secrets"

const secrets = new Secrets({
workspaceCRN: process.env.CS_WORKSPACE_CRN!,
clientId: process.env.CS_CLIENT_ID!,
clientKey: process.env.CS_CLIENT_KEY!,
apiKey: process.env.CS_CLIENT_ACCESS_KEY!,
environment: "production",
})

// Store a secret
await secrets.set("DATABASE_URL", "postgres://user:pass@host:5432/db")

// Retrieve and decrypt a single secret
const result = await secrets.get("DATABASE_URL")
if (!result.failure) {
console.log(result.data) // "postgres://user:pass@host:5432/db"
}

// Retrieve multiple secrets in one call
const many = await secrets.getMany(["DATABASE_URL", "API_KEY"])
if (!many.failure) {
console.log(many.data.DATABASE_URL)
console.log(many.data.API_KEY)
}

// List secret names (values stay encrypted)
const list = await secrets.list()

// Delete a secret
await secrets.delete("DATABASE_URL")
```

## CLI Reference

The CLI is available via `npx stash` after install.
Expand Down Expand Up @@ -472,24 +432,6 @@ After init, run `npx stash db setup` to configure your database.
|------|-------------|
| `--supabase` | Use Supabase-specific setup flow |

### `npx stash secrets`

Manage encrypted secrets from the terminal.

```bash
npx stash secrets set -name DATABASE_URL -value "postgres://..." -environment production
npx stash secrets get -name DATABASE_URL -environment production
npx stash secrets list -environment production
npx stash secrets delete -name DATABASE_URL -environment production
```

| Command | Flags | Aliases | Description |
|-----|----|-----|-------|
| `npx stash secrets set` | `-name`, `-value`, `-environment` | `-n`, `-V`, `-e` | Encrypt and store a secret |
| `npx stash secrets get` | `-name`, `-environment` | `-n`, `-e` | Retrieve and decrypt a secret |
| `npx stash secrets list` | `-environment` | `-e` | List all secret names in an environment |
| `npx stash secrets delete` | `-name`, `-environment`, `-yes` | `-n`, `-e`, `-y` | Delete a secret (prompts for confirmation unless `-yes`) |

## Configuration

### Local Development
Expand Down Expand Up @@ -552,7 +494,7 @@ const client2 = await Encryption({

### Logging

The SDK uses structured logging across all interfaces (Encryption, Secrets, Supabase, DynamoDB). Each operation emits a single wide event with context such as the operation type, table, column, lock context status, and duration.
The SDK uses structured logging across all interfaces (Encryption, Supabase, DynamoDB). Each operation emits a single wide event with context such as the operation type, table, column, lock context status, and duration.

Configure the log level with the `STASH_STACK_LOG` environment variable:

Expand Down Expand Up @@ -631,19 +573,6 @@ const lc = new LockContext(options?)
const result = await lc.identify(jwtToken)
```

### `Secrets`

```typescript
import { Secrets } from "@cipherstash/stack/secrets"

const secrets = new Secrets(config)
await secrets.set(name, value)
await secrets.get(name)
await secrets.getMany(names)
await secrets.list()
await secrets.delete(name)
```

### Schema Builders

```typescript
Expand All @@ -661,7 +590,6 @@ csValue(valueName) // returns ProtectValue (for nested values)
| `@cipherstash/stack` | `Encryption` function (main entry point) |
| `@cipherstash/stack/schema` | `encryptedTable`, `encryptedColumn`, `csValue`, schema types |
| `@cipherstash/stack/identity` | `LockContext` class and identity types |
| `@cipherstash/stack/secrets` | `Secrets` class and secrets types |
| `@cipherstash/stack/client` | Client-safe exports (schema builders and types only - no native FFI) |
| `@cipherstash/stack/types` | All TypeScript types (`Encrypted`, `Decrypted`, `ClientConfig`, `EncryptionClientConfig`, query types, etc.) |

Expand All @@ -675,7 +603,6 @@ If you are migrating from `@cipherstash/protect`, the following table maps the o
| `csTable(name, cols)` | `encryptedTable(name, cols)` | `@cipherstash/stack/schema` |
| `csColumn(name)` | `encryptedColumn(name)` | `@cipherstash/stack/schema` |
| `import { LockContext } from "@cipherstash/protect/identify"` | `import { LockContext } from "@cipherstash/stack/identity"` | `@cipherstash/stack/identity` |
| N/A | `Secrets` class | `@cipherstash/stack/secrets` |
| N/A | CLI | `npx stash` |

All method signatures on the encryption client (`encrypt`, `decrypt`, `encryptModel`, etc.) remain the same. The `Result` pattern (`data` / `failure`) is unchanged.
Expand Down
10 changes: 0 additions & 10 deletions packages/stack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,6 @@
"default": "./dist/identity/index.cjs"
}
},
"./secrets": {
"import": {
"types": "./dist/secrets/index.d.ts",
"default": "./dist/secrets/index.js"
},
"require": {
"types": "./dist/secrets/index.d.cts",
"default": "./dist/secrets/index.cjs"
}
},
"./schema": {
"import": {
"types": "./dist/schema/index.d.ts",
Expand Down
1 change: 0 additions & 1 deletion packages/stack/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default defineConfig([
'src/client.ts',
'src/types-public.ts',
'src/identity/index.ts',
'src/secrets/index.ts',
'src/schema/index.ts',
'src/eql/v3/index.ts',
'src/drizzle/index.ts',
Expand Down
3 changes: 1 addition & 2 deletions skills/stash-encryption/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,9 @@ The SDK never logs plaintext data.

| Import Path | Provides |
|---|---|
| `@cipherstash/stack` | `Encryption` function, `Secrets` class, `encryptedTable`, `encryptedColumn`, `encryptedField` (convenience re-exports) |
| `@cipherstash/stack` | `Encryption` function, `encryptedTable`, `encryptedColumn`, `encryptedField` (convenience re-exports) |
| `@cipherstash/stack/schema` | `encryptedTable`, `encryptedColumn`, `encryptedField`, schema types |
| `@cipherstash/stack/identity` | `LockContext` class and identity types |
| `@cipherstash/stack/secrets` | `Secrets` class and secrets types |
| `@cipherstash/stack/drizzle` | `encryptedType`, `extractEncryptionSchema`, `createEncryptionOperators` for Drizzle ORM |
| `@cipherstash/stack/supabase` | `encryptedSupabase` wrapper for Supabase |
| `@cipherstash/stack/dynamodb` | `encryptedDynamoDB` helper for DynamoDB |
Expand Down
Loading
Loading