█ ▄▄▄ ▗▞▀▘█ ▄ ▄▄▄ ▄▄▄▄ ▄ ■ ▐▌
█ █ █ ▝▚▄▖█▄▀ ▀▄▄ █ █ █ ▄ ▗▄▟▙▄▖▐▌
█ ▀▄▄▄▀ █ ▀▄ ▄▄▄▀ █ █ █ ▐▌ ▐▛▀▚▖
█ █ █ █ ▐▌ ▐▌ ▐▌
▐▌
Flexible tool written in Go for automating the rotation of secrets. It is designed to be a hybrid-cloud solution that helps you improve your security posture by regularly rotating sensitive credentials.
While the core rotation engine is generic, the tool is currently focused on rotating JWT Signing Secrets.
- Interactive Terminal UI: A polished and user-friendly command-line interface (built with Bubble Tea) guides you through the entire configuration process.
- Multi-Cloud Support: Store and manage your secrets in any of the three major cloud providers:
- AWS Secrets Manager
- Google Cloud Secret Manager
- Azure Key Vault
- Pluggable Observability: Get notifications about rotation events in your favorite monitoring tools.
- Sentry
- Slack
- (Support for both at the same time is available)
- Flexible Rotation Modes:
- Run Once: Perform an immediate, one-time rotation of your secret.
- Periodic Rotation (Serverless Deployment): The tool generates the necessary code and provides simple, copy-paste instructions to deploy a serverless function (AWS Lambda, Google Cloud Function, or Azure Function) to your cloud provider. This provides a robust, hands-off solution for automated rotation.
To get started, run the interactive CLI:
go run main.goThe tool will guide you through the following steps:
- Choose Your Cloud Provider: Select AWS, GCP, or Azure.
- Enter Configuration: Provide the necessary configuration for your chosen provider (e.g., GCP Project ID and Secret ID).
- Select Notification Channels: Choose whether you want to receive notifications in Sentry, Slack, both, or neither.
- Select Rotation Mode: Choose whether you want to run the rotation once or set up a periodic rotation via a serverless function.
- Execute or Get Instructions:
- If you chose "Run once," the tool will perform the rotation and then exit.
- If you chose "Run periodically," the tool will display a detailed set of instructions for deploying the serverless function to your cloud provider.
To run the deployed serverless function, you will need to configure some environment variables.
The serverless function will need credentials to access your secret manager. This is typically handled by assigning an IAM Role (or equivalent) to the function with the necessary permissions.
You will also need to set the following provider-specific environment variables:
- AWS:
SECRET_ID,REGION - GCP:
PROJECT_ID,SECRET_ID - Azure:
VAULT_URI,SECRET_NAME
To enable notifications, set the following environment variables:
- Sentry:
SENTRY_DSN: Your Sentry DSN.
- Slack:
SLACK_BOT_TOKEN: Your Slack Bot Token (starts withxoxb-).SLACK_CHANNEL_ID: The ID of the channel to post in.
The tool is built on a modular and extensible architecture:
RotationManager: A generic secret rotation engine that handles the core rotation logic.JWTManager: A specialized manager built on top of theRotationManagerto handle JWT-specific operations like signing and validating tokens.SecretStorageInterface: A pluggable storage interface that allows the tool to support different cloud backends.NotifierInterface: A pluggable notification interface that makes it easy to add new observability tools.
This design makes the tool easy to maintain and extend with new secret types, storage backends, or notifiers in the future.
As an alternative to the CLI, you can deploy a serverless Slack bot that can be queried for the last rotation status.
- Deploy the Bot: The code for the bot is in the
deployment/slack-botdirectory. You can deploy it as a serverless function (e.g., AWS Lambda). - Configure Environment Variables: The bot needs the same cloud provider credentials and configuration as the rotation function.
- Create a Slack App: In your Slack workspace, create a new Slack App.
- Create a Slash Command: In your app's settings, create a new slash command:
- Command:
/locksmith - Request URL: The URL of your deployed serverless function.
- Command:
- Usage: Once configured, any user in your workspace can type
/locksmith statusin a channel to get the timestamp of the last secret rotation.
When a new JWT signing secret is generated, the tool performs the following steps to ensure a high level of security:
-
Cryptographically Secure Randomness: The secret is created by generating a 64-byte slice filled with cryptographically secure random data using Go's standard
crypto/randlibrary. This ensures that the generated secrets are unpredictable and suitable for cryptographic operations. -
Unique Secret ID: A unique ID (
kid) is generated for each secret. This is done by creating an HMAC-SHA256 hash of the secret value itself. The first 12 characters of the resulting hex-encoded hash are used as the secret's ID. This ID is then embedded in the header of any JWTs signed with this secret, allowing for seamless validation during the key rotation grace period.