Functional Specification: Secrets Management with Infisical
1. Introduction & Goal
Problem: The project currently relies on multiple .env files across different services (/backend/.env, /python-services/.env, etc.). This approach is insecure, difficult to manage, and prone to errors. Secrets are not centrally stored or audited.
Goal: To implement a centralized, secure, and scalable secrets management solution by deploying a self-hosted Infisical instance. This will replace the use of .env files for storing sensitive information.
2. Current State
- Secrets like database URLs, API keys, and JWT secrets are stored in plaintext
.envfiles within service directories. - There is no central source of truth for secrets, making rotation and access control difficult.
.env.examplefiles are used for documentation, but they can easily fall out of sync with actual required variables.- Sharing secrets among team members is an insecure manual process.
3. Proposed Solution
We will deploy a self-hosted Infisical instance using Docker on Hetzner. All services will be updated to fetch their configuration and secrets from Infisical at runtime using the Infisical SDK.
This provides:
- Centralized Management: A single dashboard to manage all secrets for all environments (development, production, etc.).
- Enhanced Security: Secrets are encrypted at rest and in transit. Access can be controlled via role-based access control (RBAC).
- Audit Trails: All access and changes to secrets are logged.
- Developer Experience: A simple CLI (
infisical run) and SDKs streamline development and eliminate the need to manage local.envfiles.
4. Scope of Work (Implementation Steps)
-
Deploy Infisical:
- Deploy the
infisical/infisical:latestDocker image on the Hetzner server, potentially managed via Dokploy. - Configure persistent volume for Infisical data.
- Deploy the
-
Configure Infisical Project:
- Create a new project named
chainalign. - Set up environments within the project (e.g.,
development,production).
- Create a new project named
-
Migrate Secrets:
- Identify all secrets from existing
.envfiles inbackend,python-services, and any other service. - Add these secrets to the
chainalignproject in Infisical, assigning them to the appropriate environments.
- Identify all secrets from existing
-
Integrate Infisical SDK:
- For each service (e.g.,
graphql-server,python-service), add the appropriate Infisical SDK (@infisical/sdkfor Node.js). - Create a configuration loader (e.g.,
config.js) in each service that:- Initializes the Infisical client using
INFISICAL_CLIENT_IDandINFISICAL_CLIENT_SECRET. - Fetches all secrets for the current
NODE_ENV. - Exports the secrets for the application to use.
- Initializes the Infisical client using
- For each service (e.g.,
-
Update Environment Configuration:
- The only environment variables required by the services will be
INFISICAL_CLIENT_ID,INFISICAL_CLIENT_SECRET, andNODE_ENV. - These will be stored in a single, git-ignored
.env.localfile for local development. - In production (Hetzner/Dokploy), these variables will be injected securely by the deployment system.
- The only environment variables required by the services will be
-
Cleanup:
- Delete all old
.envfiles from the project repository. - Ensure
.env.localand similar files are listed in.gitignore. - Update
README.mdand other developer documentation to reflect the new setup process.
- Delete all old
5. Out of Scope
- This FSD does not cover the migration of the user authentication system from Firebase to SuperTokens. That is detailed in a separate document.
- This FSD does not cover the setup of advanced Infisical features like secret rotation or signed JWTs, which can be considered in a future phase.
6. Success Criteria
- All services successfully start and run by fetching secrets from the central Infisical instance.
- No sensitive information (API keys, database URLs, etc.) exists in any
.envfile within the git repository. - Local development is simplified via the
infisical run --env=development -- npm run devcommand. - Production deployments automatically receive secrets without any
.envfiles on the server.