CipherStash takes the security of our software, infrastructure, and customers extremely seriously. This document describes the security posture, reporting process, and guidelines for this repository and associated packages.
This repository is the CipherStash Stack monorepo for JavaScript/TypeScript. It publishes the following packages to npm:
| Package | Description |
|---|---|
@cipherstash/stack |
Main package: encryption client, schema, EQL v3 typed client |
stash |
CipherStash CLI |
@cipherstash/nextjs |
Next.js helpers |
@cipherstash/migrate |
Plaintext-to-encrypted column migration tooling |
@cipherstash/stack-prisma |
Prisma Next integration (searchable field-level encryption for Postgres) |
@cipherstash/stack-drizzle |
Drizzle ORM integration for @cipherstash/stack (EQL v3) |
@cipherstash/stack-supabase |
Supabase integration for @cipherstash/stack (EQL v3) |
@cipherstash/wizard |
AI-powered encryption setup |
@cipherstash/protect-ffi |
Native FFI bindings to the CipherStash Client SDK — the Rust core @cipherstash/stack encrypts and decrypts through |
@cipherstash/protect-ffi-darwin-arm64@cipherstash/protect-ffi-darwin-x64@cipherstash/protect-ffi-linux-arm64-gnu@cipherstash/protect-ffi-linux-x64-gnu@cipherstash/protect-ffi-linux-x64-musl@cipherstash/protect-ffi-win32-x64-msvc |
Prebuilt per-platform binaries for @cipherstash/protect-ffi. Installed as optional dependencies; one is selected at load time for the host platform |
@cipherstash/eql |
Encrypt Query Language — the PostgreSQL SQL bundle (eql_v3 schema: domains, operators, index-term extractors) that stores and queries encrypted payloads, plus its generated TypeScript types. Applied by stash eql install and by the Prisma Next adapter's migrations. Released in lockstep with the eql-bindings Rust crate, which emits the payloads this SQL reads |
This repository also carries the source of the eql-bindings Rust crate
(packages/eql/crates/eql-bindings), published to crates.io and released in
lockstep with @cipherstash/eql. It is in scope for security reports on the
same terms as the npm packages above.
Note on publishing.
@cipherstash/eqland theeql-bindingscrate are developed here but are still published fromcipherstash/encrypt-query-language— the npm package'srepository/bugsfields and the crate'srepository/homepageall still name it, as does npm trusted publishing, and repointing every one of them is Phase 5 ofdocs/plans/2026-08-13-eql-monorepo-absorption.md. Everything else in the table above — including all seven@cipherstash/protect-ffi*packages, whose own cutover has completed — is published from this repository by.github/workflows/release.yml. Source, issues, and security reports for all of them belong here regardless.The provenance attestation on a release names the repository that built it, and is the only thing that settles the paragraph above:
curl -s https://registry.npmjs.org/-/npm/v1/attestations/@cipherstash%2fprotect-ffi@0.32.0returnscipherstash/stack; the same call against@cipherstash%2feql@3.0.5returnscipherstash/encrypt-query-language. Check there before repeating either claim: this note went on namingcipherstash/protectjs-ffias the protect-ffi publisher through0.32.0— the release that proved the cutover and disproved the sentence.
scripts/__tests__/frozen-publisher-docs.test.mjsnow holds this paragraph toFROZEN_PUBLISHERSinscripts/release-gate.mjs. It fails if the note names a package the map does not freeze, and fails again on the Phase-5 cutover that empties the map — so the next half of this note to go stale does so loudly.
Security fixes are released for the latest release line of each package. Security reports are welcome for any version, but fixes land in the latest release — if you are running an older major version, plan to upgrade to receive them.
All packages follow semantic versioning and undergo internal security review, automated analysis, and reproducible builds as part of our SDLC.
If you believe you have found a security vulnerability in any CipherStash code, service, or dependency:
📧 Please email: security@cipherstash.com
We request that you do not publicly disclose the issue before we have had a chance to investigate and provide a fix.
When reporting, please include (as applicable):
- Description of the vulnerability
- Steps to reproduce
- Impact assessment or potential misuse
- Any relevant logs, PoCs, or screenshots
- Suggested remediation (if you have one)
We will acknowledge receipt within 48 hours and provide regular updates until the issue is resolved.
CipherStash follows a coordinated responsible disclosure process:
- Submit report privately via
security@cipherstash.com. - Acknowledgement within 48 hours.
- Assessment of severity using CVSS and internal risk models.
- Fix development and patch release in a private branch.
- Coordinated disclosure, including:
- New patch release(s)
- Security advisory on GitHub
- Credit to reporter (optional)
We will never take legal action against good-faith security researchers who follow this policy.
The following are in scope:
- The
cipherstash/stackGitHub repository - All npm packages listed under Supported Packages above — scope follows the source, not the release pipeline (see the note on publishing)
- CipherStash Stack cryptographic implementations, configuration layers, and CLI tooling
- Key-handling, authenticated encryption behaviour, JSON/JSONB field-level encryption flows
- Documentation or code examples that could lead to insecure usage
- CipherStash’s internal infrastructure
- CipherStash Proxy, ZeroKMS, or other backend products
The following are out of scope:
- Example applications in the
examplesdir (though we are still grateful for any relevant disclosures there) - Social engineering, physical attacks, or denial-of-service
- Attacks requiring privileged access to developer machines or CI/CD infrastructure
To maintain a strong security posture, contributors MUST:
- Do not modify cryptographic primitives without prior discussion
- Avoid introducing new crypto dependencies without prior discussion
- Never check in test keys, secrets, or example credentials
- Avoid adding dependencies unless necessary
- Keep dependencies updated and vetted
- Use TypeScript for all new code
- Ensure all code paths that handle keys or encrypted data include type-safe boundaries
- Submit PRs with tests covering edge cases and misuse-resistant behaviour
- Flag any changes involving key derivation, key wrapping, AAD, or encryption modes for mandatory security review
- Do not merge PRs that downgrade security controls or introduce unsafe defaults
This repo applies a set of supply-chain controls sourced from
lirantal/npm-security-best-practices:
a post-install script policy, a 7-day dependency cooldown (pnpm
minimumReleaseAge, mirrored by Dependabot's cooldown), exotic-dependency
blocking (blockExoticSubdeps), frozen-lockfile CI, registry pinning, and
CODEOWNERS coverage of supply-chain-critical paths. These controls are
validated by e2e/tests/supply-chain.e2e.test.ts so silent regressions fail
CI. See skills/stash-supply-chain-security/SKILL.md for the full guide.
The release.yml workflow publishes packages to npm using OIDC trusted
publishing (id-token: write). There is no long-lived NPM_TOKEN — the
workflow deliberately avoids one, and setting one would bypass trusted
publishing.
GitHub Actions cache poisoning is a known attack against credential-bearing workflows. The mechanism is:
- A lower-privileged workflow run plants a malicious entry under a deterministic cache key
- A privileged workflow restores a cache from that deterministic cache key
- The malicious entry is executed by the privileged workflow, and secrets are exfiltrated
We mitigate this by:
- Explicitly disabling all caching in
release.yml - Automated checks for disabled caching on high-risk workflows
For general questions about CipherStash security practices (not security incidents), contact:
For vulnerability disclosures:
Thank you for helping keep the CipherStash ecosystem secure.