CLI tool
keyshade-xyz/keyshade avatar
keyshade-xyz/keyshade

keyshade: realtime secrets protected by public key encryption

Realtime secret and configuration management tool

769 stars265 forksTypeScriptMPL-2.0

At a glance

What is it?
keyshade is an MPL 2.0 licensed secret and configuration management tool that encrypts values with public key encryption, pushes updates into running applications without a restart, and organises them in workspaces, projects and environments with versioning, roles and an event log. The judgement is that the cryptographic model is the interesting part, because a team member can use a secret without ever holding the private key that protects it.
Who is it for?
keyshade fits a team that runs its own services and wants one place for secrets and configuration where a rotation does not mean a redeploy, because the values are pushed to the runtime and every change is versioned and logged.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Public key encryption is the design, not a feature

The opening paragraph of the readme states the mechanism, and it is the right place to start because everything else follows from it. Keyshade is designed to simplify the integration of secrets and variables into a codebase, and it prioritises the security of the data by leveraging public key encryption, empowered by elliptic curve cryptography, for storing and transferring secrets to the runtime environment in realtime.

The consequence, spelled out in the feature list, is the interesting one. Because the values are encrypted with public key encryption, they are encrypted at rest and in transit, and it becomes mathematically impossible for anyone to decrypt them without the private key. And because it is public key encryption rather than a shared symmetric key, any team member can use the secrets in the runtime environment without having to know your private key.

That last point is the one that distinguishes this design from a password manager for teams. The usual approach to sharing configuration across a team is to distribute a credential, and distributing a credential is distributing the ability to read everything. Here the private key stays with the owner and the team receives the ability to use the values.

The project site is keyshade.io and the documentation lives at docs.keyshade.io, with a Discord community, a Twitter account and a LinkedIn page linked from the readme.

The problems it names are the real ones

The readme has a section on why, and the reasons are more specific than a general claim about security.

The first is that cloud providers store your sensitive data in plaintext or in decipherable hashes, which means anyone with access to the provider's dashboard can view your secrets. The second is access control, since the provider does not let you control who can access which secret, and that becomes a problem when you do not want everyone to have access to everything. The third is maintainability, because as the application grows you add more secrets and you end up updating them in multiple places by hand.

The fourth is the one every developer has hit. Secrets are generally configured as environment variables, so updating one means restarting the application. The fifth is collaboration, which is hard because you end up sharing your provider's credentials with your team, and worse, sending the secrets over insecure channels such as email or your chat platform.

That list is a decent specification for a secret manager, and it is a fair one to judge the project against. The restart problem in particular is what the realtime update path is aimed at, and the collaboration problem is what the public key model is aimed at.

Environments, rotation and versioning remove the restart

Three features work together to take the operational friction out of configuration.

Live updates come first. Whenever you change a secret, it is automatically updated in the runtime environment, which means you do not have to restart the application to pick up a change. That is the feature the environment variable problem in the readme's list of caveats points at.

Multiple environments come second. You can create separate environments for an application, and the readme names development, staging and production as the typical ones, so the same secret name can hold different values in different places and be referenced from the code accordingly.

Versioning and rotation are the third pair. A history of all your secrets is kept, so an older version of a configuration can be restored if you need to, and rotation is a first-class operation: you can update a secret regularly without having to update the application that consumes it. Those two are related, because rotation without versioning is a leap of faith, and versioning without rotation is an archive nobody consults.

One caveat belongs here. The readme says the goal is to enable you to manage secrets effortlessly without unnecessary detail or complexity, and that promise depends on the runtime integration doing the work of watching for updates. The exact mechanism of that push is not described in the readme, which is one of the reasons the setting things up page in the documentation is the place to start.

Workspaces, projects, custom roles and an event log

The organisational model is the standard one for a secrets manager, and it is useful naming the pieces

Data is organised into workspaces and projects, which is what makes sharing with a team straightforward: you add people to a workspace and the projects inside it become available to them. Access control follows from that, since you own your secrets and decide who can reach them. Custom roles sit on top, so you can fine tune who is allowed to do what rather than handing out a single administrator flag.

Event tracking is the audit trail. For every event, a detailed log records what happened, accounting for who did what and when, which is the record you need when a value has to change and someone asks why.

On top of that sits auditing and anomaly detection, where the readme says the robots continuously monitor access to your secrets and variables and that, with the power of AI, it becomes near to impossible to breach your data. That sentence deserves a sceptical read. What is described as continuous monitoring of access is a log you already have, and anomaly detection over that log is a well understood piece of engineering, so the practical question is not whether the feature exists but how the alerts are surfaced and who is expected to act on them.

Integrations are the last item, described as a vast library, and that is the feature that determines whether a team adopts the tool at all, since a secret manager is only useful if it can feed the systems that need the values.

A pnpm and Turborepo monorepo with staged prereleases

The repository layout says a lot about how the project is organised. There is an apps directory, a packages directory, a blob and a bucket directory, a docs directory and a scripts directory, with a turbo.json and a pnpm-workspace.yaml at the root, so it is a Turborepo monorepo on pnpm. The package manifest names the package manager exactly, pnpm at 9.2.0, and the topics list the frameworks, Next.js, NestJS and React.

