seekrit

Trust & security

Last reviewed: September 20, 2026

This page is the plain-language answer to the questions a security review asks. It is written to be read next to the security model, which has the technical detail. Two rules govern it: every claim here is true today, and everything we do not have is stated, not implied. If you find something on this page that has drifted from what the product does, tell us and we will fix the page or the product.

Contents

The short version

note

seekrit is zero-knowledge about secret values. Encryption and decryption happen on your side, in the browser, the CLI, seekrit run, an SDK, or the egress proxy. The server stores ciphertext, wrapped keys, and metadata. A full copy of our database yields no secret, no private key, and no passphrase. We hold no SOC 2, ISO 27001, or third-party audit yet, and this page says so rather than hinting otherwise. What we offer instead is a design you can check, and the code and test vectors to check it with.

Who runs seekrit

seekrit is built and operated by Miles Zimmerman. It is not yet a registered company. That matters for two things: we cannot sign a contract with you (no DPA, no SLA with credits) until an entity exists, and we cannot start a SOC 2 engagement until then either. Both are on the roadmap below. It does not change what the software does with your secrets, which is the part this page is mostly about.

What we can see, and what we cannot

To operate the service the server processes metadata. It never processes secret contents.

We can seeWe can never see
Secret names and your org, app, and environment structureSecret values (plaintext)†
Which principals hold access to which environmentsYour private keys or passphrases
Access events, timing, and volumeThe contents of any encrypted blob
Account and billing metadataKMS key material or signing keys

† One exception, opt-in and scoped: third-party sync.

We say this plainly because names can be sensitive on their own (ACME_PROD_DB_PASSWORD tells a reader something). If your threat model requires hiding names or topology from the server, that is a different design and we will be honest about the trade-offs rather than promise it.

How the encryption works. Each environment has an AES-256 data key. Secrets are encrypted client-side with AES-256-GCM, with the environment and secret name bound in as authenticated data so ciphertext cannot be moved between secrets undetected. The data key is never stored in the clear. It is wrapped to each authorized principal's P-256 public key, so holding a grant and the matching private key is what access means. Service tokens carry their private key in the token string itself. We store only a hash of the token for lookup and its public key for wrapping. Blob formats are versioned so algorithms can move without breaking existing data. The security model and encryption pages have the byte-level detail.

The one place we decrypt

Some platforms hold their own copy of your environment and never give you a process to run first. A Vercel build reads variables Vercel already has. If you want seekrit to be the source of truth for such a platform, something has to hold plaintext to push it, and the push happens when nobody is logged in. There is no cryptographic trick that avoids this. Anyone who claims otherwise is pushing plaintext too.

We chose to make the exception small and provable instead of pretending it does not exist:

  • Off by default, enabled per environment and per destination. Turning on production → Vercel grants nothing for staging and nothing to any other destination.
  • You mint the access, not us. Enabling sync wraps the environment's data key, in your browser, to that connection's public key. Our API cannot compute that wrap. An attacker with complete control of our control plane still cannot enable sync on an environment.
  • The key that opens it is not in the database. It lives in isolated per-organization storage. Delete the connection and it is destroyed, which makes every grant to it permanently unreadable, by us included.
  • Transient. A run decrypts, pushes, and discards. Nothing is cached between runs, and the grant is re-read every time, so revoking it stops the next run.
  • Recorded. Enabling sync requires an explicit acknowledgment stored in the audit log, and every run writes its own audit entry.

You may not need it. If you can run a process where the secrets are used, decryption stays entirely on your side: seekrit run in CI or a container, the egress proxy for agent workloads, a language SDK in your app, or the Kubernetes chart. Sync is the last resort, and the sync guide says so.

Verify it yourself

An attestation asks you to trust an auditor. A zero-knowledge design lets you skip the middleman and check the claim directly. Here is what is public today:

  • The decrypt path is open, five times over. The Python, Go, JavaScript, Ruby, and Elixir SDKs each reimplement resolve-and-decrypt from scratch, so you can read exactly what a client does with a token and a ciphertext.
  • Shared golden test vectors. Every SDK, the Terraform provider, and the cluster-side resolver are pinned byte-for-byte to the same published fixture. Run one SDK's vector test and you have confirmed what the ciphertext format is and that decryption needs nothing the server holds.
  • The egress proxy is open source. seekritdev/proxy is the component that sits between an agent and the internet. You can read the substitution engine, the default-deny allowlist, and the TLS interception code before you trust them.
  • Your data is portable and independently decryptable. seekrit archive create exports an organization as one signed file, and seekrit archive decryptor writes a self-contained HTML page that opens it on an air-gapped machine with your passphrase, a service token, or a recovery quorum. If seekrit disappeared tomorrow, the export plus your keys is everything you need. See taking your data out and the export guide.
  • Network-level proof. Watch the requests your browser or CLI makes. The value field in every write is a sc1. ciphertext, and the resolve response carries ciphertext and a wrapped key, never a plaintext.

What is not public: the control-plane API and the web console. Opening them is a decision we have not made yet, and this page will say so until we do.

Where your data lives

  • Compute. Cloudflare Workers, Durable Objects, and KV. Requests are served from Cloudflare's edge, with the API placed near its database in the United States.
  • Database. Managed Postgres hosted by PlanetScale in the United States, reached through Cloudflare Hyperdrive. It holds ciphertext, wrapped keys, and metadata only.
  • Authentication. Stytch holds account identities, session state, TOTP enrollments, and, if you use one, the password hash for your login. It never sees a keyring passphrase, which is distinct from your password by design and never leaves your device.
  • Resolve cache. Successful resolves are cached at Cloudflare's edge as the same ciphertext the database holds, with a purge on every write and revoke.
  • Data residency. The hosted service runs in the United States today. If you need seekrit in your own Cloudflare account and Postgres database, contact us about a deployment. Regional hosting for the shared service has no committed date.