The release setup is the most detailed part. The manifest is private and marked MPL-2.0, and it configures semantic-release with two branches, main, and develop, which is given the prerelease identifier stage. The release notes generator uses the conventional commits preset and maps commit types to sections, with features, bug fixes, performance improvements, reverts, documentation, styles, chores, refactors and a hidden section for tests. The commit message format is fixed to a chore(release) line followed by the tag and the notes, with the skip ci marker.

So the develop branch produces the stage builds and main produces the stable ones, which explains a tag like v2.49.1-stage.1 in the release history. That is a sensible scheme for a project with several applications in one repository, since the CLI, the web app and the platform can move at different speeds and still be versioned together.

The rest of the tooling is conventional and complete: husky hooks, lint-staged, prettier, an eslint flat config, a codecov configuration and a CHANGELOG file.

Local development runs Postgres, Redis and an entire Sentry

The compose file for local development is a good guide to what the service needs.

The database is Postgres 13 published on 5432 with a volume for its data directory, and Redis 7 on 6379 with its own volume. Alongside them sits a self-hosted Sentry, the getsentry/sentry 22.1.0 image published on port 9002, with its own Postgres and its own Redis, and five named volumes in total. Everything sits on a bridge network called keyshade-dev.

Running the full Sentry stack in development is a heavy choice, and the reason is visible in the environment file. Sentry is configured per surface, with separate DSNs and sample rates for the web app, the platform, the CLI and the API, and separate web and platform DSNs again. The example file also shows the OAuth variables for GitHub, GitLab and Google with their callback URLs, the admin email, the API port, which is 4200, and the domain, which is localhost for development.

One instruction in that file is best copied verbatim when you set up your own instance, because it is the kind of detail that is easy to miss and annoying to debug:

bash
docker compose run --rm sentry config generate-secret-key

The compose file also exists in a test variant, docker-compose-test.yml, which suggests the same services are used by the test suite rather than by a mocked layer.

The activity level is the caveat, and the licence is unusual

The release history and the dates tell the story of where the project is.

Version 2.48.0 and 2.49.0 were both published on 2026-01-05, an hour apart, and v2.49.1-stage.1 followed on 2026-01-10. The last push to the repository was on 2026-04-08, and the repository is not archived. So the tagged releases are from January and the code has been quiet at the top level since April, and any evaluation should plan around a fixed version rather than around a stream of fixes.

The licence deserves a note of its own. It is MPL 2.0, the Mozilla Public License, which is file level copyleft rather than the permissive licences most infrastructure tools use. The manifest records it as MPL-2.0 and the repository has a LICENSE file. For a hosted service that means the modifications you publish have to be published too, which is a different arrangement from the permissive terms most comparable projects carry.

Two smaller details round out the picture. The repository carries a Formula directory, which is the shape a Homebrew cask takes, and a keyshade.json at the root, which is the kind of file that holds a client configuration for the CLI. The readme also points at a detailed setup page in the documentation, and at the contributing guide for anyone who wants to work on it, with a code of conduct and a security policy in the repository.

Editorial conclusion

keyshade fits a team that runs its own services and wants one place for secrets and configuration where a rotation does not mean a redeploy, because the values are pushed to the runtime and every change is versioned and logged. It is the wrong choice if you need a product with a support commitment, since the last push was on 2026-04-08 and the newest tagged release is from January 2026, and it is the wrong choice if you want the deployment to be trivial, because the development stack is a Postgres, a Redis and a full self-hosted Sentry. Before you adopt it, read the setting things up page in the documentation, decide where the private key lives, because everything else depends on it, and check the semantic-release configuration on the develop branch, since that branch produces prerelease builds rather than stable ones.

Frequently asked questions

How does keyshade encrypt secrets?

It uses public key encryption powered by elliptic curve cryptography, so secrets are encrypted at rest and in transit and cannot be decrypted without the private key. Because it is public key encryption, a team member can use the secrets in the runtime environment without knowing that private key.

Do I have to restart my application when a secret changes?

No. Whenever a secret changes it is updated automatically in the runtime environment, which is the feature aimed at the common complaint that secrets are environment variables and therefore need a restart to change.

How are secrets organised and who can see them?

Secrets live in workspaces and projects, and you share them by adding people to a workspace. Custom roles fine tune what each member can do, and every event is logged with who did what and when.

What does it take to run keyshade locally?

The compose file starts Postgres 13, Redis 7 and a self-hosted Sentry on a bridge network, with the API on port 4200 and the web app on localhost. The environment file holds the database and Redis URLs, the OAuth credentials for GitHub, GitLab and Google, and separate Sentry DSNs for the web, platform, CLI and API surfaces.

Official sources

  1. keyshade-xyz/keyshade on GitHub
  2. License: MPL-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/keyshade-xyz-keyshade.svg)](https://hysenlabs.com/projects/keyshade-xyz-keyshade)

Was this useful?