Availability and getting your data out

  • Status page. status.seekrit.dev shows current and historical availability for the API, console, and docs.
  • No SLA yet. We publish uptime, but we cannot sign an SLA with credits until there is an entity to sign it. If you need one, ask and we will tell you where that stands.
  • What an outage does to you. A running seekrit run process keeps working: it decrypted at startup and holds the values in its own memory, and with --cache it can also start from a last-known-good encrypted copy. The Kubernetes resolver keeps serving its last good snapshot when a refresh fails. New deploys that need a fresh resolve wait until the API is back. Nothing about an outage exposes a value.
  • Backups. The database provider takes automated backups. Because the database holds only ciphertext, a backup is no more sensitive than the live database. We do not yet publish a tested restore objective. Until we do, the export below is your guarantee.
  • Export and deletion. Export the whole organization at any time with seekrit archive create (see above). Deleting an environment destroys its wrapped keys, and deleting an organization removes its rows after a short transition window described in the privacy policy.

Subprocessors

The third parties that process data on our behalf, and what each one sees:

ProviderRoleWhat it processes
CloudflareHosting, edge cache, Durable Object storage, usage metering, transactional emailCiphertext, wrapped keys, metadata, request logs, the email addresses we send to
PlanetScaleManaged PostgresCiphertext, wrapped keys, metadata, audit log
StytchAuthenticationAccount email, session state, TOTP enrollment, login password hash
StripeBillingBilling contact and payment details, when a paid plan is active

Destinations you configure are not subprocessors: an audit-log export to your own OTLP endpoint, a sync connection to your Vercel project, or telemetry from a self-hosted component to your own collector all go where you point them. Self-hosted components (seekrit run, the proxy, the provisioner, the resolvers) send telemetry only to a collector you name and never to seekrit.

We will update this list before adding a provider, and the privacy policy is kept consistent with it.

Access, revocation, and rotation

Revoking a grant immediately stops that principal from fetching the data key again. It does not erase a key the principal already fetched. Anyone who cached a data key holds it until the key is rotated: a new data key is generated, secrets are re-encrypted, and the new key is wrapped only for remaining principals. This is true of every envelope-encrypted system and we would rather say it than let you assume revocation reaches into a laptop.

  • Rotation of a stored value (a database password, an API key) can be scheduled and managed: see rotation.
  • Rotation of an environment's data key is a deliberate, client-driven action today. Automatic rotate-on-revoke is on the roadmap and not shipped.
  • Practical rule: after removing anyone who held broad access, rotate, and treat what they could read as compromised until you have.

Lost passphrase or departed sole key-holder: because we never hold your keys, we cannot reset a passphrase or recover a private key. Any other grant-holder can restore access to a new member, and customer-controlled recovery splits an org recovery key across custodians you choose, so a quorum can restore access without trusting us. Keep at least two admins on every production environment either way.

What is audited

Every mutating action writes an append-only audit row before the request returns: secret writes, grants and revocations, token lifecycle, KMS operations, lease mint and revoke, rotation, sync enablement and every sync run, plan changes. There is no update or delete path for the audit log. Denied secret resolutions are durably audited too, since those are the security-significant reads.

Successful high-volume reads (every workload startup calling resolve) are metered for usage and anomaly detection rather than written as durable rows, and that telemetry is sampled. A complete durable read audit is a roadmap item for regulated customers and is not shipped. You can stream the durable audit log to your own SIEM today with audit export.

Attestations we hold, and do not

We will not claim a certification we do not hold, and we will not describe one as "in progress" until an auditor is engaged.

Status
SOC 2 Type I / Type IINot held. Blocked on incorporation. Planned as the first compliance track once an entity exists.
ISO 27001Not held. Not planned before SOC 2.
Independent cryptographic auditNot done. Planned. The envelope scheme, key hierarchy, token format, SSH CA signing, and verifier paths are the scope. Until then, the public vectors and SDKs are the review surface.
Penetration testNot done. Planned alongside the crypto audit.
Data Processing AgreementNot available. Requires a contracting entity. The privacy policy describes our practices in the meantime.
Signed SLANot available. Same reason. Public uptime at status.seekrit.dev.
Bug bountyNo paid program. Reports are welcome and credited; see responsible disclosure.

When any row changes, this page changes the same day.

Responsible disclosure

If you find a vulnerability, report it privately to security@seekrit.dev. We also publish a security.txt.

  • We acknowledge reports within two business days and aim to have a fix or a mitigation plan within fourteen days for anything that affects confidentiality of secrets, keys, or credentials.
  • Please give us a reasonable window to fix before public disclosure. We will keep you updated and credit you when the fix ships, unless you ask us not to.
  • In scope: seekrit.dev, app.seekrit.dev, api.seekrit.dev, mcp.seekrit.dev, the published CLI, SDKs, proxy, and self-hosted components. Out of scope: denial of service, social engineering, and findings against the third-party providers listed above (report those to them directly).
  • Please do not access, modify, or exfiltrate another user's data while testing. Use your own organization.

Contact

We would rather give you a precise "not yet" than a vague "yes."